关于全局API Hook的一个问题,请大家帮忙。

kook 2006-12-31 03:08:32
以下是我的代码,并不算很长,应该也是写得很清楚的了。代码后面有文字说明

以下是DLL的代码
library dll;

uses
SysUtils,
Windows,
Classes,
Dialogs,
APIHook in 'APIHook.pas';

var
Hook:HHOOK;

function GetMsgProc(nCode:Integer;wParam:wParam;lParam:lParam):LRESULT;stdcall;
begin
Result := 0;
end;

procedure SetHook;
begin
Hook := SetWindowsHookEx(WH_GETMESSAGE,@GetMsgProc,hInstance,0);
end;

procedure RemoveHook;
begin
UnHookWindowsHookEx(Hook);
end;

exports
SetHook, RemoveHook;

{$R *.res}

begin
APIHook_Up;
end.




以下是APIHook单元的代码
unit APIHook;

interface

uses
Windows, Messages, Classes, SysUtils, Dialogs;

type
PImage_Import_Entry = ^Image_Import_Entry;
Image_Import_Entry = record
Characteristics: DWORD;
TimeDateStamp: DWORD;
MajorVersion: Word;
MinorVersion: Word;
Name: DWORD;
LookupTable: DWORD;
end;

TImportCode = packed record
JumpInstruction: Word;
AddressOfPointerToFunction: ^Pointer;
end;
PImportCode = ^TImportCode;

//TSetFocus = function(hWnd: HWND): HWND; stdcall;

TDeleteFileW = function(lpFileName: PWideChar): BOOL; stdcall;
TDeleteFileA = function(lpFileName: PAnsiChar): BOOL; stdcall;
TDeleteFile = function(lpFileName: PChar): BOOL; stdcall;

function LocateFunctionAddress(Code: Pointer): Pointer;stdcall;
function RepointFunction(OldFunc, NewFunc: Pointer): Integer;stdcall;
procedure APIHook_Up;stdcall;
procedure APIHook_Off;stdcall;

var
OldDeleteFileW:TDeleteFileW;
OldDeleteFileA:TDeleteFileA;
OldDeleteFile:TDeleteFile;
FuncDeleteFileW: PImportCode;
FuncDeleteFileA: PImportCode;
FuncDeleteFile: PImportCode;
implementation
////////////////////////////////////////////////////////////////////////

function MyDeleteFileW(lpFileName: PWideChar): BOOL; stdcall;
begin
MessageBox(0,'qqq','qqq',mb_ok);
Result:= true;
end;

function MyDeleteFileA(lpFileName: PAnsiChar): BOOL; stdcall;
begin
MessageBox(0,'qqq','qqq',mb_ok);
Result:= true;
end;

function MyDeleteFile(lpFileName: PChar): BOOL; stdcall;
begin
MessageBox(0,'qqq','qqq',mb_ok);
Result:= true;
end;

////////////////////////////////////////////////////////////////////////

function LocateFunctionAddress(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 RepointFunction(OldFunc, NewFunc: Pointer): Integer;
var
IsDone: TList;
function RepointAddrInModule(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 := LocateFunctionAddress(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);
RepointAddrInModule(GetModuleHandle(PChar(DLL)), OldFunc, NewFunc);
Func := Pointer(Integer(DOS) + ImportDesc.LookupTable);
while Func^ <> nil do
begin
f := LocateFunctionAddress(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 := RepointAddrInModule(GetModuleHandle(nil), OldFunc, NewFunc);
finally
IsDone.Free;
end;
end;

Procedure PermuteFunction(OldFunc:Pointer; NewFunc:Pointer);
var
written: DWORD;
begin
WriteProcessMemory(GetCurrentProcess,OldFunc,@NewFunc,4,written);
end;


procedure APIHook_Up;
begin

if @OldDeleteFileW = nil then
@OldDeleteFileW := LocateFunctionAddress(@DeleteFileW);

if @OldDeleteFileA = nil then
@OldDeleteFileA := LocateFunctionAddress(@DeleteFileA);

if @OldDeleteFile = nil then
@OldDeleteFile := LocateFunctionAddress(@DeleteFile);

PermuteFunction(funcDeleteFileW.AddressOfPointerToFunction, @MyDeleteFileW);
PermuteFunction(funcDeleteFileA.AddressOfPointerToFunction, @MyDeleteFileA);
PermuteFunction(funcDeleteFile.AddressOfPointerToFunction, @MyDeleteFile);

end;

procedure APIHook_Off;
begin
If @OldDeleteFileW <> nil then
begin
PermuteFunction(funcDeleteFileW.AddressOfPointerToFunction, @OldDeleteFileW);
end;

If @OldDeleteFileA <> nil then
begin
PermuteFunction(funcDeleteFileA.AddressOfPointerToFunction, @OldDeleteFileA);
end;

If @OldDeleteFile <> nil then
begin
PermuteFunction(funcDeleteFile.AddressOfPointerToFunction, @OldDeleteFile);
end;

end;

initialization

FuncDeleteFile := @DeleteFile;
FuncDeleteFileA := @DeleteFileA;
FuncDeleteFileW := @DeleteFileW;

finalization

APIHook_Off;

end.


本来我用新函数替换旧函数的时候调用的是RepointFunction函数
不知道为什么总是提示内存读取错误的信息。后来我用PermuteFunction做转换,发现对全局进程不管用。
我是这么操作的:
首先把APIHook这个单元放到我自己的一个程序中,然后再我自己的程序中调用DeleteFile函数来删除一个文件,结果是成功的。但是这并不是全局钩子,现在我要做全局钩子的话,把上面的代码放入DLL中。启动钩子后,我直接在桌面上删除一个文件,居然一点反映都没有,这到底是怎么回事啊,请问各位大哥我的代码到底哪里出了问题。或者哪里还没有考虑到的东西。

如果有可能的话,给一个DeleteFile的全局钩子的详细代码的话更好,小弟不胜感激。
...全文
187 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
wlp555ren 2007-01-09
  • 打赏
  • 举报
回复
在全局的Dll里不要定义过多的变量,因为当运行的时候它会加载一份到每个触发钩子的进程里,所以,你再认真的把代码改一下,不是很难,我现在在公司,不能给你源代码。。
ly_liuyang 2007-01-04
  • 打赏
  • 举报
回复
Explorer用的是SHFileOperation哦~不是DeleteFile~
而且全局Hook不是这么简单的

1,183

社区成员

发帖
与我相关
我的任务
社区描述
Delphi Windows SDK/API
社区管理员
  • Windows SDK/API社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧