一般两种方法...
[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 ApiThank:
前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 ApiThank:
前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
}