Win64 驱动内核编程-20.UnHook SSDT
UNHOOK SSDT
要恢复 SSDT,首先要获得 SSDT 各个函数的原始地址,而 SSDT 各个函数的原始地址,自然是存储在内核文件里的。于是,有了以下思路:
1.获得内核里 KiServiceTable 的地址(变量名称:KiServiceTable)
2.获得内核文件在内核里的加载地址(变量名称:NtosBase)
3.获得内核文件在 PE32+结构体里的映像基址(变量名称:NtosImageBase)
4.在自身进程里加载内核文件并取得映射地址(变量名称:NtosInProcess)
5.计算出 KiServiceTable 和 NtosBase 之间的“距离”(变量名称:RVA)
6.获得指定 INDEX 函数的地址(计算公式:*(PULONGLONG)(NtosInProcess + RVA
+ 8 * index) - NtosImageBase + NtosBase)
第六步的计算原理:
上面公式需要好好理解下,我卡在一个地方卡了好久,就是
NtosBase + RVA = KiServiceTable
NtosInProcess + RVA = 是一个地址,这个地址存的是存数组地址的。还是相对于文件的基址的。我一直觉得因为都是load到了内存:
NtosBase + RVA = NtosInProcess + RVA
因为之前我认为只有在文件里才会存在FOA地址什么的,一担load了之后就自动修改了。根据相关桥自动修改了。结果看这个样子并不是我想的那样,load之后依然是相对于文件基址的地址而不是和NtosBase + RVA = KiServiceTable一样。这个后期整清楚了我在补充吧。但是已经验证了,资料上的公式是正确的。
接下来是细化每一个地方(下面的代码是我从资料里整理过来的,如果是要实际使用,记得重新整理并且改改,比如内存泄漏问题,比如很多东西都有函数代替不用咱们模拟,代码会精简许多)。
驱动部分代码:
MyDriver.h
#include <ntddk.h>#define dprintf if (DBG) DbgPrint#define DEVICE_NAME L"\\Device\\MyDriver" #define LINK_NAME L"\\DosDevices\\MyDriver" #define LINK_GLOBAL_NAME L"\\DosDevices\\Global\\MyDriver"#define IOCTL_ClrSSDTHOOK CTL_CODE(FILE_DEVICE_UNKNOWN, 0x800, METHOD_BUFFERED, FILE_ANY_ACCESS) //Clear ssdt hook #define IOCTL_GetKiSrvTab CTL_CODE(FILE_DEVICE_UNKNOWN, 0x801, METHOD_BUFFERED, FILE_ANY_ACCESS) //Get KiServiceTable #define IOCTL_GetFuncAddr CTL_CODE(FILE_DEVICE_UNKNOWN, 0x802, METHOD_BUFFERED, FILE_ANY_ACCESS) //Get function address #define IOCTL_GetTest CTL_CODE(FILE_DEVICE_UNKNOWN, 0x803, METHOD_BUFFERED, FILE_ANY_ACCESS) //testMyDriver.cpp
#include <ntddk.h> #include <windef.h> #include "MyDriver.h"#pragma intrinsic(__readmsr)typedef struct _SYSTEM_SERVICE_TABLE{PVOID ServiceTableBase; PVOID ServiceCounterTableBase; ULONGLONG NumberOfServices; PVOID ParamTableBase; } SYSTEM_SERVICE_TABLE, *PSYSTEM_SERVICE_TABLE;typedef struct _UNHOOK_SSDT64{ULONGLONG Address;ULONGLONG id; }UNHOOK_SSDT64,*PUNHOOK_SSDT64;typedef UINT64 (__fastcall *SCFN)(UINT64,UINT64);SCFN scfn; ULONGLONG ssdt_base_aadress, ssdt_func_address, KiServiceTable; ULONG32 ssdt_func_index; UNHOOK_SSDT64 uhssdt64={0}; PSYSTEM_SERVICE_TABLE KeServiceDescriptorTable;ULONGLONG GetKeServiceDescriptorTable64() {PUCHAR StartSearchAddress = (PUCHAR)__readmsr(0xC0000082);PUCHAR EndSearchAddress = StartSearchAddress + 0x500;PUCHAR i = NULL;UCHAR b1 = 0, b2 = 0, b3 = 0;ULONG templong = 0;ULONGLONG addr = 0;for (i = StartSearchAddress; i<EndSearchAddress; i++){if (MmIsAddressValid(i) && MmIsAddressValid(i + 1) && MmIsAddressValid(i + 2)){b1 = *i;b2 = *(i + 1);b3 = *(i + 2);if (b1 == 0x4c && b2 == 0x8d && b3 == 0x15) //4c8d15 {memcpy(&templong, i + 3, 4);addr = (ULONGLONG)templong + (ULONGLONG)i + 7;return addr;}}}return 0; }KIRQL WPOFFx64() {KIRQL irql=KeRaiseIrqlToDpcLevel();UINT64 cr0=__readcr0();cr0 &= 0xfffffffffffeffff;__writecr0(cr0);_disable();return irql; }void WPONx64(KIRQL irql) {UINT64 cr0=__readcr0();cr0 |= 0x10000;_enable();__writecr0(cr0);KeLowerIrql(irql); }ULONG GetOffsetAddress(ULONGLONG FuncAddr) {ULONG dwtmp=0;PULONG ServiceTableBase=NULL;if(KeServiceDescriptorTable==NULL)KeServiceDescriptorTable=(PSYSTEM_SERVICE_TABLE)GetKeServiceDescriptorTable64();ServiceTableBase=(PULONG)KeServiceDescriptorTable->ServiceTableBase;dwtmp=(ULONG)(FuncAddr-(ULONGLONG)ServiceTableBase);return dwtmp<<4; }VOID UnHookSSDT(ULONG id, ULONGLONG FuncAddr) {KIRQL irql;ULONG dwtmp;PULONG ServiceTableBase=NULL;dwtmp=GetOffsetAddress(FuncAddr);ServiceTableBase=(PULONG)KeServiceDescriptorTable->ServiceTableBase;irql=WPOFFx64();ServiceTableBase[id]=dwtmp;WPONx64(irql); }ULONGLONG GetSSDTFunctionAddress64(ULONGLONG NtApiIndex) {LONG dwTemp = 0;ULONGLONG qwTemp = 0, stb = 0, ret = 0;PSYSTEM_SERVICE_TABLE ssdt = (PSYSTEM_SERVICE_TABLE)GetKeServiceDescriptorTable64();stb = (ULONGLONG)(ssdt->ServiceTableBase);qwTemp = stb + 4 * NtApiIndex;dwTemp = *(PLONG)qwTemp;dwTemp = dwTemp >> 4;ret = stb + (LONG64)dwTemp;return ret; }VOID DriverUnload(PDRIVER_OBJECT pDriverObj) { UNICODE_STRING strLink;RtlInitUnicodeString(&strLink, LINK_NAME);IoDeleteSymbolicLink(&strLink);IoDeleteDevice(pDriverObj->DeviceObject);DbgPrint("[my driver]:DriverUnload\n"); }NTSTATUS DispatchCreate(PDEVICE_OBJECT pDevObj, PIRP pIrp) {pIrp->IoStatus.Status = STATUS_SUCCESS;pIrp->IoStatus.Information = 0;IoCompleteRequest(pIrp, IO_NO_INCREMENT);return STATUS_SUCCESS; }NTSTATUS DispatchClose(PDEVICE_OBJECT pDevObj, PIRP pIrp) {pIrp->IoStatus.Status = STATUS_SUCCESS;pIrp->IoStatus.Information = 0;IoCompleteRequest(pIrp, IO_NO_INCREMENT);return STATUS_SUCCESS; }NTSTATUS DispatchIoctl(PDEVICE_OBJECT pDevObj, PIRP pIrp) {NTSTATUS status = STATUS_INVALID_DEVICE_REQUEST;PIO_STACK_LOCATION pIrpStack;ULONG uIoControlCode;PVOID pIoBuffer;ULONG uInSize;ULONG uOutSize;pIrpStack = IoGetCurrentIrpStackLocation(pIrp);uIoControlCode = pIrpStack->Parameters.DeviceIoControl.IoControlCode;pIoBuffer = pIrp->AssociatedIrp.SystemBuffer;uInSize = pIrpStack->Parameters.DeviceIoControl.InputBufferLength;uOutSize = pIrpStack->Parameters.DeviceIoControl.OutputBufferLength;switch(uIoControlCode){case IOCTL_ClrSSDTHOOK:{memcpy(&uhssdt64, pIoBuffer, sizeof(UNHOOK_SSDT64));UnHookSSDT((ULONG)uhssdt64.id, uhssdt64.Address);status = STATUS_SUCCESS;break;}case IOCTL_GetKiSrvTab:{if(ssdt_base_aadress==0)ssdt_base_aadress=GetKeServiceDescriptorTable64();KiServiceTable=*(PULONGLONG)ssdt_base_aadress;memcpy(pIoBuffer, &KiServiceTable, 8);status = STATUS_SUCCESS;break;}case IOCTL_GetFuncAddr:{memcpy(&ssdt_func_index, pIoBuffer, 4);ssdt_func_address=GetSSDTFunctionAddress64((ULONGLONG)ssdt_func_index);memcpy(pIoBuffer, &ssdt_func_address, 8);status = STATUS_SUCCESS;break;}case IOCTL_GetTest:{DbgPrint("[my driver]:IoControl is OK \n");break;}}if(status == STATUS_SUCCESS)pIrp->IoStatus.Information = uOutSize;elsepIrp->IoStatus.Information = 0; pIrp->IoStatus.Status = status;IoCompleteRequest(pIrp, IO_NO_INCREMENT);return status; }NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObj, PUNICODE_STRING pRegistryString) {DbgPrint("[my driver]:DriverEntry\n");NTSTATUS status = STATUS_SUCCESS;UNICODE_STRING ustrLinkName;UNICODE_STRING ustrDevName; PDEVICE_OBJECT pDevObj;pDriverObj->MajorFunction[IRP_MJ_CREATE] = DispatchCreate;pDriverObj->MajorFunction[IRP_MJ_CLOSE] = DispatchClose;pDriverObj->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchIoctl;pDriverObj->DriverUnload = DriverUnload;RtlInitUnicodeString(&ustrDevName, DEVICE_NAME);status = IoCreateDevice(pDriverObj, 0, &ustrDevName, FILE_DEVICE_UNKNOWN, 0, FALSE, &pDevObj);if(!NT_SUCCESS(status)) return status;if(IoIsWdmVersionAvailable(1, 0x10))RtlInitUnicodeString(&ustrLinkName, LINK_GLOBAL_NAME);elseRtlInitUnicodeString(&ustrLinkName, LINK_NAME);status = IoCreateSymbolicLink(&ustrLinkName, &ustrDevName); if(!NT_SUCCESS(status)){IoDeleteDevice(pDevObj); return status;}return STATUS_SUCCESS; }
安装部分代码:
ScmDrvCtrl.h
#pragma comment(lib,"advapi32.lib")class cDrvCtrl { public:cDrvCtrl(){m_pSysPath = NULL;m_pServiceName = NULL;m_pDisplayName = NULL;m_hSCManager = NULL;m_hService = NULL;m_hDriver = INVALID_HANDLE_VALUE;}~cDrvCtrl(){if (m_hService) {CloseServiceHandle(m_hService);}if (m_hSCManager) {CloseServiceHandle(m_hSCManager);}if (m_hDriver) {CloseHandle(m_hDriver);}} public:DWORD m_dwLastError;PCHAR m_pSysPath;PCHAR m_pServiceName;PCHAR m_pDisplayName;HANDLE m_hDriver;SC_HANDLE m_hSCManager;SC_HANDLE m_hService; public:BOOL Install(PCHAR pSysPath,PCHAR pServiceName,PCHAR pDisplayName);BOOL Start();BOOL Stop();BOOL Remove();BOOL Open(PCHAR pLinkName);BOOL IoControl(DWORD dwIoCode, PVOID InBuff, DWORD InBuffLen, PVOID OutBuff, DWORD OutBuffLen, DWORD *RealRetBytes);BOOL IoControl(HANDLE hDrvHandle, DWORD dwIoControlCode, PVOID lpInBuffer, DWORD nInBufferSize, PVOID lpOutBuffer, DWORD nOutBufferSize); private:BOOL GetSvcHandle(PCHAR pServiceName);DWORD CTL_CODE_GEN(DWORD lngFunction); protected://null };BOOL cDrvCtrl::GetSvcHandle(PCHAR pServiceName) {m_pServiceName = pServiceName;m_hSCManager = OpenSCManagerA(NULL,NULL,SC_MANAGER_ALL_ACCESS);if (NULL == m_hSCManager){m_dwLastError = GetLastError();return FALSE;}m_hService = OpenServiceA(m_hSCManager,m_pServiceName,SERVICE_ALL_ACCESS);if (NULL == m_hService){CloseServiceHandle(m_hSCManager);return FALSE;}else{return TRUE;} }BOOL cDrvCtrl::Install(PCHAR pSysPath,PCHAR pServiceName,PCHAR pDisplayName) {m_pSysPath = pSysPath;m_pServiceName = pServiceName;m_pDisplayName = pDisplayName;m_hSCManager = OpenSCManagerA(NULL,NULL,SC_MANAGER_ALL_ACCESS);if (NULL == m_hSCManager){m_dwLastError = GetLastError();return FALSE;}m_hService = CreateServiceA(m_hSCManager,m_pServiceName,m_pDisplayName,SERVICE_ALL_ACCESS,SERVICE_KERNEL_DRIVER,SERVICE_DEMAND_START,SERVICE_ERROR_NORMAL,m_pSysPath,NULL,NULL,NULL,NULL,NULL);if (NULL == m_hService){m_dwLastError = GetLastError();if (ERROR_SERVICE_EXISTS == m_dwLastError){m_hService = OpenServiceA(m_hSCManager,m_pServiceName,SERVICE_ALL_ACCESS);if (NULL == m_hService){CloseServiceHandle(m_hSCManager);return FALSE;}}else{CloseServiceHandle(m_hSCManager);return FALSE;}}return TRUE; }BOOL cDrvCtrl::Start() {if (!StartServiceA(m_hService,NULL,NULL)){m_dwLastError = GetLastError();return FALSE;}return TRUE; }BOOL cDrvCtrl::Stop() {SERVICE_STATUS ss;GetSvcHandle(m_pServiceName);if (!ControlService(m_hService,SERVICE_CONTROL_STOP,&ss)){m_dwLastError = GetLastError();return FALSE;}return TRUE;}BOOL cDrvCtrl::Remove() {GetSvcHandle(m_pServiceName);if (!DeleteService(m_hService)){m_dwLastError = GetLastError();return FALSE;}return TRUE; }BOOL cDrvCtrl::Open(PCHAR pLinkName)//example: \\\\.\\xxoo {if (m_hDriver != INVALID_HANDLE_VALUE)return TRUE;m_hDriver = CreateFileA(pLinkName, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);if(m_hDriver != INVALID_HANDLE_VALUE)return TRUE;elsereturn FALSE; }BOOL cDrvCtrl::IoControl(DWORD dwIoCode, PVOID InBuff, DWORD InBuffLen, PVOID OutBuff, DWORD OutBuffLen, DWORD *RealRetBytes) {DWORD dw;BOOL b=DeviceIoControl(m_hDriver,CTL_CODE_GEN(dwIoCode),InBuff,InBuffLen,OutBuff,OutBuffLen,&dw,NULL);if(RealRetBytes)*RealRetBytes=dw;return b; }BOOL cDrvCtrl::IoControl(HANDLE hDrvHandle, DWORD dwIoControlCode, PVOID lpInBuffer, DWORD nInBufferSize, PVOID lpOutBuffer, DWORD nOutBufferSize) {DWORD lDrvRetSize;return DeviceIoControl(hDrvHandle, dwIoControlCode, lpInBuffer, nInBufferSize, lpOutBuffer, nOutBufferSize, &lDrvRetSize, 0); }DWORD cDrvCtrl::CTL_CODE_GEN(DWORD lngFunction) {return (FILE_DEVICE_UNKNOWN * 65536) | (FILE_ANY_ACCESS * 16384) | (lngFunction * 4) | METHOD_BUFFERED; }main.cpp #include "stdafx.h" #include <string> #include <stdio.h> #include <Windows.h> #include "ScmDrvCtrl.h"#pragma warning(disable:4996) #pragma comment(lib,"user32.lib")using namespace std;void GetAppPath(char *szCurFile) {GetModuleFileNameA(0, szCurFile, MAX_PATH);for (SIZE_T i = strlen(szCurFile) - 1; i >= 0; i--){if (szCurFile[i] == '\\'){szCurFile[i + 1] = '\0';break;}} }//start********************Dirver************************* cDrvCtrl dcDirver; BOOL InstallDriver(char * pSysFileName, char * pServiceName, char * pDisplayName) {char szSysFile[MAX_PATH] = { 0 };GetAppPath(szSysFile);strcat(szSysFile, pSysFileName);BOOL bInstallSuc = FALSE;if (dcDirver.Install(szSysFile, pServiceName, pDisplayName)) {if (dcDirver.Start()) {char pLink[1024] = "\\\\.\\";strcat(pLink , pDisplayName);dcDirver.Open(pLink);DWORD x = 0, y = 0, z = 0;dcDirver.IoControl(0x803, &x, sizeof(x), &y, sizeof(y), &z);bInstallSuc = TRUE;}}return bInstallSuc; }VOID UnInstallDriver() {CloseHandle(dcDirver.m_hDriver);dcDirver.Stop();dcDirver.Remove(); }//end********************Dirver*************************//start********************NtosBase************************* //获得内核文件在内核里的加载地址(变量名称:NtosBase) #ifndef NT_SUCCESS #define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0) #endif #ifndef STATUS_SUCCESS #define STATUS_SUCCESS ((NTSTATUS)0x00000000L) #endif #ifndef STATUS_UNSUCCESSFUL #define STATUS_UNSUCCESSFUL ((NTSTATUS)0xC0000001L) #endif#define SystemModuleInformation 11 #define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L)typedef struct _SYSTEM_MODULE_INFORMATION_ENTRY{ULONG Unknow1;ULONG Unknow2;ULONG Unknow3;ULONG Unknow4;PVOID64 Base;ULONG Size;ULONG Flags;USHORT Index;USHORT NameLength;USHORT LoadCount;USHORT ModuleNameOffset;char ImageName[256]; } SYSTEM_MODULE_INFORMATION_ENTRY, *PSYSTEM_MODULE_INFORMATION_ENTRY;typedef struct _SYSTEM_MODULE_INFORMATION{ULONG Count;//内核中以加载的模块的个数SYSTEM_MODULE_INFORMATION_ENTRY Module[1]; } SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION;typedef long(__stdcall *ZWQUERYSYSTEMINFORMATION)(IN ULONG SystemInformationClass,IN OUT PVOID SystemInformation,IN ULONG SystemInformationLength,IN PULONG ReturnLength OPTIONAL); ZWQUERYSYSTEMINFORMATION ZwQuerySystemInformation;ULONGLONG NtosBase = 0; CHAR NtosName[260] = { 0 };char *cs(char *str1, char *str2) //connect string {long newstrlen = strlen(str1) + strlen(str2) + 1;char *newstr = (char*)malloc(newstrlen);memcpy(newstr, str1, strlen(str1));memcpy(newstr + strlen(str1), str2, strlen(str2) + 1);return newstr; }ULONGLONG GetNtosBaseAndPath(char *ModuleName){ZwQuerySystemInformation = (ZWQUERYSYSTEMINFORMATION)GetProcAddress(GetModuleHandleA("ntdll.dll"), "ZwQuerySystemInformation");ULONG NeedSize, i, ModuleCount;ULONGLONG qwBase = 0;PSYSTEM_MODULE_INFORMATION pSystemModuleInformation;ULONG uBufferSize = 0x5000;PVOID pBuffer = malloc(uBufferSize);if (ZwQuerySystemInformation(SystemModuleInformation, pBuffer, uBufferSize, &NeedSize) == STATUS_INFO_LENGTH_MISMATCH) {free(pBuffer);pBuffer = malloc(NeedSize+10);ZwQuerySystemInformation(SystemModuleInformation, pBuffer, uBufferSize, &NeedSize);}pSystemModuleInformation = (PSYSTEM_MODULE_INFORMATION)pBuffer;//获得模块的总数量ModuleCount = pSystemModuleInformation->Count;if (ModuleName != NULL) {strcpy(ModuleName, pSystemModuleInformation->Module[0].ImageName + pSystemModuleInformation->Module[0].ModuleNameOffset);}qwBase = (ULONGLONG)pSystemModuleInformation->Module[0].Base;free(pBuffer);return qwBase; } VOID GetNtosBase(){char FileName[260] = { 0 }, *FullName;NtosBase = GetNtosBaseAndPath(FileName);FullName = cs("C:\\Windows\\system32\\", FileName);strcpy(NtosName, FullName);printf("NTOSKRNL base: %llx\n", NtosBase);printf("NTOSKRNL name: %s\n", NtosName); }//end********************NtosBase*************************//start********************NtosImageBase*************************ULONGLONG NtosImageBase = 0;DWORD FileLen(char *filename){WIN32_FIND_DATAA fileInfo = { 0 };DWORD fileSize = 0;HANDLE hFind;hFind = FindFirstFileA(filename, &fileInfo);if (hFind != INVALID_HANDLE_VALUE){fileSize = fileInfo.nFileSizeLow;FindClose(hFind);}return fileSize; }CHAR *LoadDllContext(char *filename){DWORD dwReadWrite, LenOfFile = FileLen(filename);HANDLE hFile = CreateFileA(filename, GENERIC_READ , FILE_SHARE_READ , 0, OPEN_EXISTING, 0, 0);if (hFile != INVALID_HANDLE_VALUE){PCHAR buffer = (PCHAR)malloc(LenOfFile);SetFilePointer(hFile, 0, 0, FILE_BEGIN);ReadFile(hFile, buffer, LenOfFile, &dwReadWrite, 0);CloseHandle(hFile);return buffer;}return NULL; }VOID GetNtosImageBase(){PIMAGE_NT_HEADERS64 pinths64;PIMAGE_DOS_HEADER pdih;char *NtosFileData = NULL;NtosFileData = LoadDllContext(NtosName);pdih = (PIMAGE_DOS_HEADER)NtosFileData;pinths64 = (PIMAGE_NT_HEADERS64)(NtosFileData + pdih->e_lfanew);NtosImageBase = pinths64->OptionalHeader.ImageBase;printf("ImageBase: %llx\n", NtosImageBase);free(NtosFileData); } //end********************NtosImageBase*************************//start********************KiServiceTable************************* ULONGLONG KiServiceTable; DWORD CTL_CODE_GEN(DWORD lngFunction) {return (FILE_DEVICE_UNKNOWN * 65536) | (FILE_ANY_ACCESS * 16384) | (lngFunction * 4) | METHOD_BUFFERED; } VOID GetKiServiceTable() {dcDirver.IoControl(dcDirver.m_hDriver, CTL_CODE_GEN(0x801), NULL, 0, &KiServiceTable, 8);printf("KiServiceTable: %llx\n", KiServiceTable); } //end********************KiServiceTable*************************//start********************AllSSDTFunction*************************DWORD GetSSDTFunctionIndex(char *FunctionName) {return *(DWORD*)((PUCHAR)GetProcAddress(LoadLibraryW(L"ntdll.dll"), FunctionName) + 4); //极限精简/*PUCHAR fptr=(PUCHAR)GetProcAddress(LoadLibraryW(L"ntdll.dll"),FunctionName);DWORD index=*(DWORD*)(fptr+4);return index;*//*所有的函数都像下面一样:00000000`775a0110 4c8bd1 mov r10,rcx00000000`775a0113 b8??000000 mov eax,??h00000000`775a0118 0f05 syscall00000000`775a011a c3 ret*/ }ULONGLONG NtosInProcess = 0;ULONGLONG GetFunctionOriginalAddress(DWORD index) {if (NtosInProcess == 0)NtosInProcess = (ULONGLONG)LoadLibraryExA(NtosName, 0, DONT_RESOLVE_DLL_REFERENCES); //"C:\\Windows\\system32\\ntkrnlmp.exe"ULONGLONG RVA = KiServiceTable - NtosBase;ULONGLONG temp = *(PULONGLONG)(NtosInProcess + RVA + 8 * (ULONGLONG)index);ULONGLONG RVA_index = temp - NtosImageBase; //IMAGE_OPTIONAL_HEADER64.ImageBase=0x140000000(这个值基本是固定的)return RVA_index + NtosBase; }VOID PrintAllSSDTFunction() {DWORD i = 0, fl = 0, fs_pos = 0, fe_pos = 0, PauseCnt = 0, ssdt_fun_cnt = 0;ULONG64 ssdt_func_addr = 0, ssdt_func_ori_addr = 0;CopyFileW(L"c:\\windows\\system32\\ntdll.dll", L"c:\\ntdll.txt", 0);fl = FileLen("c:\\ntdll.txt");char func_start[] = "ZwAcceptConnectPort", func_end[] = "ZwYieldExecution"; //每个函数名之间隔着\0char *funs = (char *)malloc(strlen(func_start)); memcpy(funs, func_start, strlen(func_start));char *fune = (char *)malloc(strlen(func_end)); memcpy(fune, func_end, strlen(func_end));char *ntdlltxt = LoadDllContext("c:\\ntdll.txt");for (i = 0; i<fl; i++){if (memcmp(ntdlltxt + i, funs, strlen(func_start)) == 0)fs_pos = i;if (memcmp(ntdlltxt + i, fune, strlen(func_end)) == 0){fe_pos = i;break;}}ntdlltxt = ntdlltxt + fs_pos;//打印头printf("ID\t当前地址\t 原始地址\t 函数名\n");//这里不能显示到最后一个函数while (strcmp(ntdlltxt, func_end) != 0){DWORD fn_index = GetSSDTFunctionIndex(ntdlltxt);if (fn_index<1000){ssdt_func_ori_addr = GetFunctionOriginalAddress(fn_index);dcDirver.IoControl(dcDirver.m_hDriver, CTL_CODE_GEN(0x802), &fn_index, 4, &ssdt_func_addr, 8);ntdlltxt[0] = 'N'; ntdlltxt[1] = 't'; //寻找的是Zw***,但是应该显示Nt***if (ssdt_func_ori_addr != ssdt_func_addr)printf("0x%-0.3X!\t%llx %llx %s\n", fn_index, ssdt_func_addr, ssdt_func_ori_addr, ntdlltxt);elseprintf("0x%-0.3X\t%llx %llx %s\n", fn_index, ssdt_func_addr, ssdt_func_ori_addr, ntdlltxt);}else{fn_index = 0x57; //不同的系统,不同的编号,由于目前只有WIN7 X64,所以这里直接硬编码了ssdt_func_ori_addr = GetFunctionOriginalAddress(fn_index);dcDirver.IoControl(dcDirver.m_hDriver, CTL_CODE_GEN(0x802), &fn_index, 4, &ssdt_func_addr, 8);ntdlltxt[0] = 'N'; ntdlltxt[1] = 't';if (ssdt_func_ori_addr != ssdt_func_addr)printf("0x%-0.3X!\t%llx %llx %s\n", fn_index, ssdt_func_addr, ssdt_func_ori_addr, ntdlltxt);elseprintf("0x%-0.3X\t%llx %llx %s\n", fn_index, ssdt_func_addr, ssdt_func_ori_addr, ntdlltxt);/*0:000> u ZwQuerySystemTimentdll!ZwQuerySystemTime:00000000`77b20450 e91b62fdff jmp ntdll!RtlQuerySystemTime (00000000`77af6670)00000000`77b20455 6666660f1f840000000000 nop word ptr [rax+rax]*//*nt!ZwQuerySystemTime:fffff800`01673fa0 488bc4 mov rax,rspfffff800`01673fa3 fa clifffff800`01673fa4 4883ec10 sub rsp,10hfffff800`01673fa8 50 push raxfffff800`01673fa9 9c pushfqfffff800`01673faa 6a10 push 10hfffff800`01673fac 488d053d270000 lea rax,[nt!KiServiceLinkage (fffff800`016766f0)]fffff800`01673fb3 50 push raxfffff800`01673fb4 b857000000 mov eax,57hfffff800`01673fb9 e9825e0000 jmp nt!KiServiceInternal (fffff800`01679e40)fffff800`01673fbe 6690 xchg ax,ax*/}ntdlltxt = ntdlltxt + strlen(ntdlltxt) + 1;PauseCnt++;ssdt_fun_cnt++;if (PauseCnt == 101){printf("\nPress [ENTER] to continue...\n");getchar();PauseCnt = 0;}}//显示完最后一个函数DWORD fn_index = GetSSDTFunctionIndex(ntdlltxt);ssdt_func_ori_addr = GetFunctionOriginalAddress(fn_index);dcDirver.IoControl(dcDirver.m_hDriver, CTL_CODE_GEN(0x802), &fn_index, 4, &ssdt_func_addr, 8);ntdlltxt[0] = 'N'; ntdlltxt[1] = 't';printf("0x%-0.3X\t%llx %llx %s\n", fn_index, ssdt_func_addr, ssdt_func_ori_addr, ntdlltxt);//显示测试的hook函数ssdt_fun_cnt++;//显示ssdt表上的函数数printf("\nTotal of SSDT function: %ld\n", ssdt_fun_cnt);DeleteFileA("c:\\ntdll.txt"); }//end********************AllSSDTFunction*************************//start********************UnHook*************************typedef struct _UNHOOK_SSDT64 {ULONGLONG Address;ULONGLONG id; }UNHOOK_SSDT64, *PUNHOOK_SSDT64; VOID UnhookSSDT() {ULONG id;ULONG64 ssdt_func_ori_addr = 0;UNHOOK_SSDT64 data = { 0 };printf("Input SSDT function index which you want to unhook (like 0x29): ");scanf("0x%x", &id);ssdt_func_ori_addr = GetFunctionOriginalAddress(id);data.Address = ssdt_func_ori_addr;data.id = (ULONGLONG)id;dcDirver.IoControl(dcDirver.m_hDriver, CTL_CODE_GEN(0x800), &data, sizeof(UNHOOK_SSDT64), 0, 0); }//end********************UnHook************************* int main() {//安装驱动if (!InstallDriver("Dri.sys", "MyDriver", "MyDriver")) {printf("LoadDriver=false\n");return 0;}else {printf("LoadDriver=true\n");}getchar();GetNtosBase();GetNtosImageBase();GetKiServiceTable();PrintAllSSDTFunction();getchar();UnhookSSDT();getchar();getchar();//卸载驱动UnInstallDriver();printf("UninstallDriver=true\n");return 0; }
执行结果1:hook掉关闭进程的函数,然后加载上面的驱动。
执行结果2 Hook SSDT保护计算器不被结束
执行结果3 执行UnHook 取消掉上面SSDT HOOK 的保护并且成功结束掉计算器
最后再声明一遍,所有的代码几乎都来源于学习资料,胡文亮前辈。还有很多细节为了测试方便我就随意的改了。很多地方发现内存泄漏以及无用代码。如果是用于实际项目,一定要弄清楚原理之后好好改改代码再用。
总结
以上是生活随笔为你收集整理的Win64 驱动内核编程-20.UnHook SSDT的全部内容,希望文章能够帮你解决所遇到的问题。
- 上一篇: Win64 驱动内核编程-19.HOOK
- 下一篇: Win64 驱动内核编程-21.DKOM