09SSDT概述

Posted ltyandy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了09SSDT概述相关的知识,希望对你有一定的参考价值。


SSDT概述

通过08内核编程HOOK_KiFastCall.md可以知道,用户层的函数调用都会进入到0环, 0环将服务函数的地址实现保存在SSDT表中. KiFastCallEntry函数会使用调用号找到函数的参数个数表和函数地址表, 并将用户栈的参数拷贝到内核栈,最后调用了系统服务表中的函数.

SSDT HOOK的原理很简单: 找到SSDT,将对应的函数地址进行替换,就完成HOOK了.

在进行HOOK的过程中,唯一需要注意的是: SSDT表是不可写的, 强行写入会产生内存访问异常, 但是也有方法使其变成可写:

  1. 关闭CR0寄存器中的WP位 这个位是用于控制是否开启页保护的, 当其被置1, CPU就会做写入检查, 当其置0,就不做检查.(02_寄存器.md)

  2. 使用MDL重新映射SSDT表的元素,这样也可以进行写入(04内核编程内核新概念.md)

HOOK 代码

#include <ntddk.h>
?
typedef struct _KSYSTEM_SERVICE_TABLE

   PULONG ServiceTableBase;   //函数地址表的首地址
   PULONG ServiceCounterTableBase;// 函数表中每个函数被调用的次数
   ULONG   NumberOfService;// 服务函数的个数, NumberOfService * 4 就是整个地址表的大小
   UCHAR*   ParamTableBase; // 参数个数表首地址
KSYSTEM_SERVICE_TABLE, *PKSYSTEM_SERVICE_TABLE;
?
typedef struct _KSERVICE_TABLE_DESCRIPTOR

   KSYSTEM_SERVICE_TABLE   ntoskrnl;// ntoskrnl.exe的服务函数,即SSDT
   KSYSTEM_SERVICE_TABLE   win32k; // win32k.sys的服务函数(GDI32.dll/User32.dll 的内核支持),即ShadowSSDT
   KSYSTEM_SERVICE_TABLE   notUsed1; // 不使用
   KSYSTEM_SERVICE_TABLE   notUsed2; // 不使用
KSERVICE_TABLE_DESCRIPTOR, *PKSERVICE_TABLE_DESCRIPTOR;
typedef NTSTATUS(NTAPI*FnZwOpenProcess)(PHANDLE ProcessHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PCLIENT_ID ClientId);
?
?
?
void OnUnLoad(DRIVER_OBJECT* driver);
?
void installHookSSDT();
void uninstallHook();
void disablePageWriteProtect();
void enablePageWriteProtect();
NTSTATUS NTAPI MyZwOpenProcess(PHANDLE ProcessHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PCLIENT_ID ClientId);
?
?
FnZwOpenProcess g_oldZwOpenProcess; // 原始ZwOpenProcess函数
ULONG           g_uPid; // 需要保护的进程ID, 这个PID可以通过内核通讯来修改.
KSERVICE_TABLE_DESCRIPTOR* g_pServiceTable = NULL;
?
NTSTATUS DriverEntry(DRIVER_OBJECT* driver, UNICODE_STRING* path)

?
   DbgBreakPoint();
   driver->DriverUnload = OnUnLoad;
?
   // 安装HOOK
   installHookSSDT();
?
   return STATUS_SUCCESS;

?
void OnUnLoad(DRIVER_OBJECT* driver)

   // 卸载HOOK
   uninstallHook();

?
void installHookSSDT()

   // 1. 找到SSDT表的首地址
   // 1.1 在分析KiFastCallEntry时, 可以看到系统从KPCR中取出了当前线程对象
   //     然后又从当前线程对象(KTHREAD)中取出了ServiceTable.因此,可以仿照
   //     这个做法.
   // 1.2 ServiceTable在KTHREAD的以下偏移:
   //       +0x0bc ServiceTable     : Ptr32 Void
   PETHREAD* pCurThread = PsGetCurrentThread();
?
   g_pServiceTable = (KSERVICE_TABLE_DESCRIPTOR*)
       (*(ULONG*)((ULONG_PTR)pCurThread + 0xBC));
?
   // 2. 找到函数在表中的位置(其位置就是调用号.)
   // 2.1 保存旧的函数地址(0xBE是ZwOpenProcess函数)
   g_oldZwOpenProcess =
       (FnZwOpenProcess)g_pServiceTable->ntoskrnl.ServiceTableBase[0xBE];
?
   // 3. 将内存分页设置为可写
   disablePageWriteProtect();
   // 4. 写入新函数地址到SSDT表中
   g_pServiceTable->ntoskrnl.ServiceTableBase[0xBE] = (PULONG)MyZwOpenProcess;
   // 5. 将内存分页属性恢复不可写
   enablePageWriteProtect();

?
void uninstallHook()

   if (g_oldZwOpenProcess)
  
       // 1. 将内存分页设置为可写
       disablePageWriteProtect();
       // 2. 写入新函数地址到SSDT表中
       g_pServiceTable->ntoskrnl.ServiceTableBase[0xBE] = (PULONG)g_oldZwOpenProcess;
       // 3. 将内存分页属性恢复不可写
       enablePageWriteProtect();
  

?
NTSTATUS NTAPI MyZwOpenProcess(PHANDLE ProcessHandle,
                               ACCESS_MASK DesiredAccess,
                               POBJECT_ATTRIBUTES ObjectAttributes,
                               PCLIENT_ID ClientId)

   if (ClientId->UniqueProcess == g_uPid)
  
       DesiredAccess = 0; // 将访问权限置零
  
   // 调用原始函数
   return g_oldZwOpenProcess(ProcessHandle,
                             DesiredAccess,
                             ObjectAttributes,
                             ClientId);

?
// 关闭内存页写入保护
void _declspec(naked) disablePageWriteProtect()

   _asm
  
       push eax;
       mov eax, cr0;
       and eax, ~0x10000;
       mov cr0, eax;
       pop eax;
       ret;
  

?
// 开启内存页写入保护
void _declspec(naked) enablePageWriteProtect()

   _asm
  
       push eax;
       mov eax, cr0;
       or eax, 0x10000;
       mov cr0, eax;
       pop eax;
       ret;
  

以上是关于09SSDT概述的主要内容,如果未能解决你的问题,请参考以下文章

Ansible概述

Tomcat概述

Git概述

消息队列概述

MongoDB概述与部署

基础知识(09) -- Spring 概述