首页 网络安全 安全学院 查看内容

Delphi实现SSDT Hook

2008-10-20 10:33 918 0

摘要: 关于SSDT Hook的理论知识就不多说了。简单的说一下Delphi开发KMD的一些需要注意的地方...这里使用DDDK---有点自己修改过的痕迹不过区别不大...自己可以看代码1.KeSe...
关键词: nbsp ZwOpenProcess 函数 DbgPrint KeServiceDescrip eax torTable GetImportFunAddr 地址 Address

关于SSDT Hook的理论知识就不多说了。简单的说一下Delphi开发KMD的一些需要注意的地方...这里使用DDDK---有点自己修改过的痕迹不过区别不大...自己可以看代码1.KeServiceDescriptorTable是一个很特殊的函数...如果直接使用implib来进行创建库的话你会发现这个函数是被忽略的...因为偏移为0所以这个函数基本上只能起到标志作用没有任何实用价值....一些代码中出现了代码:function SystemService(AFunc:Pointer):PLONG;beginResult:=PLONG(Cardinal(KeServiceDescriptorTable^.ServiceTableBase)+SizeOf(ULONG)*PULONG(ULONG(AFunc)+1)^);end;很容易让人误认为是运行后的返回值(PS:Delphi的函数调用可以不需要写xxx())上面说过因为这个函数几乎是没用的...所以不可能是执行他后返回地址还有一点需要注意的...难道这个地址是说函数的地址??导入表中的确是可以创建这个函数...但是这个函数几乎是没用的...而且系统的SYS Loader也不可能为他填写正确的函数地址...这里取得地址就是他的本身地址...因为他的虚拟偏移为0所以你直接使用代码:PPointer(@KeServiceDescriptorTable)^;得到这个地址就可以了2.fastcall的问题这个问题很头痛.这个函数和delphi的调用方式完全不一样很容易让人误认为是相同的Delphi的寄存器调用方式是eax,edx,ecx,push...,etcvc的fastcall大部分是edx,ecx,etc....所以为了解决这个问题需要自己重写某些代码部分...3.基本上没什么需要注意了自己做好链接库您当然可以使用mickeylan牛为我们制作的rmcoff...4.调试部分WinDbg什么的我就不说了...因为无法进行源码调试个人觉得SysDebuger就不错其实asm也就那么回事。不是吗?呵呵下面写一个完整的SSDT Hook代码:{   NtOpenProcess[SSDT Hook] By Anskya   Email: Anskya[at]Gmail.com}unit Driver;interfaceuses   ntddk;   // ---->DDDK.pasfunction _DriverEntry(DriverObject: PDriverObject; RegistryPath: PUnicodeString): NTSTATUS; stdcall;implementationtype   TZwOpenProcess = function(ProcessHandle:PHandle; DesiredAccess:TAccessMask; ObjectAttributes:PObjectAttributes; ClientId:PClientId): NTSTATUS; stdcall;var   HookActive: Boolean;   ZwOpenProcessNextHook: TZwOpenProcess;//   从导入表中获取一个函数的地址function GetImportFunAddr(lpImportAddr: Pointer): Pointer; stdcall;begin   Result := PPointer(PPointer(Cardinal(lpImportAddr) + 2)^)^;end;//   KeServiceDescriptorTable+函数名计算SSDT函数偏移function SystemServiceName(AFunc: Pointer): PLONG; stdcall;var   lpKeServiceDescriptorTable: PServiceDescriptorEntry;begin   lpKeServiceDescriptorTable := PPointer(@KeServiceDescriptorTable)^;   Result := PLONG(Cardinal(lpKeServiceDescriptorTable^.ServiceTableBase) + (SizeOf(ULONG) * PULONG(ULONG(AFunc) + 1)^));end;//   KeServiceDescriptorTable+序号名计算SSDT函数偏移function SystemServiceOrd(iOrd: ULONG): PLONG; stdcall;var   lpKeServiceDescriptorTable: PServiceDescriptorEntry;begin   lpKeServiceDescriptorTable := PPointer(@KeServiceDescriptorTable)^;   Result := PLONG(PLONG(Cardinal(lpKeServiceDescriptorTable^.ServiceTableBase) + (SizeOf(ULONG) * iOrd)));end;//   钩子过程function ZwOpenProcessHookProc(ProcessHandle:PHandle; DesiredAccess:TAccessMask; ObjectAttributes:PObjectAttributes; ClientId:PClientId): NTSTATUS; stdcall;begin   DbgPrint('ZwOpenProcess HookProc: NewZwOpenProcess(ProcessHandle:0x%.8X,DesiredAccess:0x%.8X,ObjectAttributes:0x%.8X,ClientId:0x%.8X)',         ProcessHandle, DesiredAccess, ObjectAttributes, ClientId);   Result := ZwOpenProcessNextHook(ProcessHandle, DesiredAccess, ObjectAttributes, ClientId);   DbgPrint('ZwOpenProcess HookProc: NewZwOpenProcess(-):0x%.8X', Result);end;//   驱动卸载过程procedure DriverUnload(DriverObject:PDriverObject); stdcall;begin   if (HookActive) then   begin     asm       cli                                               //disable WP bit       push   eax       mov   eax, cr0                                     //move CR0 register into EAX       and   eax, not 000010000h                         //disable WP bit       mov   cr0, eax                                     //write register back       pop   eax     end;     ZwOpenProcessNextHook := TZwOpenProcess(xInterlockedExchange(SystemServiceName(GetImportFunAddr(@ZwOpenProcess)), LONG(@ZwOpenProcessNextHook)));     asm       push   eax                                           //enable WP bit       mov   eax, cr0                                       //move CR0 register into EAX       or     eax, 000010000h                               //enable WP bit       mov   cr0, eax                                       //write register back       pop   eax       sti     end;     DbgPrint('ZwOpenProcess New Address: 0x%.8X', SystemServiceName(GetImportFunAddr(@ZwOpenProcess))^);     DbgPrint('ZwOpenProcess Old Address: 0x%.8X', DWORD(@ZwOpenProcessNextHook));     HookActive := False;   end;   DbgPrint('DriverUnload(-)');end;//   驱动入口点function _DriverEntry(DriverObject:PDriverObject;RegistryPath:PUnicodeString): NTSTATUS; stdcall;begin   DriverObject^.DriverUnload := @DriverUnload;   Result := STATUS_SUCCESS;   DbgPrint('DriverEntry(-):0x%.8X', Result);   HookActive := False;   DbgPrint('ZwOpenProcess Import Address: 0x%.8X', GetImportFunAddr(@ZwOpenProcess));   DbgPrint('KeServiceDescriptorTable() Address 1: 0x%.8X', @KeServiceDescriptorTable);   DbgPrint('KeServiceDescriptorTable() Address 2: 0x%.8X', PPointer(@KeServiceDescriptorTable)^);   DbgPrint('ZwOpenProcess ord Address: 0x%.8X', SystemServiceOrd($7A)^);     //   XP ord!   DbgPrint('ZwOpenProcess Name Address: 0x%.8X', SystemServiceName(GetImportFunAddr(@ZwOpenProcess))^);   DbgPrint('ZwOpenProcess HookProc Address: 0x%.8X', @ZwOpenProcessHookProc);   if (Not HookActive) then   begin     //   SSDT Hook     asm                                             //disable WP bit       cli       push   eax       mov   eax, cr0                                   //move CR0 register into EAX       and   eax, not 000010000h                         //disable WP bit       mov   cr0, eax                                   //write register back       pop   eax     end;     //lpNew^ := LONG(lpOld);     ZwOpenProcessNextHook := TZwOpenProcess(xInterlockedExchange(SystemServiceName(GetImportFunAddr(@ZwOpenProcess)), LONG(@ZwOpenProcessHookProc)));     asm       push   eax                                       //enable WP bit       mov   eax, cr0                                   //move CR0 register into EAX       or     eax, 000010000h                           //enable WP bit       mov   cr0, eax                                   //write register back       pop   eax       sti     end;     DbgPrint('ZwOpenProcess New Address: 0x%.8X', SystemServiceName(GetImportFunAddr(@ZwOpenProcess))^);     DbgPrint('ZwOpenProcess Old Address: 0x%.8X', DWORD(@ZwOpenProcessNextHook));     HookActive := True;   end else   begin     DbgPrint('ZwOpenProcess Hooked!!! By Anskya');   end;end;end.关于function GetImportFunAddr(lpImportAddr: Pointer): Pointer; stdcall;这个函数稍微说一下...如果你使用的连接库是x86模式的你就不能这样了。。。这个是标准格式...call [xxxx]---->jmp [xxxxxx]---->函数地址x86模式的lib是直接call [xxxx]---->函数地址这里需要注意一下这个函数你可以本地获取一下Ring3下的函数地址吧...这个我就不多说了...相信大家import hook玩的都比我熟现在正在自己整理一个头部...当然也是站在各位前辈的肩膀上进行更新的心得:有的时候觉得Delphi写驱动也很有意思,相对来说比较简单...入门不错(就是编译方面比较麻烦..但是翻译的同时也学到了许多东西.我喜欢这份工作...以后会有更多的东西呈现给大家看看...由于小弟初次接触底层相关的东西难免有错误希望大家海涵,还有指出。我会虚心接受的。)没太大必最好不要用Delphi去写这个。头部翻译麻烦,源码级调试,等等问题。。。还有就是您真的有这个必要吗?写一些简单的不错。。。KMD方面的还行。。。感谢:zhuwg(孜孜不倦的为小弟解答问题.提供了许多资料和私货)Holy Father(DDDK的确开辟了.驱动编程的...什么什么)mickeylan(感谢为Delphi fans所做的一切)Ron Korb(心灵秘境的那张专辑让人心醉。。。)
声明:文章版权归原作者所有 部分文章转自互联网 如有侵权请联系 [邮箱地址] 删除

路过

雷人

握手

鲜花

鸡蛋

最新评论

返回顶部