现在的位置: 首页 > 综合 > 正文

Ring0 inline hook For Delphi.

2013年08月08日 ⁄ 综合 ⁄ 共 7007字 ⁄ 字号 评论关闭
内嵌钩子呀内嵌钩子呀...
一般两种方法...
[1]jmp
0.获取一个足够的长度...Copy原来的数据保存到一个地方
1.jmp 长跳转到HookProc部分
2.处理完毕后跳转到...会原来抽取的代码...
3.执行完毕后再jmp回到原有指令
[2]返回地址...push xxx+ret
[3]这个是为了bypass某些检测工具---小跳一下...然后大跳一下(抱歉不是CS)
[4]其他跳转法...你喜欢玩EPO吗?呵呵

这里用第二种方法---抱歉我不想别人说我抄袭Ms-Rem的代码...

Copy code

{
  Hook Api Library 0.2 [Ring0] By Anskya
  Email:Anskya@Gmail.com
  ring3 inline hook For Api

Thank:
  前29A高手也一直都是我的偶像...z0mbie大牛...这里膜拜一下
  使用的LDE32引擎是翻译他老人家的...C->Delphi...

说明:
  1.利用堆栈跳转
  没有使用传统的jmp xxxx 长跳转,使用容易理解的push xxxx+ret
  仔细看代码容易理解...封装完好.

  2.内存补丁结构:
  补丁1:|push xxx--钩子处理过程|ret|
  补丁2:|保存原始补丁地址|保存原始地址代码长度|原始地址的代码|push xxxxxx|ret|

更新说明:
  0.2:
    支持Ring0 Inline Hook
  0.1:
    Ring3 Inline Hook
}
unit HookApiLib;

interface

{$DEFINE Ring0}

uses
  LDE32,
{$IFDEF Ring0}
  ntddk,
  macros
{$ELSE}
  Windows
{$ENDIF}
  ;

function HookCode(OldProc, NewProc: Pointer): Pointer;
function UnHookCode(TargetProc: Pointer): Boolean;

implementation

type
  LPfar_jmp = ^_far_jmp;
  _far_jmp = packed record
    PushOpCode: BYTE;
    PushArg: Pointer;
    RetOpCode: BYTE;
  end;
  Tfar_jmp = _far_jmp;

function HookCode(OldProc, NewProc: Pointer): Pointer;
var
  lpFuncProc, lpInlineProc: Pointer;
  InlineLen, OpcodeLen: ULONG;
  stfar_jmp_hook: Tfar_jmp;
{$IFNDEF Ring0}
  OldProtect: ULONG;
{$ENDIF}
begin
  Result := nil;
  if ((OldProc = nil) or (NewProc = nil)) then Exit;

  InlineLen := 0;
  lpFuncProc := OldProc;

  while (InlineLen < SizeOf(Tfar_jmp)) do
  begin
    GetInstLenght(lpFuncProc, @OpcodeLen);
    lpFuncProc := Pointer(ULONG(lpFuncProc) + OpcodeLen);
    InlineLen := InlineLen + OpcodeLen;
  end;

  stfar_jmp_hook.PushOpCode := $68;
  stfar_jmp_hook.PushArg := NewProc;
  stfar_jmp_hook.RetOpCode := $C3;

{$IFDEF Ring0}
  lpInlineProc := ExAllocatePoolWithTag(NonPagedPool, 8 + InlineLen  + SizeOf(Tfar_jmp), PoolWithTag);
{$ELSE}
  lpInlineProc := Pointer(GlobalAlloc(GMEM_FIXED, SizeOf(Pointer) + SizeOf(ULONG) + InlineLen  + SizeOf(Tfar_jmp)));
{$ENDIF}

  if (lpInlineProc = nil) then Exit;
 
  PPointer(lpInlineProc)^ := OldProc;
  Inc(PBYTE(lpInlineProc), SizeOf(Pointer));

  PULONG(lpInlineProc)^ := InlineLen;
  Inc(PBYTE(lpInlineProc), SizeOf(ULONG));

{$IFDEF Ring0}
  memcpy(lpInlineProc, OldProc, InlineLen);
{$ELSE}
  CopyMemory(lpInlineProc, OldProc, InlineLen);
{$ENDIF}
  Inc(PBYTE(lpInlineProc), InlineLen);
  //  改写跳转代码
  with LPfar_jmp(lpInlineProc)^ do
  begin
    PushOpCode := $68;
    PushArg := Pointer(ULONG(OldProc) + InlineLen);
    RetOpCode := $C3;
  end;

{$IFDEF Ring0}
  //  开始嵌入Hook
  if NT_SUCCESS(WriteReadOnlyMemoryMark(OldProc, @stfar_jmp_hook, SizeOf(Tfar_jmp))) then
  begin
    Result := Pointer(ULONG(lpInlineProc) - InlineLen);
  end else
  begin
    ExFreePoolWithTag(lpInlineProc, PoolWithTag);
    Result := nil;
  end; 
{$ELSE}
  //  使内存可写
  VirtualProtect(OldProc, SizeOf(Tfar_jmp), PAGE_EXECUTE_READWRITE, OldProtect);
  //  写入跳转代码
  CopyMemory(OldProc, @stfar_jmp_hook, SizeOf(Tfar_jmp));
  Result := Pointer(ULONG(lpInlineProc) - InlineLen);
  //  写回原属性
  VirtualProtect(OldProc, SizeOf(Tfar_jmp), OldProtect, OldProtect);
{$ENDIF}
end;

function UnHookCode(TargetProc: Pointer): Boolean;
var
  lpFuncProc, lpInlineProc: Pointer;
  InlineLen: ULONG;
{$IFNDEF Ring0}
  OldProtect: ULONG;
{$ENDIF}
begin
  Result := False;
  if (TargetProc = nil) then Exit;
  lpInlineProc := TargetProc;
  Dec(PBYTE(lpInlineProc), SizeOf(Pointer) + SizeOf(ULONG));

  lpFuncProc := PPointer(lpInlineProc)^;
  Inc(PBYTE(lpInlineProc), SizeOf(Pointer));

  InlineLen := PULONG(lpInlineProc)^;
  Inc(PBYTE(lpInlineProc), SizeOf(ULONG));

{$IFDEF Ring0}
  //  开始解除Hook
  if NT_SUCCESS(WriteReadOnlyMemoryMark(lpFuncProc, TargetProc, InlineLen)) then
  begin
    Dec(PBYTE(lpInlineProc), SizeOf(Pointer) + SizeOf(ULONG));
    ExFreePoolWithTag(lpInlineProc, PoolWithTag);
    Result := True;
  end; 
{$ELSE}
  //  使内存可写
  VirtualProtect(lpFuncProc, InlineLen, PAGE_EXECUTE_READWRITE, OldProtect);
  //  写回原有数据
  CopyMemory(lpFuncProc, TargetProc, InlineLen);
  Dec(PBYTE(lpInlineProc), SizeOf(Pointer) + SizeOf(ULONG));

  GlobalFree(ULONG(lpInlineProc));
  Result := True;
  //  写回原属性
  VirtualProtect(lpFuncProc, InlineLen, OldProtect, OldProtect);
{$ENDIF}
end;

end.

下面的Hook情况就完全和...Ring3下一模一样了。。。

Copy code

{
  NtOpenProcess[Inline Hook] By Anskya
  Email: Anskya[at]Gmail.com
}
unit Driver;

interface

uses
  Windows, macros, ntddk, HookApiLib, LDE32;

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

implementation

type
  LPfar_jmp = ^_far_jmp;
  _far_jmp = packed record
    PushOpCode: BYTE;
    PushArg: Pointer;
    RetOpCode: BYTE;
  end;
  Tfar_jmp = _far_jmp;

type
  TZwOpenProcess = function(ProcessHandle:PHandle; DesiredAccess:TAccessMask; ObjectAttributes:PObjectAttributes; ClientId:PClientId): NTSTATUS; stdcall;

var
  HookActive: Boolean;
  ZwOpenProcessNextHook: TZwOpenProcess;

//  钩子过程
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
  UnHookCode(@ZwOpenProcessNextHook);
  DbgPrint('DriverUnload(-)');
end;

//  驱动入口点
function _DriverEntry(DriverObject: PDriverObject; RegistryPath: PUnicodeString): NTSTATUS; stdcall;
var
  lpFuncProc: Pointer;
  lpInlineProc: Pointer;
  InlineLen: ULONG;
begin
  DriverObject^.DriverUnload := @DriverUnload;
  Result := STATUS_SUCCESS;
  DbgPrint('DriverEntry(-):0x%.8X', Result);

  HookActive := False;

  if (Not HookActive) then
  begin
    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);

    lpFuncProc := PPointer(SystemServiceOrd($7A))^;
    DbgPrint('ZwOpenProcess New Address: 0x%.8X', lpFuncProc);

    lpFuncProc := PPointer(SystemServiceName(GetImportFunAddr(@ZwOpenProcess)))^;
    DbgPrint('ZwOpenProcess New Address: 0x%.8X', lpFuncProc);

    @ZwOpenProcessNextHook := HookCode(lpFuncProc, @ZwOpenProcessHookProc);

    lpInlineProc := @ZwOpenProcessNextHook;
    Dec(PBYTE(lpInlineProc), SizeOf(Pointer) + SizeOf(ULONG));

    lpFuncProc := PPointer(lpInlineProc)^;
    DbgPrint('OldProc : 0x%.8X', lpFuncProc);
    Inc(PBYTE(lpInlineProc), SizeOf(Pointer));

    InlineLen := PULONG(lpInlineProc)^;
    DbgPrint('OldProc Inline Code Len : %d', InlineLen);
    Inc(PBYTE(lpInlineProc), SizeOf(ULONG));

    DbgPrint('ZwOpenProcess Target Address: 0x%.8X', @ZwOpenProcessNextHook);
  end else
  begin
    DbgPrint('ZwOpenProcess Hooked!!! By Anskya');
  end;
end;

end.

这么写代码纯属娱乐好孩子不好学我哦...非程序员的代码写的就是难看...大家多担待...
完全源代码见附件

Copy code

{
  Hook Api Library 0.2 [Ring0] By Anskya
  Email:Anskya@Gmail.com
  ring3 inline hook For Api

Thank:
  前29A高手也一直都是我的偶像...z0mbie大牛...这里膜拜一下
  使用的LDE32引擎是翻译他老人家的...C->Delphi...

说明:
  1.利用堆栈跳转
  没有使用传统的jmp xxxx 长跳转,使用容易理解的push xxxx+ret
  仔细看代码容易理解...封装完好.

  2.内存补丁结构:
  补丁1:|push xxx--钩子处理过程|ret|
  补丁2:|保存原始补丁地址|保存原始地址代码长度|原始地址的代码|push xxxxxx|ret|

更新说明:
  0.2:
    支持Ring0 Inline Hook
  0.1:
    Ring3 Inline Hook
}

Copy code

{
  LDE32.pas: Z0MBiE DISASM ENGINE[LDE32]
  LDE32 Delphi Coded By Anskya
  Email: [email]Anskya@Gmail.com[/email]

更新说明:
  procedure GetInstLenght(myiptr0: Pointer; osizeptr: PULONG);
  function GetProcLength(myiptr0: Pointer): ULONG;

0.2:
  增加 GetProcLength函数.用于获取一个函数过程的长度.

0.1:
  翻译

  Thank: z0mbie
}

抱歉!评论已关闭.