修补 public 非虚拟方法

Patching a public non-virtual method

我需要为整个应用程序修补一个 public 方法,用我自己的方法替换它,但仍然能够从我的修补方法中调用原始方法。

我知道如何用我自己的方法替换方法。 How to change the implementation (detour) of an externally declared function

还有另一个例子:Make Disabled Menu and Toolbar Images look better?

但我不知道的是如何先调用原始文件。例如

// Store the original address of the method to patch
var OriginalMethodBackup: TXRedirCode;     

// this is the implementation of the new method
procedure MyNew_Method(Self: TObject; Index: Integer);
begin
  try
    // some code here
    call ORIGINAL public method here
  finally
    // some code here
  end;
end;

编辑: 我试过 Delphi Detours 库,但它无法在 D5 和 D7 下编译。有很多问题,例如指针运算、未知类型、class vars、未知编译器指令、未知 asm 指令等......代码应该被移植以支持 D5 和 D7(奇怪的是作者说它支持 D7 ).到目前为止,我已经完成了大部分移植工作,但仍然存在一些问题。无论如何,我不确定它在我完成后是否能正常工作。所以可能需要替代方案。

如果您想更改非虚拟方法,则需要修补该方法。

您可以使用 Delphi Detours library 修补例程:

type
  TMyMethod = procedure(Self: TObject; Index: Integer);

var
  OldMethod: TMyMethod;  //make sure to initialize to nil.

procedure MyNewMethod(Self: TObject; Index: Integer);
begin
  Assert(Assigned(OldMethod),'Error: MyMethod is not hooked');
  //If you need to call the OldMethod you can use the variable. 
  OldMethod(Self, Index);
  //Do additional stuff here
  ShowMessage('New stuff');
end;

procedure DoHook;
begin
  @OldMethod:= InterceptCreate(@MyOriginalMethod, @MyNewMethod);
end;

procedure RemoveHook;
begin
  if Assigned(OldMethod) then
  begin
    InterceptRemove(@OldMethod);
    OldMethod := nil;
  end;
end;

A link 到 DDetours is here 的 wiki。

在修补该方法时,您可以调用 OldMethod 来访问原始方法。

对我来说似乎很直接:

  • 恢复补丁
  • 调用方法
  • 再次打补丁

编辑: 正如其他人所指出的,这只是在单线程中使用的有效方法。