一、效果图
二、分析
这里对NtCreateProcessEx做拦截,用WinDbg来定位该函数在SSDT中的记录地址:
0: kd> dd KeServiceDescriptorTable 8055d700 80505450 00000000 0000011c 805058c4 8055d710 00000000 00000000 00000000 00000000 8055d720 00000000 00000000 00000000 00000000 8055d730 00000000 00000000 00000000 00000000 8055d740 00000002 00002710 bf80c0b6 00000000 8055d750 f8399a80 f82ffb60 820f06b0 806f70c0 8055d760 071d8498 00000000 0b14f8a6 00000000 8055d770 13460466 01cf525a 00000000 00000000 0: kd> dd 80505450 + 0x30 * 4 80505510 805d2136 80618172 805ac3ae 80615702 80505520 805c49b6 805d1fd4 80617622 805fa0e6 80505530 805a60f4 80643f58 806440a8 80617026 80505540 80616858 806170d6 80577c2c 80624c16 80505550 805f5958 80624de6 8057a24a 80613680 80505560 805befc4 805edd88 806170e4 80624fc6 80505570 806170c8 80625230 805b4c9e 805edf34 80505580 8061660c 80577cf8 805b7806 8062549a 0: kd> u 805d2136 nt!NtCreateProcessEx: 805d2136 6a0c push 0Ch 805d2138 68e0b84d80 push offset nt!ObWatchHandles+0x684 (804db8e0) 805d213d e83eaaf6ff call nt!_SEH_prolog (8053cb80) 805d2142 64a124010000 mov eax,dword ptr fs:[00000124h] 805d2148 33d2 xor edx,edx 805d214a 389040010000 cmp byte ptr [eax+140h],dl 805d2150 7435 je nt!NtCreateProcessEx+0x51 (805d2187) 805d2152 8955fc mov dword ptr [ebp-4],edx
三、源代码
#include <ntddk.h> typedef struct _SERVICE_DESCRIPTOR_TABLE { PULONG ServiceTableBase; PULONG ServiceCounterTableBase; ULONG NumberOfServices; PUCHAR ParamTableBase; }SERVICE_DESCRIPTOR_TABLE, *PSERVICE_DESCRIPTOR_TALBLE; extern PSERVICE_DESCRIPTOR_TALBLE KeServiceDescriptorTable; typedef NTSTATUS (*NTCREATEPROCESSEX)(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES, HANDLE, ULONG, HANDLE, HANDLE, HANDLE, ULONG); //保存NtCreateProcessEx函数的地址 NTCREATEPROCESSEX ulNtCreateProcessEx = 0; //在指针数组中NtCreateProcessEx的地址 ULONG ulNtCreateProcessExAddr = 0; VOID UN_PROTECT() { _asm { push eax mov eax,0FFFEFFFFh mov CR0,eax pop eax } } VOID RE_PROTECT() { _asm { push eax mov eax,CR0 or eax,0FFFEFFFFh mov CR0,eax pop eax } } VOID DriverUnload(PDRIVER_OBJECT pDriverObject) { UN_PROTECT(); //替换NtCreateProcessEx的地址为MyNtCreateProcessEx *(PULONG)ulNtCreateProcessExAddr = (ULONG)ulNtCreateProcessEx; RE_PROTECT(); } NTSTATUS MyNtCreateProcessEx ( __out PHANDLE ProcessHandle, __in ACCESS_MASK DesiredAccess, __in_opt POBJECT_ATTRIBUTES ObjectAttributes, __in HANDLE ParentProcess, __in ULONG Flags, __in_opt HANDLE SectionHandle, __in_opt HANDLE DebugPort, __in_opt HANDLE ExceptionPort, __in ULONG JobMemberLevel ) { NTSTATUS Status = STATUS_SUCCESS; KdPrint(("Enter MyNtCreateProcessEx! ")); Status = ulNtCreateProcessEx(ProcessHandle, DesiredAccess, ObjectAttributes, ParentProcess, Flags, SectionHandle, DebugPort, ExceptionPort, JobMemberLevel); return Status; } VOID HookCreateProcess() { ULONG ulSsdt = 0; //获取SSDT ulSsdt = (ULONG)KeServiceDescriptorTable->ServiceTableBase; //获取NtCreateProcessEx地址的指针 ulNtCreateProcessExAddr = ulSsdt + 0x30 * 4; //备份NtCreateProcessEx的原始地址 ulNtCreateProcessEx = (NTCREATEPROCESSEX)*(PULONG)ulNtCreateProcessExAddr; UN_PROTECT(); //替换NtCreateProcessEx的地址为MyNtCreateProcessEx *(PULONG)ulNtCreateProcessExAddr = (ULONG)MyNtCreateProcessEx; RE_PROTECT(); } NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegistryPath) { NTSTATUS Status = STATUS_SUCCESS; pDriverObject->DriverUnload = DriverUnload; HookCreateProcess(); return Status; }