SSDT Hook For Delphi
标 题: 【原创】SSDT Hook For Delphi
作 者: Anskya
时 间: 2008-04-23,11:49:56
链 接: http://bbs.pediy.com/showthread.php?t=63611
关于SSDT Hook的理论知识就不多说了。
简单的说一下Delphi开发KMD的一些需要注意的地方...
这里使用DDDK---有点自己修改过的痕迹不过区别不大...自己可以看代码
1.KeServiceDescriptorTable是一个很特殊的函数...如果直接使用implib来进行创建库的话
你会发现这个函数是被忽略的...因为偏移为0所以这个函数基本上只能起到标志作用没有任何实用价值....一些代码中出现了
代码:
function SystemService(AFunc:Pointer):PLONG;begin Result:=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...,etc
vc的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(心灵秘境的那张专辑让人心醉。。。)
转载请保留版权.原文出处:看雪论坛
上传的附件
NtOpenProcess[SSDT Hook].rar (9.2 KB, 745 次下载)
此帖于 2008-04-23 11:52:06 被 Anskya 最后编辑
[公告]请注意言行举止,不要让大家觉得不适! 有点累了初级会员
资 料: 注册日期: Jul 2005
帖子:
5精华: 0
现金: 200 Kx
致谢数: 0
获感谢文章数:0
获会员感谢数:0
2 2008-04-23, 11:54:45
支持 , 王
[公告]如果你觉得有人语言挑衅,请点每帖右上角的“举报”按钮! combojiang『编程技术小组』
资 料: 注册日期: May 2007
帖子:
742精华:
26现金: 107 Kx
致谢数: 1
获感谢文章数:0
获会员感谢数:0
3 2008-04-23, 12:25:53
呵呵,虽然不懂dephi,但是好贴还是要顶的。
[招生]15PB开始接受第002期报名! 十指紧扣初级会员
资 料: 注册日期: Sep 2006
帖子:
72精华: 0
现金: 202 Kx
致谢数: 0
获感谢文章数:0
获会员感谢数:0
4 2008-04-23, 13:01:44
KeServiceDescriptorTable是一个很特殊的函数....
KeServiceDescriptorTable不是函数!
[公告]如果你觉得有人语言挑衅,请点每帖右上角的“举报”按钮! hmilywen初级会员
资 料: 注册日期: Apr 2007
帖子:
483精华: 0
现金: 253 Kx
致谢数: 11
获感谢文章数:5
获会员感谢数:12
5 2008-04-23, 13:02:05
女王很好~~
[招生]15PB开始接受第002期报名! smnk初级会员
资 料: 注册日期: Jun 2007
帖子:
73精华: 0
现金: 158 Kx
致谢数: 0
获感谢文章数:2
获会员感谢数:2
6 2008-04-23, 20:37:06
顶下小0~~~~~
[公告]如果你觉得有人语言挑衅,请点每帖右上角的“举报”按钮! zhuwg高级会员
资 料: 注册日期: Jul 2005
帖子:
684精华:
11现金: 286 Kx
致谢数: 11
获感谢文章数:1
获会员感谢数:1
7 2008-04-23, 21:03:18
进来支持女王大牛
偶不懂delphi。。不过KeServiceDescriptorTable这个是导出函数,
在C的DDK里面可以直接extern 能够得到正确的系统地址
[公告]请注意言行举止,不要让大家觉得不适! 靴子初级会员
资 料: 注册日期: Mar 2008
帖子:
230精华: 0
现金: 233 Kx
致谢数: 3
获感谢文章数:1
获会员感谢数:1
8 2008-04-23, 21:57:37
如何加载这个sys呢。。
[公告]如果你觉得有人语言挑衅,请点每帖右上角的“举报”按钮! 十指紧扣初级会员
资 料: 注册日期: Sep 2006
帖子:
72精华: 0
现金: 202 Kx
致谢数: 0
获感谢文章数:0
获会员感谢数:0
9 2008-04-24, 08:55:27
引用:
最初由 zhuwg发布
进来支持女王大牛
偶不懂delphi。。不过KeServiceDescriptorTable这个是导出函数,
在C的DDK里面可以直接extern 能够得到正确的系统地址
变量而已。。。
[公告]请注意言行举止,不要让大家觉得不适! hpxpj普通会员
资 料: 注册日期: Apr 2007
帖子:
88精华:
1现金: 208 Kx
致谢数: 0
获感谢文章数:0
获会员感谢数:0
10 2008-04-24, 09:12:47
引用:
最初由 靴子发布
如何加载这个sys呢。。
自己编写或随便找个能加载sys的软件如:InstDRV
[公告]如果你觉得有人语言挑衅,请点每帖右上角的“举报”按钮! 迷茫小猪初级会员
资 料: 注册日期: Nov 2007
帖子:
144精华: 0
现金: 193 Kx
致谢数: 0
获感谢文章数:0
获会员感谢数:0
11 2008-04-24, 10:04:03
是不是跟API HOOK差不多呀
[公告]请注意言行举止,不要让大家觉得不适! myqingniao初级会员
资 料: 注册日期: Apr 2006
帖子:
42精华: 0
现金: 215 Kx
致谢数: 0
获感谢文章数:0
获会员感谢数:0
12 2008-04-24, 22:57:13
这个女的真的很厉害啊!
牛一个
[公告]如果你觉得有人语言挑衅,请点每帖右上角的“举报”按钮! 海浪轻风普通会员
资 料: 注册日期: Jun 2006
帖子:
77精华:
1现金: 209 Kx
致谢数: 0
获感谢文章数:0
获会员感谢数:0
13 2008-04-25, 09:03:59
支持牛人!!
[公告]请注意言行举止,不要让大家觉得不适! mickeylan『编程技术小组』
资 料: 注册日期: Aug 2004
帖子:
154精华:
14现金: 138 Kx
致谢数: 0
获感谢文章数:0
获会员感谢数:0
14 2008-05-27, 21:17:00
引用:
最初由 myqingniao发布
这个女的真的很厉害啊!
牛一个
你怎么知道别人是女的?顶一个
[公告]如果你觉得有人语言挑衅,请点每帖右上角的“举报”按钮! dalong初级会员
资 料: 注册日期: Jan 2005
帖子:
24精华: 0
现金: 238 Kx
致谢数: 0
获感谢文章数:0
获会员感谢数:0
15 2008-07-29, 11:29:58
初学驱动,看不大明白,LZ发布的SSDT Hook For Delphi 这个程序和楼主发布的Pure Delphi Code恢复驱动哪个好用,容易上手??
好像卡巴已经杀了SSDT Hook For Delphi 这个驱动了吧,我安装后驱动没能恢复呀!