x86下以ntopenprocess为例的SSDTHook

来源:互联网 发布:阿里云自定义监控实例 编辑:程序博客网 时间:2024/06/06 00:30
#include "SSDTHook32.h"PVOID   __ServiceTableBase = NULL;ULONG32 __NtOpenProcessIndex = 0;PVOID   __OldNtOpenProcess = NULL;BOOLEAN __IsHook = FALSE;NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegisterPath){NTSTATUS Status = STATUS_SUCCESS;ULONG32  v1 = 0;char FunctionName[] = "NtOpenProcess";//要钩的函数名DriverObject->DriverUnload = Unload;__NtOpenProcessIndex = 0x0be;/*ntdll!ZwOpenProcess:77585dc8 b8be000000      mov     eax,0BEh77585dcd ba0003fe7f      mov     edx,offset SharedUserData!SystemCallStub (7ffe0300)77585dd2 ff12            call    dword ptr [edx]77585dd4 c21000          ret     10h77585dd7 90              nop*///这里我们得知函数索引为0be//并且直接得到了SSDT地址即 extern PSERVER_SERVICE_DESCRIPTOR_TABLE KeServiceDescriptorTable;if (KeServiceDescriptorTable == NULL){return Status;}//base首地址   SSDT第一成员__ServiceTableBase = ((PSERVER_SERVICE_DESCRIPTOR_TABLE)KeServiceDescriptorTable)->Unknow0;//需要的函数(直接地址)__OldNtOpenProcess = ((PULONG32)__ServiceTableBase)[__NtOpenProcessIndex];//直接更改函数地址HookSSDT(__ServiceTableBase, __NtOpenProcessIndex, FakeOpenProcess);return Status;}VOID HookSSDT(PVOID ServiceTableBase, ULONG32 SSDTFunctionIndex, PVOID FakeFunctionAddress){ULONG32  v1 = 0;WPOFF();((PULONG32)__ServiceTableBase)[__NtOpenProcessIndex] = FakeFunctionAddress;WPON();__IsHook = TRUE;}VOID UnHookSSDT(){WPOFF();((PULONG32)__ServiceTableBase)[__NtOpenProcessIndex] = __OldNtOpenProcess;WPON();}VOID WPOFF(){_disable();__writecr0(__readcr0() & (~(0x10000)));}VOID WPON(){__writecr0(__readcr0() ^ 0x10000);_enable();}VOID Unload(PDRIVER_OBJECT DriverObject){DbgPrint("ByeByeDriver\r\n");if (__IsHook){UnHookSSDT();__IsHook = FALSE;}}NTSTATUS FakeOpenProcess(_Out_    PHANDLE            ProcessHandle,_In_     ACCESS_MASK        DesiredAccess,_In_     POBJECT_ATTRIBUTES ObjectAttributes,_In_opt_ PCLIENT_ID         ClientID){PEPROCESS  EProcess = PsGetCurrentProcess();    //进程上下背景文if (EProcess != NULL&&MmIsAddressValid(EProcess)){//通过EProcess 获得进程名称 char *ProcessImageName = PsGetProcessImageFileName(EProcess);    //0x2e0 if (strstr(ProcessImageName, "EnumProcess") != 0){return STATUS_ACCESS_DENIED;  //黑名单}}((pfnNtOpenProcess)__OldNtOpenProcess)(ProcessHandle, DesiredAccess, ObjectAttributes, ClientID);  //白名单}

//以上为代码实现

运行环境为win7(32)

#pragma once#include <ntddk.h>typedef struct _SERVER_SERVICE_DESCRIPTOR_TABLE_{PVOID Unknow0;PVOID Unknow1;PVOID Unknow2;PVOID Unknow3;}SERVER_SERVICE_DESCRIPTOR_TABLE, *PSERVER_SERVICE_DESCRIPTOR_TABLE;VOID Unload(PDRIVER_OBJECT DriverObject);VOID HookSSDT(PVOID ServiceTableBase, ULONG32 SSDTFunctionIndex, PVOID FakeFunctionAddress);VOID UnHookSSDT();VOID WPOFF();VOID WPON();NTSTATUS FakeOpenProcess(_Out_    PHANDLE            ProcessHandle,_In_     ACCESS_MASK        DesiredAccess,_In_     POBJECT_ATTRIBUTES ObjectAttributes,_In_opt_ PCLIENT_ID         ClientID);extern PSERVER_SERVICE_DESCRIPTOR_TABLE KeServiceDescriptorTable;externchar* PsGetProcessImageFileName(PEPROCESS EProcess);typedefNTSTATUS(*pfnNtOpenProcess)(_Out_    PHANDLE            ProcessHandle,_In_     ACCESS_MASK        DesiredAccess,_In_     POBJECT_ATTRIBUTES ObjectAttributes,_In_opt_ PCLIENT_ID         ClientID);
//以上为SSDTHook32.h的头文件

//其实原理非常简单 就是获取SSDT地址 然后更改目标函数地址(因为32位下SSDT存入的是函数的直接地址)

//获取SSDT方法在代码批注里有所说明

//如何得到目标函数的索引 可以从Ntdll中查找相关函数的调用 具体可以通过调试得到

//此例函数索引中为windbg7(32)中得到的

0 0
原创粉丝点击