来自网上。
typedef struct _SERVICE_DESCRIPTOR_TABLE { PVOID ServiceTableBase; PULONG ServiceCounterTableBase; ULONG NumberOfService; ULONG ParamTableBase; }SERVICE_DESCRIPTOR_TABLE,*PSERVICE_DESCRIPTOR_TABLE; // As KeServiceDescriptorTable only one here on the simple point extern PSERVICE_DESCRIPTOR_TABLE KeServiceDescriptorTable;//KeServiceDescriptorTable For the exported function ///////////////////////////////////// VOID Hook(); VOID Unhook(); VOID OnUnload(IN PDRIVER_OBJECT DriverObject); ////////////////////////////////////// ULONG JmpAddress; //Jump to NtOpenProcess address ULONG OldServiceAddress;//Original NtOpenProcess service address ////////////////////////////////////// __declspec(naked) NTSTATUS __stdcall MyNtOpenProcess(PHANDLE ProcessHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PCLIENT_ID ClientId) { DbgPrint("NtOpenProcess() called"); __asm{ push 0C4h push 804eb560h //10 bytes jmp [JmpAddress] } } /////////////////////////////////////////////////// NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,PUNICODE_STRING RegistryPath) { DriverObject->DriverUnload = OnUnload; DbgPrint("Unhooker load"); Hook(); return STATUS_SUCCESS; } ///////////////////////////////////////////////////// VOID OnUnload(IN PDRIVER_OBJECT DriverObject) { DbgPrint("Unhooker unload!"); Unhook(); } ///////////////////////////////////////////////////// VOID Hook() { ULONG Address; Address = (ULONG)KeServiceDescriptorTable->ServiceTableBase + 0x7A * 4;//0x7A for NtOpenProcess service ID DbgPrint("Address:0xX",Address); OldServiceAddress = *(ULONG*)Address;//Save original NtOpenProcess address DbgPrint("OldServiceAddress:0xX",OldServiceAddress); DbgPrint("MyNtOpenProcess:0xX",MyNtOpenProcess); JmpAddress = (ULONG)NtOpenProcess + 10; //Jump to NtOpenProcess function header +10 DbgPrint("JmpAddress:0xX",JmpAddress); __asm{ //Remove the memory protection cli mov eax,cr0 and eax,not 10000h mov cr0,eax } *((ULONG*)Address) = (ULONG)MyNtOpenProcess; //HOOK SSDT __asm{ //Restore the memory protection mov eax,cr0 or eax,10000h mov cr0,eax sti } } ////////////////////////////////////////////////////// VOID Unhook() { ULONG Address; Address = (ULONG)KeServiceDescriptorTable->ServiceTableBase + 0x7A * 4; //Find SSDT __asm{ cli mov eax,cr0 and eax,not 10000h mov cr0,eax } *((ULONG*)Address) = (ULONG)OldServiceAddress; //Restore SSDT __asm{ mov eax,cr0 or eax,10000h mov cr0,eax sti } //Debugging DbgPrint("Unhook"); }