驱动:HooK内核函数为自己的函数(来自网络)
hook不同的函数,需要定义相对应的函数原型,本例原型为NTOpenProcess
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
#include <ntdef.h> LONG preAddr,curAddr,writeAddr; bool isHook; //驱动入口 extern "C" NTSTATUS DriverEntry( PDRIVER_OBJECT pDriObj, PUNICODE_STRING pRegStr) { isHook = false; //标示没有Hook DbgPrint("Driver Entry..\n"); //linktest(); UNICODE_STRING functionname; RtlInitUnicodeString(&functionname, L"NtOpenProcess"); DbgPrint("%ws current address:%x \n",functionname.Buffer, curAddr = GetSSDTFunctionAddr(HOOKOFFSET)); DbgPrint("%ws source address:%x \n",functionname.Buffer, preAddr = GetSystemRoutineAddr(&functionname)); if(curAddr == preAddr){ DbgPrint("program wasn't hook! but will be.."); } SSDTWrite((LONG)HookFunction, HOOKOFFSET); isHook = true; pDriObj->DriverUnload = MyUnloadDriver; return STATUS_SUCCESS; } //卸载函数 VOID MyUnloadDriver(PDRIVER_OBJECT pDriObj) { DbgPrint("Driver Unload!"); if(isHook)SSDTWrite(preAddr,HOOKOFFSET); } /* *获取SSDT表中functionname函数的当前地址 */ LONG GetSSDTFunctionAddr(int pOffset) { DbgPrint("In the SSDTWrite function..\n"); LONG basePtr; int iOffset = pOffset*4; _asm{ push eax push ebx mov ebx, KeServiceDescriptorTable mov ebx,[ebx] mov eax, iOffset add ebx,eax mov writeAddr,eax //将要写入jmp代码的地址 mov ebx,[ebx] mov basePtr,ebx //现在该地址的代码 pop ebx pop eax } return basePtr; } /* *获取SSDT表中functionname函数的原地址 */ LONG GetSystemRoutineAddr(PUNICODE_STRING functionname) { LONG ret = NULL; return ret = (LONG)MmGetSystemRoutineAddress(functionname); //原地址的 } /* *用writeAddress地址,来代替SSDT表中相应函数的地址,其中iOffset是函数的偏移 */ VOID SSDTWrite(const LONG writeAddress, int iOffset) { DbgPrint(" \n HOOK \n"); LONG *SSDT_ADR,t_addr; t_addr = (LONG)KeServiceDescriptorTable->ServiceTableBase; SSDT_ADR = (PLONG)(t_addr+iOffset*4); PHookFunction = (MyFunction *)writeAddress; _asm{ cli mov eax,cr0 and eax,not 10000h mov cr0,eax } *SSDT_ADR = (ULONG)PHookFunction; _asm{ mov eax,cr0 mov ebx,10000h or eax,ebx mov cr0,eax sti } } //自己的函数用来代替内核函数 NTSTATUS HookFunction( OUT PHANDLE ProcessHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, IN PCLIENT_ID ClientId ) { DbgPrint("嘿嘿come here"); ProcessHandle = NULL; return STATUS_ACCESS_DENIED; } |
头文件,其中122标示为SSDT表的第122个函数NTOpenProcess
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
#ifdef __cplusplus extern "C" { #endif #include "ntddk.h" #ifdef __cplusplus } #endif #define HOOKOFFSET 122 VOID MyUnloadDriver(PDRIVER_OBJECT pDriObj); LONG GetSSDTFunctionAddr(int pOffset); LONG GetSystemRoutineAddr(PUNICODE_STRING functionname); VOID SSDTWrite(const LONG writeAddress, int iOffset); extern "C" NTSTATUS __stdcall HookFunction( OUT PHANDLE ProcessHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, IN PCLIENT_ID ClientId ) ; extern "C" typedef NTSTATUS __stdcall MyFunction( OUT PHANDLE ProcessHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, IN PCLIENT_ID ClientId ) ; MyFunction * PHookFunction; typedef struct _ServiceDescriptorTable { PVOID ServiceTableBase; //System Service Dispatch Table 的基地址 PVOID ServiceCounterTable; //包含着 SSDT 中每个服务被调用次数的计数器。这个计数器一般由sysenter 更新。 unsigned int NumberOfServices;//由 ServiceTableBase 描述的服务的数目。 PVOID ParamTableBase; //包含每个系统服务参数字节数表的基地址-系统服务参数表 }*PServiceDescriptorTable; extern "C" PServiceDescriptorTable KeServiceDescriptorTable; |

浙公网安备 33010602011771号