X86 下的SSDT HOOK

匿名 (未验证) 提交于 2019-12-02 23:49:02

Ŀ¼

SSDTHOOK

x32下,直接获取系统描述符表.以及调用号.就可以进行HOOK了.

x64下可以设置回调来进行过滤我们想要的功能.当然如果你简单的过一下PatchGuard也可以设置SSDT HOOK.

首先SSDT 我们是可以在windbg下看到的

SSDT表的结构如下:

 typedef struct _KSERVICE_TABLE_DESCRIPTOR {     PULONG_PTR Base;     PULONG Count;     ULONG Limit;     PUCHAR Number; } KSERVICE_TABLE_DESCRIPTOR, *PKSERVICE_TABLE_DESCRIPTOR; 

在WRK中的 ke.h中可以看到.

查看定义

在wrk中也可以看到定义的地方. 所以我们只需要在我们的函数中引用这个全局变量即可.

其中这个结构第一项是表的首地址 第二项是表的个数. *表 + n = 第某个函数的地址
也就是 base[10]就是第十项的地址.

KeServiceDescriptorTable

对应PCHunter查看.

所以我们想要HOOK就很简单了.

  1. 导入全局变量. 则获得SSDT表的地址
  2. 获取你想HOOK函数的位置
  3. 进行HOOK
  4. HOOK之前关闭一下CR0得写保护

代码如下:

 #include "Driver.h"  NTKERNELAPI UCHAR* PsGetProcessImageFileName(IN PEPROCESS Process);  void UnHook(); void DriverUnLoad(PDRIVER_OBJECT pDriverObj) {     UnHook();     KdPrint(("驱动卸载成功")); }  typedef struct _KSERVICE_TABLE_DESCRIPTOR {     PULONG_PTR Base;     PULONG Count;     ULONG Limit;     PUCHAR Number; } KSERVICE_TABLE_DESCRIPTOR, *PKSERVICE_TABLE_DESCRIPTOR;  __declspec(dllimport) KSERVICE_TABLE_DESCRIPTOR KeServiceDescriptorTable; //导入全局变量  // sizeof(base) + 370 * 4 = NtTerMinateProcess  //extern KSERVICE_TABLE_DESCRIPTOR KeServiceDescriptorTable typedef NTSTATUS(*PfnZwTerminateProcess)(     IN HANDLE              ProcessHandle OPTIONAL,     IN NTSTATUS            ExitStatus);  PfnZwTerminateProcess OldZwTerminateProcess; NTSTATUS Hook_ZwTerminateProcess(     IN HANDLE              ProcessHandle OPTIONAL,     IN NTSTATUS            ExitStatus) {     NTSTATUS rc;     PEPROCESS pRocess;     UCHAR *pszProcessName;     //UCHAR *pszProcessName = PsGetProcessImageFileName();     rc = ObReferenceObjectByHandle(ProcessHandle, GENERIC_ALL, *PsProcessType, KernelMode, &pRocess, NULL);     if (!NT_SUCCESS(rc))     {                  return OldZwTerminateProcess(ProcessHandle, ExitStatus);     }     pszProcessName = PsGetProcessImageFileName(pRocess);     if (strstr(pszProcessName, "calc"))     {         return STATUS_ACCESS_DENIED;         ObDereferenceObject(pRocess);     }     ObDereferenceObject(pRocess);     rc = OldZwTerminateProcess(ProcessHandle, ExitStatus);     return rc; } //关闭写保护 1111 1111 1111 1110 1111 1111 1111 1111  VOID _CloseWriteProtected() {     __asm     {         push eax         mov eax, cr0         and eax, 0xFFFEFFFF         mov cr0,eax         pop eax     }     return; } VOID _OpenTheWriteProtected() {     __asm     {         push    eax         mov        eax, cr0         or eax, NOT 0xFFFEFFFF         mov        cr0, eax         pop        eax     }     return; } void HOOK() {     //370是ntTerminateProcess 也可以写成 base + sizeof(type) *n = *(KeServiceDescriptorTable.Base) + 4 * 370 = NtTinminateProcess的地址     /*     OldZwTerminateProcess = (PfnZwTerminateProcess)(*(KeServiceDescriptorTable.Base) + 370 * 4);     */     OldZwTerminateProcess = (PfnZwTerminateProcess)KeServiceDescriptorTable.Base[370];     _CloseWriteProtected();     //     KeServiceDescriptorTable.Base[370] = (int)Hook_ZwTerminateProcess;      _OpenTheWriteProtected(); } void UnHook() {     _CloseWriteProtected();     //     KeServiceDescriptorTable.Base[370] = (int)OldZwTerminateProcess;      _OpenTheWriteProtected(); } NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObj, PUNICODE_STRING pRegPath) {          pDriverObj->DriverUnload = DriverUnLoad;          HOOK();     return STATUS_SUCCESS; }    

总的来说如果按照服务号来HOOK是很简单的.如果没有服务号你怎么HOOK?
其实在32位下.你调用的函数.里面就有调用号.内核也跟应用层的调用号是息息相关的.我们可以取得函数调用号进行HOOK也可以.

如:

未测试. KeServiceDescriptorTable.Base[*(PULONG)((PUCHAR)_FUNCTION +1)];

其中_FUNCTION用名字修改即可.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!