HOOK钩子技术5 SSDT Inline Hook

原理

内联钩子的原理在R3和R0下是相同的,就是不改变SSDT表项,而是改变函数内部前几条指令。 内联钩子的典型伪函数为:

demo__cplusplusextern “C” NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath);#endiftypedef NTSTATUS (*NtCreateProcess)(OUT PHANDLEProcessHandle,IN ACCESS_MASKDesiredAccess,IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,IN HANDLEParentProcess,IN BOOLEANInheritObjectTable,IN HANDLESectionHandle OPTIONAL,IN HANDLEDebugPort OPTIONAL,IN HANDLEExceptionPort OPTIONAL ,IN ULONGJobMemberLevel ); typedef struct _SERVICE_DESCRIPTOR_TABLE{PULONG ServiceTableBase;PULONG ServiceCounterTableBase;ULONG NumberOfService;PUCHAR ParamTableBase;}SERVICE_DESCRIPTOR_TABLE,*PSERVICE_DESCRIPTOR_TALBE;NtCreateProcess real_func_addr = NULL;unsigned char bOldBytes[5];unsigned char bNewBytes[5];extern “C” PSERVICE_DESCRIPTOR_TALBE KeServiceDescriptorTable;//name can’t change. import member must be global variable./*cr0 -16th bit = 0 means page can write*/bool REMOVE_ONLYREAD(){__asm{push eaxmov eax,CR0and eax, not 10000hmov CR0,eaxpop eax}return TRUE;}/*cr0 -16th bit(WP) = 1,reset to the attribute of ONLY READ*/bool RESET_ONLYREAD(){__asm{push eaxmov eax,CR0or eax,10000hmov CR0,eaxpop eax}return TRUE;}VOID RelineHookCreateProcess(){REMOVE_ONLYREAD();//writememory with “jmp xxxxxxxx”;RtlCopyMemory((PVOID)real_func_addr,(CONST PVOID)bNewBytes,5);RESET_ONLYREAD();}VOID UnHookCreateProcess(){REMOVE_ONLYREAD();//__asm int 3RtlCopyMemory((PVOID)real_func_addr,(const PVOID)bOldBytes,5);RESET_ONLYREAD();}void InlineSSDTHookUnload(PDRIVER_OBJECT pDriverObject) //no return ,with return compiler error{UnHookCreateProcess();DbgPrint(“GoodBye from InlineHook!\n”);}NTSTATUS MyNtCreateProcessEx(OUT PHANDLEProcessHandle,IN ACCESS_MASKDesiredAccess,IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,IN HANDLEParentProcess,IN BOOLEANInheritObjectTable,IN HANDLESectionHandle OPTIONAL,IN HANDLEDebugPort OPTIONAL,IN HANDLEExceptionPort OPTIONAL ,IN ULONGJobMemberLevel){NTSTATUS Status = STATUS_SUCCESS;UnHookCreateProcess();Status = real_func_addr(ProcessHandle,DesiredAccess,ObjectAttributes,ParentProcess,InheritObjectTable,SectionHandle ,DebugPort ,ExceptionPort ,JobMemberLevel);RelineHookCreateProcess();DbgPrint(“have hook CreateProcess!\r\n”);return Status;}NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath){unsigned i;DbgPrint(“Hello from InlineSSDTHook!\n”);DriverObject->DriverUnload = InlineSSDTHookUnload;//hookPULONG PSsdt = (PULONG)KeServiceDescriptorTable->ServiceTableBase;PULONG p_real_func_addr =PSsdt+0x30;//(unsigned char *) pssdt+0x30*4;DbgPrint(“%08x,%08x”,p_real_func_addr,PSsdt+0x30); //diff compared with ssdt hookreal_func_addr = (NtCreateProcess)(*p_real_func_addr);//__asm int 3RtlCopyMemory((PVOID)bOldBytes,(CONST PVOID)real_func_addr,5);bNewBytes[0] =’\xe9′;*(PULONG)&bNewBytes[1]=(ULONG)MyNtCreateProcessEx-(ULONG)real_func_addr-5;//__asm int 3RtlCopyMemory((PVOID)real_func_addr,(CONST PVOID)bNewBytes,5);return STATUS_SUCCESS;}

今天在做实验的时候,老是出错,无语了。在本地加载了程序的符号文件后调试出现各种奇葩问题,比如说函数入口指令的第一个字节总是没有改回来,后来也不知道怎么解决的。

挂钩后不能打开程序,提示文件错误 ,,但是停止服务后恢复正常,所以怀疑是伪函数执行时候有错误,查了半天也没有错误。最后发现是少了一个参数,我函数指针定义成nt!NtCreatProcess 的参数了,nt!NtCreateProcessEx 比nt!ntCreateProces 多了一个参数JobMemeberLevel 。

typedef NTSTATUS (*NtCreateProcessEx)(OUT PHANDLEProcessHandle,IN ACCESS_MASKDesiredAccess,IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,IN HANDLEParentProcess,IN BOOLEANInheritObjectTable,IN HANDLESectionHandle OPTIONAL,IN HANDLEDebugPort OPTIONAL,IN HANDLEExceptionPort OPTIONAL ,/*************/IN ULONGJobMemberLevel );

可是非常奇怪,参数错误函数执行肯定出错,昨天的SSDT HOOK却也是少了这个参数,挂钩函数也是nt!ntCreateProcessEx,按理说应该出错啊,为什么昨天的又是正确的呢???参数不一致也可以?仔细研究一下。

命运掌握在自己手中

HOOK钩子技术5 SSDT Inline Hook

相关文章:

你感兴趣的文章:

标签云: