2011-03-17 86 views
2

我有一个coclass检查注册表,以确定是否安装了应用程序,但它做得很差,并没有找到应用程序的较新版本。在安装了竞争应用程序的情况下,它将尝试打开该应用程序。如果竞争应用程序已被卸载,程序将崩溃。这个coclass是在DLL文件中定义的,我没有库的源代码,所以我不能只是改变它。我一直在寻找使用钩子来替换功能,但看起来很复杂,当我看到使用SetWindowsHookEx的MSDN文档。有人可以提供一个如何使用SetWindowsHookEx或另一种挂钩到Windows的方法的例子吗?挂钩在德尔福的DLL函数

谢谢

编辑:我想指出,我接受了我所做的,因为它的工作对我的答案。在问题提出时,我不能使用其他答案,但看起来它同样好。

回答

6

下面是我自己的代码库很短的例子显示了最基本的挂钩技术:

unit MethodHooker; 

interface 

implementation 

uses 
    SysUtils, Windows, Classes; 

procedure Patch(Address: Pointer; const NewCode; Size: Integer); 
var 
    NumberOfBytes: DWORD; 
begin 
    WriteProcessMemory(GetCurrentProcess, Address, @NewCode, Size, NumberOfBytes); 
end; 

type 
    PInstruction = ^TInstruction; 
    TInstruction = packed record 
    Opcode: Byte; 
    Offset: Integer; 
    end; 

procedure Redirect(OldAddress, NewAddress: Pointer); 
var 
    NewCode: TInstruction; 
begin 
    NewCode.Opcode := $E9;//jump relative 
    NewCode.Offset := Integer(NewAddress)-Integer(OldAddress)-SizeOf(NewCode); 
    Patch(OldAddress, NewCode, SizeOf(NewCode)); 
end; 

function GetCursorPos(var lpPoint: TPoint): BOOL; stdcall; 
(* The GetCursorPos API in user32 fails if it is passed a memory address >2GB which 
    breaks LARGEADDRESSAWARE apps. We counter this by calling GetCursorInfo instead 
    which does not suffer from the same problem. *) 
var 
    CursorInfo: TCursorInfo; 
begin 
    CursorInfo.cbSize := SizeOf(CursorInfo); 
    Result := GetCursorInfo(CursorInfo); 
    if Result then begin 
    lpPoint := CursorInfo.ptScreenPos; 
    end else begin 
    lpPoint := Point(0, 0); 
    end; 
end; 

initialization 
    if not ModuleIsPackage then begin 
    if not CheckWin32Version(6, 1) then begin 
     //this bug was fixed in Windows 7 
     Redirect(@Windows.GetCursorPos, @MethodHooker.GetCursorPos); 
    end; 

end. 
+1

非常漂亮。可以用于邪恶,或者是好的。但非常漂亮。 – 2011-03-17 19:13:34

+0

你从哪里得到NewCode.Opcode值? – mnuzzo 2011-03-17 19:14:07

+0

@mnuzzo Intel x86文档 – 2011-03-17 19:17:06

5

一个很好的迂回/挂钩单元(可以检查跳跃和应用新的偏移!)我会建议KOLdetours.pas

我在许多项目中使用了这个,例如我的AsmProfiler。

顺便说一句:随着迂回,你会得到一个“蹦床”,所以你可以称之为原始功能呢!

+0

+1这样的单位(我熟悉madCodeHook)提供的不仅仅是我的小例子。 – 2011-03-17 19:17:46

+0

尽管您的解决方案看起来很棒,但我无法使用开源软件。 – mnuzzo 2011-03-17 19:24:39

+0

@mnuzzo我不认为你是那个意思。也许你不能在MPL下使用代码。但madCodeHook受到商业许可,你应该可以使用它。 – 2011-03-17 19:38:10

3

我是koldetours的auhtor。许可证是免费的,即使用于商业程序即可。基本上它是真正的开源,并没有受到任何授权的束缚。就像它的派生代码一样。它在标题中清楚地表明了这一点。