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) //test
MyDriver.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 + 0