问题描述:怎么hook windows的系统API?咨询范围:实现方法描述,实现代码。
给分标准:
回贴内容清晰明确,深入浅出者回赠高分。
回贴全面深入,不掺水分的,可以考虑标准分值(100分)相送。
回贴能够对理解问题有较大帮助者另有50分相赠。
贴面上的分数不是给分上限,按以上标准给分,达到标准的有一个给一个。
欢迎对这问题有兴趣的朋友一起来UP,共同提高。
欢迎大家对问题提出自已的见解和想法(不给分)。
谢绝回贴捞分者。
给分标准:
回贴内容清晰明确,深入浅出者回赠高分。
回贴全面深入,不掺水分的,可以考虑标准分值(100分)相送。
回贴能够对理解问题有较大帮助者另有50分相赠。
贴面上的分数不是给分上限,按以上标准给分,达到标准的有一个给一个。
欢迎对这问题有兴趣的朋友一起来UP,共同提高。
欢迎大家对问题提出自已的见解和想法(不给分)。
谢绝回贴捞分者。
这样的资料多的是,只要把C的换成Delphi就行了。如果直接用C,换都不要换了。
------------------------------------------------TImportCode = packed record
JumpInstruction : Word; // 应该是$25FF,JUMP指令
AddressOfPointerToFunction: PPointer;// 真正的开始地址
end;
PImportCode = ^TImportCode;------------------------------------------------2、用下面的函数返回函数的真正地址
------------------------------------------------
function TrueFunctionAddress(func: Pointer): Pointer;
var
Code: PImportCode;
begin
Result:= func;
if func = nil then exit;
try
Code := func;
if (Code.JumpInstruction = $25FF) then begin
Result := Code.AddressOfPointerToFunction^;
end;
except
Result := nil;
end;
end;------------------------------------------------3、替换函数:
Procedure PermuteFunction(OldFunc:PPOinter; NewFunc:Pointer);
var
written: DWORD;
begin
WriteProcessMemory(GetCurrentProcess, OldFunc, @NewFunc, 4, written);
end;------------------------------------------------4、第一个程序
------------------------------------------------
unit mess;interface
uses
Windows, Messages, SysUtils, Classes, APIHook;procedure API_Hookup;
procedure Un_API_Hook;var
FuncMessageboxA, FuncMessageboxW: PImportCode;implementationtype
TMessageA = function(hwn: hwnd; lptext: pchar; lpcapion: pchar; utype: cardinal): integer; stdcall;
TMessageW = function(hwn: hwnd; lptext: pwidechar; lpcapion: pwidechar; utype: cardinal): integer; stdcall;var
OldMessageBoxA: TMessageA;
OldMessageBoxW: TMessageW;
function MyBoxA(hwn:hwnd;lptext:pchar;lpcapion:pchar;utype:cardinal): integer; stdcall;
begin
result := OldMessageBoxA(hwn, 'Succes Hook A !', lpcapion, utype);
end;function MyBoxw(hwn:hwnd;lptext:pwidechar;lpcapion:pwidechar;utype:cardinal): integer; stdcall;
begin
result := OldMessageBoxW(hwn, '成功挂上W!', lpcapion, utype);
end;procedure API_Hookup;
begin
if @OldMessageBoxA = nil then
@OldMessageBoxA := TrueFunctionAddress(@messageboxA);
if @OldMessageBoxW = nil then
@OldMessageBoxW := TrueFunctionAddress(@messageboxW); PermuteFunction(FuncMessageboxA.AddressOfPointerToFunction, @MyBoxA);
PermuteFunction(FuncMessageboxW.AddressOfPointerToFunction, @MyBoxW);
end;procedure Un_API_hook;
begin
If @OldMessageBoxA <> nil then begin
PermuteFunction(FuncMessageboxA.AddressOfPointerToFunction, @OldMessageboxA);
PermuteFunction(FuncMessageboxW.AddressOfPointerToFunction, @OldMessageboxW);
end;
end;initialization
FuncMessageboxA := @MessageboxA;
FuncMessageboxW := @MessageboxW;
end.------------------------------------------------5、在主窗体上添加三个按钮,添加Onclick代码,如下:
------------------------------------------------
procedure TForm1.Button1Click( Sender : TObject);
begin
API_HookUp;
end;procedure TForm1.Button3Click( Sender : TObject);
begin
Un_API_Hook;
end;procedure TForm1.Button2Click( Sender : TObject);
begin
MessageBoxA(Form1.Handle,'NO HOOK UP A','MessageBoxA',MB_OK);
MessageBoxW(Form1.Handle,'NO HOOK UP W','MessageBoxW',MB_OK);
end;------------------------------------------------6、如果现在新建一个Application TestTry,在Form上添加一个按钮,
其Onclick事件如下:
------------------------------------------------
procedure TForm1.Button1Click(Sender: TObject);
begin
MessageBoxA(Form1.Handle,'NO HOOK UP A','MessageBoxA',MB_OK);
MessageBoxW(Form1.Handle,'NO HOOK UP W','MessageBoxW',MB_OK);
MessageBox (Form1.Handle,'NO HOOK UP BOX','MessageBox',MB_OK);
end;___________________________________________________________
7、第二个程序
___________________________________________________________uses
Windows,
SysUtils,
Classes,
APIHook in 'APIHook.pas',
mess in 'mess.pas';{$R *.RES}function GetMsgProc(code: integer; removal: integer; msg: Pointer): Integer; stdcall;
begin
Result := 0;
end;Var HookHandle: THandle;procedure StartHook; stdcall;
begin
HookHandle := SetWindowsHookEx(WH_GETMESSAGE, @GetMsgProc, HInstance, 0);
end;procedure StopHook; stdcall;
begin
UnhookWindowsHookEx( HookHandle );
end;exports StartHook, StopHook;begin
API_Hookup; //加载时挂上
end.-----------------------------------------------------------
为了卸载时能解除钩子,在Unit MESS单元最后加上一句:
-----------------------------------------------------------
finalization
Un_API_hook;-----------------------------------------------------------当然,别忘了对MESS做相应修改。编译好后别忘了存盘。新建Application TRY2程序,主Form的单元名称不妨叫TRYUnit2,在Form1上添加三个Button,并声明:
-----------------------------------------------------------
procedure StartHook; stdcall; external 'TRYDLL.DLL';
procedure StopHook; stdcall; external 'TRYDLL.DLL';-----------------------------------------------------------
三个Button的OnClick代码如下:
-----------------------------------------------------------
procedure TForm1.Button1Click(Sender: TObject);
begin
StartHook;
end;procedure TForm1.Button2Click(Sender: TObject);
begin
MessageBoxA(Form1.Handle,'NO HOOK UP A','MessageBoxA',MB_OK);
MessageBoxW(Form1.Handle,'NO HOOK UP W','MessageBoxW',MB_OK);
MessageBox (Form1.Handle,'NO HOOK UP BOX','MessageBox',MB_OK);
end;procedure TForm1.Button3Click(Sender: TObject);
begin
StopHook;
end;-----------------------------------------------------------
(* PermuteFunction功能 :用 NewFunc替代 OldFunc *)
(* Windows Me + Delphi 5.0 *)
(* ------------------------------------------ *)
unit APIHook;
interface
uses
Windows, Classes ;
type
PImage_Import_Entry = ^Image_Import_Entry;
Image_Import_Entry = record
Characteristics : DWORD;
TimeDateStamp : DWORD;
MajorVersion : Word;
MinorVersion : Word;
Name : DWORD;
LookupTable : DWORD;
end;Function TrueFunctionAddress(Code: Pointer): Pointer;
Function PermuteFunction(OldFunc, NewFunc: Pointer): Integer;
implementation
type
TImportCode = packed record
JumpInstruction: Word;
AddressOfPointerToFunction: ^Pointer;
end;
PImportCode = ^TImportCode;
function TrueFunctionAddress(Code: Pointer): Pointer;
var func: PImportCode;
begin
Result := Code;
if Code = nil then exit;
try
func := code;
if (func.JumpInstruction=$25FF) then begin
Result := func.AddressOfPointerToFunction^;
end;
except
Result := nil;
end;
end;Function PermuteFunction(OldFunc, NewFunc: Pointer): Integer;
var IsDone: TList;
Function PermuteAddrInModule(hModule: THandle; OldFunc, NewFunc: Pointer): Integer;
var
Dos : PImageDosHeader;
NT : PImageNTHeaders;
ImportDesc : PImage_Import_Entry;
RVA : DWORD;
Func : ^Pointer;
DLL : String;
f : Pointer;
written : DWORD;
begin
Result := 0;
Dos := Pointer(hModule);
if IsDone.IndexOf(Dos) >= 0 then exit;
IsDone.Add(Dos);
OldFunc := TrueFunctionAddress(OldFunc);
if IsBadReadPtr(Dos,SizeOf(TImageDosHeader)) then exit;
if Dos.e_magic <> IMAGE_DOS_SIGNATURE then exit;
NT := Pointer(Integer(Dos) + dos._lfanew);
RVA := NT^.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress; if RVA = 0 then exit;
ImportDesc := pointer(integer(Dos)+RVA);
While(ImportDesc^.Name<>0) do
begin
DLL := PChar(Integer(Dos) + ImportDesc^.Name);
PermuteAddrInModule(GetModuleHandle(PChar(DLL)),OldFunc,NewFunc);
Func := Pointer(Integer(DOS) + ImportDesc.LookupTable);
While Func^ <> nil do
begin
f := TrueFunctionAddress(Func^);
if f = OldFunc then
begin
WriteProcessMemory(GetCurrentProcess,Func,@NewFunc,4,written);
If Written > 0 then Inc(Result);
end;
Inc(Func);
end;
Inc(ImportDesc);
end;
end;begin
IsDone := TList.Create;
try
Result := PermuteAddrInModule(GetModuleHandle(nil),OldFunc,NewFunc);
finally
IsDone.Free;
end;
end;
end.
大家都是互相关心并解决问题的/无论说的对不对都是对你的关心/下次不要写的那么苛刻/
上面的程序我记不得是怎么得到了/发出来大家学习/在这里谢谢著者/
也不能HOOK到用LoadLibrary动态调用的API函数...
去FAQ区看了LoadLibrary都可以有办法解决的!