在 Delphi 中挂钩 DLL 函数

发布于 2024-10-22 06:07:06 字数 338 浏览 5 评论 0原文

我有一个 coclass,它检查注册表以确定是否安装了应用程序,但它做得很差,并且找不到应用程序的较新版本。如果安装了竞争应用程序,它将尝试打开该应用程序。如果竞争的应用程序已被卸载,程序将崩溃。这个组件类是在 DLL 文件中定义的,我没有该库的源代码,所以我不能只是更改它。我一直在研究使用挂钩来用有效的函数替换该函数,但当我查看有关使用 SetWindowsHookEx 的 MSDN 文档时,它似乎很复杂。有人可以提供一个如何使用 SetWindowsHookEx 或其他挂接到 Windows 的方法的示例吗?

谢谢

编辑:我想指出,我接受了我所做的答案,因为它对我有用。在提出问题时我无法使用其他答案,但看起来也一样好。

I have a coclass which checks the registry to determine if an application is installed, but it does this poorly and doesn't find newer versions of the application. In cases where a competing application has been installed, it will try to open that one. If the competing application has been uninstalled, the program will crash. This coclass is defined in a DLL file I do not have the source code for the library, so I can't just change that. I have been looking into using hooking to replace the function with one that works, but it seems complicated when I look at the MSDN documentation on using SetWindowsHookEx. Can someone please provide an example of how to use SetWindowsHookEx or another method of hooking into Windows?

Thank You

EDIT: I would like to note that I accepted the answer I did because it worked for me. I could not use the other answer at the time the question was asked, but it looks like its just as good.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

我最亲爱的 2024-10-29 06:07:06

这是我自己的代码库中的一个简短示例,展示了最基本的挂钩技术:

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.

Here is a short example from my own codebase which shows the most basic hooking technique:

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.
无力看清 2024-10-29 06:07:06

对于一个非常好的绕行/挂钩单元(可以检查跳跃并应用新的偏移量!)我建议 KOLdetours.pas

我在许多项目中使用它,例如我的 AsmProfiler。

顺便说一句:通过绕行,你会得到一个“蹦床”,这样你也可以调用原始函数!

For a very good detouring/hooking unit (can check for jumps and apply new offset!) I would recommend KOLdetours.pas

I use this in many projects, for example my AsmProfiler.

Btw: with detouring you get a "trampoline" so you can call the original function too!

软甜啾 2024-10-29 06:07:06

我是 koldetours 的作者。该许可证对所有人免费:即,即使在商业程序中也可以随意使用。基本上它是真正的开源,不受任何许可的限制。正如其派生代码一样。它在标题中明确指出了这一点。

I am the auhtor of koldetours. The license is a free for all: i.e. use as you like EVEN IN COMMERCIAL PROGRAMS. Basically it is real open source, not crippled by any licensing. Just as the code from which it is derived. It clearly states so in the header.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文