遍历SSDT,检测是否被hook

来源:互联网 发布:外文期刊数据库有哪些 编辑:程序博客网 时间:2024/05/22 13:29

此方法只是遍历SSDT,判断是否在ntkrnlpa.exe模块里面。也就是寻找SSDT导出NT函数的原始地址。此方法不适合检测 inline Hook。

typedef struct _SYSTEM_MODULE_INFORMATION { ULONG Reserved[2]; PVOID Base; ULONG Size; ULONG Flags; USHORT Index; USHORT Unknown; USHORT LoadCount; USHORT ModuleNameOffset; CHAR ImageName[256]; } SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION; typedef struct _tagSysModuleList {ULONG ulCount;SYSTEM_MODULE_INFORMATION smi[1];} SYSMODULELIST, *PSYSMODULELIST;

以上是SSDT模块信息的结构和链表。

NTSTATUS MyEnumSSDT(){NTSTATUS status = STATUS_UNSUCCESSFUL;PULONG SSDT_Function_Address;//SSDT表函数地址ULONG SSDT_Function_Number;//SSDT表函数个数PSYSMODULELIST pSysModuleList;SYSTEM_MODULE_INFORMATION SystemModuleInfo;//模块结构PVOID pBuffer;//SSDT总大小缓冲区ULONG uBufferSize;ULONG i = 0;ULONG j = 0;ULONG uModuleBase;ULONG uModuleMax;CHAR strMdoulePath[255];SSDT_Function_Address = (PULONG)KeServiceDescriptorTable->ServiceTableBase;SSDT_Function_Number = KeServiceDescriptorTable->NumberOfService;KdPrint(("SSDT_Function_Address:%x,SSDT_Function_Number:%d\n",SSDT_Function_Address,SSDT_Function_Number));ZwQuerySystemInformation(SystemModuleInformation,NULL,0,&uBufferSize);//枚举SSDT表Path大小if (!uBufferSize){KdPrint(("ZwQuerySystemInformation1 error!\n"));return status;}pBuffer = ExAllocatePoolWithTag(NonPagedPool,uBufferSize,MEM_TAG);//申请内存存放if (!pBuffer){KdPrint(("ExAllocatePoolWithTag error!\n"));return status;}status = ZwQuerySystemInformation(SystemModuleInformation,pBuffer,uBufferSize,NULL);//第二次遍历,填充pBuffer缓冲区if (!NT_SUCCESS(status)){KdPrint(("ZwQuerySystemInformation2 error!\n"));return status;}pSysModuleList = (PSYSMODULELIST)pBuffer;//将所有SSDT函数缓冲区换成链表来访问for (j = 0; j < pSysModuleList->ulCount; j++) //遍历获取ntkrnlpa.exe模块所在地址和大小{SystemModuleInfo = pSysModuleList->smi[j];strcpy(strMdoulePath,(SystemModuleInfo.ImageName + SystemModuleInfo.ModuleNameOffset));if (strncmp("ntkrnlpa.exe",strMdoulePath,12) == 0){uModuleBase = (ULONG)SystemModuleInfo.Base;uModuleMax = uModuleBase + SystemModuleInfo.Size;}}//遍历SSDT表,对比地址检测是否被hookfor (i = 0; i < SSDT_Function_Number; i++){if (uModuleBase < (ULONG)SSDT_Function_Address && (ULONG)SSDT_Function_Address < uModuleMax){KdPrint(("UnHook:%03d  Address:%X  Path:%s\n",i,*(SSDT_Function_Address + i),strMdoulePath));}else{KdPrint(("Hook:%03d  Address:%X  Path:%s\n",i,*(SSDT_Function_Address + i),strMdoulePath));}}if (pBuffer){ExFreePool(pBuffer);pBuffer = NULL;}return status;}


总的来说还是比较简单的,还差了一个获取SSDT导出函数名字。下一篇补全。