在delphi中调用例程调用

Rah*_*l W 18 delphi monkeypatching

我想修补一个例程调用,以便能够通过一些修改自己处理它.我正在写一个资源加载器.我想修补Delphi的LoadResourceModule和InitInheritedComponent例程.我已经在MadExcept.pas单元中检查了PatchAPI调用,但如果我可以将其用于我的项目,则无法弄明白.

我想要类似的东西

我的exe在运行时调用 - > LoadResourceModule - >跳转到 - > MyCustomResourceModule ...

任何关于此的指针都会非常有帮助.

Dav*_*nan 16

我使用以下代码:

procedure PatchCode(Address: Pointer; const NewCode; Size: Integer);
var
  OldProtect: DWORD;
begin
  if VirtualProtect(Address, Size, PAGE_EXECUTE_READWRITE, OldProtect) then 
  begin
    Move(NewCode, Address^, Size);
    FlushInstructionCache(GetCurrentProcess, Address, Size);
    VirtualProtect(Address, Size, OldProtect, @OldProtect);
  end;
end;

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

procedure RedirectProcedure(OldAddress, NewAddress: Pointer);
var
  NewCode: TInstruction;
begin
  NewCode.Opcode := $E9;//jump relative
  NewCode.Offset := NativeInt(NewAddress)-NativeInt(OldAddress)-SizeOf(NewCode);
  PatchCode(OldAddress, NewCode, SizeOf(NewCode));
end;
Run Code Online (Sandbox Code Playgroud)

您可以通过调用RedirectProcedure以下方法实现hook/patch/detour :

RedirectProcedure(@LoadResourceModule, @MyLoadResourceModule);
Run Code Online (Sandbox Code Playgroud)

这适用于32位代码.它也适用于64位代码,前提是旧函数和新函数都驻留在同一个可执行模块中.否则跳跃距离可能超过32位整数的范围.

如果有人可以提供一个适用于64位地址空间的替代方案,无论这两个地址有多远,我都会非常感兴趣.

  • 最好是*unpatch*重定向或确保在应用程序关闭时没有代码中断 - 可以进行重定向调用(例如,通过RTL或在重定向单元之前加载的其他单元),并跳转到一些未初始化的代码. (6认同)
  • 在x86或x64 CPU架构上不需要FlushInstructionCache,因为它们具有透明缓存,它实际上是无操作的.只是给那些和我一样有代码的人留言,并且想知道是否缺少FlushInstructionCache是​​一个bug.事实并非如此. (4认同)

Fr0*_*0sT 8

已经有一个Delphi绕道库.

Delphi Detours库是一个库,允许您挂钩delphi和windows API函数.它提供了一种插入和删除钩子的简便方法.

特征 :

  • 支持x86和x64架构.
  • 允许通过Trampoline函数调用原始函数.
  • 支持Multi Hook.
  • COM/Interfaces/win32api支持.
  • 支持COM vtable修补.
  • 完全线程安全的代码挂钩和取消挂钩.
  • 支持挂钩对象方法.
  • 支持Delphi 7/2005-2010/XE-XE7.
  • 支持Lazarus/FPC.
  • 支持64位地址.
  • 该库不使用任何外部库.
  • 库可以随时插入和删除钩子.
  • 该库包含InstDecode库,允许您解码asm指令(x86和x64).