当前位置:编程学习 > Delphi >>

Delphi实现SSDT Hook

关于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);
   Dbg

补充:综合编程 , 安全编程 ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,