gpt4 book ai didi

delphi - 为什么 Detours lib 不适用于虚拟方法?

转载 作者:行者123 更新时间:2023-12-03 00:21:51 24 4
gpt4 key购买 nike

我正在尝试拦截系统上每个对象的构造/销毁。为此,我使用 Detours Lib创建运行时补丁。它似乎以某种方式工作 FastCode方法确实如此。我认为它应该有相同的限制(无法修补操作码小于 5 个字节的方法)。但我选择这个库的原因是因为它创建了一个指向 Hook 方法的指针,我可以使用这个指针来调用它。

因此,为了进行修补,我尝试使用 TObject.NewInstanceTObject.FreeInstance

TObject.NewInstance 没问题,但是当我尝试对 TObject.FreeInstance、TObject.Free、TObject.BeforeDestruction 执行相同操作时(在这种情况下,我认为这是因为我上面描述的限制),我可以访问违规。

这里是一个代码示例:

var
TrampolineGetMemory: function: TObject;
TrampolineFreeInstance: procedure = nil;

implementation

type
TObjectHack = class(TObject)
function NNewInstanceTrace: TObject;
procedure NFreeInstance;
end;

procedure TObjectHack.NFreeInstance;
begin
TrampolineFreeInstance; {ERROR: apparently the jmp does not go to a valid addr}
end;

function TObjectHack.NNewInstanceTrace: TObject;
begin
Result := TrampolineGetMemory; {everything ok here}
end;

initialization
@TrampolineGetMemory := InterceptCreate(@TObject.NewInstance, @TObjectHack.NNewInstanceTrace);
@TrampolineFreeInstance := InterceptCreate(@TObject.FreeInstance, @TObjectHack.NFreeInstance);

finalization
InterceptRemove(@TrampolineGetMemory);
InterceptRemove(@TrampolineFreeInstance);

有人能看出我做错了什么吗?

最佳答案

FreeInstance 是一个实例方法而不是一个简单的过程。更重要的是,它是一个虚拟方法,而绕过虚拟方法通常会涉及到vtable修改,据我了解。简而言之,尝试 Hook FreeInstance 是检测实例销毁的错误方法。

相反,请绕道使用System._ClassDestroyTObject.CleanupInstance。前者的一个例子:

{$APPTYPE CONSOLE}

uses
System.SysUtils,
DDetours;

var
TrampolineClassDestroy: procedure(const Instance: TObject);

procedure DetouredClassDestroy(const Instance: TObject);
begin
// this is called from inside InterceptCreate, hence the test for
// TrampolineClassDestroy being assigned
if Assigned(TrampolineClassDestroy) then begin
TrampolineClassDestroy(Instance);
Writeln(Instance.ClassName, ' detour installed');
end else begin
Writeln(Instance.ClassName, ' detour not yet installed');
end;
end;

function System_ClassDestroy: Pointer;
asm
MOV EAX, offset System.@ClassDestroy
end;

procedure Main;
begin
TrampolineClassDestroy := InterceptCreate(System_ClassDestroy, @DetouredClassDestroy);
TObject.Create.Free;
end;

begin
try
Main;
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
end.

输出

TThreadsIDList detour not yet installedTIntercept detour not yet installedTObject detour installedTDictionary detour installedTObject detour installed@TList`1.Pack$23$ActRec detour installedTMoveArrayManager detour installedTList detour installedTRegGroup detour installedTMoveArrayManager detour installedTList detour installedTObject detour installedTThreadList detour installedTMoveArrayManager detour installedTList detour installedTObject detour installedTThreadList detour installedTMoveArrayManager detour installedTObjectList detour installedTRegGroups detour installedTOrdinalIStringComparer detour installedTThreadLocalCounter detour installedTMultiReadExclusiveWriteSynchronizer detour installedTComponent.Create@$929$ActRec detour installedTDelegatedComparer detour installedTObject detour installedTObject detour installedTObject detour installedEInvalidPointer detour installed

关于delphi - 为什么 Detours lib 不适用于虚拟方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29608243/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com