首页
论坛
课程
招聘
[原创]SSDT Hook For Delphi
2008-4-23 11:49 16425

[原创]SSDT Hook For Delphi

2008-4-23 11:49
16425
关于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;

interface

uses
  ntddk;  // ---->DDDK.pas

function _DriverEntry(DriverObject: PDriverObject; RegistryPath: PUnicodeString): NTSTATUS; stdcall;

implementation

type
  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(心灵秘境的那张专辑让人心醉。。。)

转载请保留版权.原文出处:看雪论坛

【看雪培训】《Adroid高级研修班》2022年夏季班招生中!

上传的附件:
收藏
点赞0
打赏
分享
最新回复 (20)
雪    币: 200
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
有点累了 活跃值 2008-4-23 11:54
2
0
支持 ,   王  
雪    币: 109
活跃值: 活跃值 (197)
能力值: ( LV13,RANK:1050 )
在线值:
发帖
回帖
粉丝
combojiang 活跃值 26 2008-4-23 12:25
3
0
呵呵,虽然不懂dephi,但是好贴还是要顶的。
雪    币: 202
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
十指紧扣 活跃值 2008-4-23 13:01
4
0
KeServiceDescriptorTable是一个很特殊的函数....

KeServiceDescriptorTable不是函数!
雪    币: 960
活跃值: 活跃值 (245)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
hmilywen 活跃值 2008-4-23 13:02
5
0
女王很好~~
雪    币: 158
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
smnk 活跃值 2008-4-23 20:37
6
0
顶下小0~~~~~
雪    币: 308
活跃值: 活跃值 (76)
能力值: ( LV12,RANK:470 )
在线值:
发帖
回帖
粉丝
zhuwg 活跃值 11 2008-4-23 21:03
7
0
进来支持女王大牛

偶不懂delphi。。不过KeServiceDescriptorTable这个是导出函数,
在C的DDK里面可以直接extern 能够得到正确的系统地址
雪    币: 23
活跃值: 活跃值 (250)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
靴子 活跃值 2008-4-23 21:57
8
0
如何加载这个sys呢。。
雪    币: 202
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
十指紧扣 活跃值 2008-4-24 08:55
9
0
变量而已。。。
雪    币: 208
活跃值: 活跃值 (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
hpxpj 活跃值 1 2008-4-24 09:12
10
0
[quote=靴子]
如何加载这个sys呢。。
[/quote]
自己编写或随便找个能加载sys的软件如:InstDRV
雪    币: 193
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
迷茫小猪 活跃值 2008-4-24 10:04
11
0
是不是跟API HOOK差不多呀
雪    币: 215
活跃值: 活跃值 (15)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
myqingniao 活跃值 2008-4-24 22:57
12
0
这个女的真的很厉害啊!

牛一个
雪    币: 214
活跃值: 活跃值 (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
海浪轻风 活跃值 1 2008-4-25 09:03
13
0
支持牛人!!
雪    币: 892
活跃值: 活跃值 (74)
能力值: ( LV9,RANK:570 )
在线值:
发帖
回帖
粉丝
mickeylan 活跃值 14 2008-5-27 21:17
14
0
你怎么知道别人是女的?顶一个
雪    币: 222
活跃值: 活跃值 (13)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
dalong 活跃值 2008-7-29 11:29
15
0
初学驱动,看不大明白,LZ发布的SSDT Hook For Delphi 这个程序和楼主发布的Pure Delphi Code恢复驱动哪个好用,容易上手??
好像卡巴已经杀了SSDT Hook For Delphi 这个驱动了吧,我安装后驱动没能恢复呀!
雪    币: 103
活跃值: 活跃值 (12)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
xushanfeng 活跃值 2009-6-7 10:27
16
0
谢谢了~下载来看下·
雪    币: 214
活跃值: 活跃值 (18)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
松松 活跃值 1 2009-6-10 22:18
17
0
标记一下...需要是看
雪    币: 112
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
不死小尧 活跃值 2009-6-30 20:01
18
0
顶顶顶顶顶顶顶
雪    币: 244
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
yuxuegong 活跃值 2009-9-1 01:20
19
0
终于找到delphi了
雪    币: 276
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
loveqqc 活跃值 2009-9-1 08:52
20
0
KeServiceDescriptorTable
这个可以直接得到地址,或者用类似于win32的GetProcAddress(handle, name)的方法得到。
雪    币: 188
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
hystat 活跃值 2009-12-22 12:40
21
0
项!绝世好贴!
游客
登录 | 注册 方可回帖
返回