SSDKHOOK其实比较简单,主要就是把SSDT表中的函数改成我们自己的,然后再return到原函数中,不过在这之前需要保存原函数地址
注意的点:PTE在WIN7/10中的属性大部分情况下为R,即只可读,所以我们需要通过内存映射的方式进行修改.
代码
#include<ntifs.h>
PULONG g_PageMapMenmory = NULL;
typedef struct _SSDTService
{
PULONG ServiceTableBase; // SSDT基址
PVOID ServiceCounterTableBase;// SSDT中服务被调用次数计数器,一般由sysenter 更新
ULONG NumberOfService; // 索引总数
PVOID ParamTableBase; // 系统服务参数表基址-系统服务参数表SSPT
}SYSTEM_SERVICE_TABLE, * PSYSTEM_SERVICE_TABLE;
typedef struct _SSDTable
{
SYSTEM_SERVICE_TABLE KernelApi;
SYSTEM_SERVICE_TABLE GuiApi;
}
SYSTEM_DESCRIPTOR_TABLE, * PSYSTEM_DESCRIPTOR_TABLE;
EXTERN_C PSYSTEM_DESCRIPTOR_TABLE KeServiceDescriptorTable;//系统通过函数名帮我们自动找到SSDT
typedef NTSTATUS (NTAPI *WbOpenProcess)(
PHANDLE ProcessHandle,
ACCESS_MASK DesiredAccess,
POBJECT_ATTRIBUTES ObjectAttributes,
PCLIENT_ID ClientId
);
WbOpenProcess NtOpenProcessOldFunAddress = NULL;//用来保存原函数地址
NTSTATUS NtOpenProcess(
PHANDLE ProcessHandle,
ACCESS_MASK DesiredAccess,
POBJECT_ATTRIBUTES ObjectAttributes,
PCLIENT_ID ClientId
) {
DbgPrint("此函数已被Hook!");
return NtOpenProcessOldFunAddress(ProcessHandle, DesiredAccess, ObjectAttributes, ClientId);
}
VOID DriverUnload(PDRIVER_OBJECT pDriverObject) {
g_PageMapMenmory[0xBE] = NtOpenProcessOldFunAddress;//恢复原函数地址
MmUnmapIoSpace(g_PageMapMenmory, PAGE_SIZE);//关闭映射
//解除hook
DbgPrint("Driver UnLoad Success!");
}
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegPath) {
//PTE 读写属性大部分情况可能是r,有概率蓝屏
//1.修改CR0
//2.MDL
//3.内存映射
//获取物理地址
PHYSICAL_ADDRESS pHyAddress = MmGetPhysicalAddress(KeServiceDescriptorTable->KernelApi.ServiceTableBase);//获取SSDT的物理地址
g_PageMapMenmory = MmMapIoSpace(pHyAddress, PAGE_SIZE, MmCached);//通过内存映射,把SSDT映射到g_PageMapMenmory
NtOpenProcessOldFunAddress = g_PageMapMenmory[0xBE];//保存原来的函数地址
g_PageMapMenmory[0xBE] = NtOpenProcess;//进行HOOK,修改到我们自己的函数
pDriverObject->DriverUnload = DriverUnload;//卸载驱动
DbgPrint("Driver Load Success!");
return STATUS_SUCCESS;
}

|