gpt4 book ai didi

visual-studio-2010 - 通过注入(inject)的 Delphi dll 启用 __fastcall 来 Hook 在 MSVC++ 上制作的应用程序

转载 作者:行者123 更新时间:2023-12-03 15:56:58 25 4
gpt4 key购买 nike

我试图在使用 microsoft Visual Studio 2010 编译的应用程序中 Hook 一个函数,并从 delphi 2010 dll 启用 __fastcall,但我不熟练如何解决以下问题:

C++ 函数是:

     void __fastcall function(int arg1; char* arg2);

我正在尝试类似的事情(使用 uallHook):

    var FTextMessage : procedure(Modo: integer; Msg: pchar); register;
procedure onTextMessage(Modo: integer; Msg: pchar); register;
begin
ShowMessage(inttostr(Modo) + ' - ' + string(Msg));
FTextMessage(Modo, Msg);
end;
begin
HookCode(Ptr($574210), @onTextMessage, @FTextMessage);
end.

这会导致调试/崩溃。

所以,我发现:

"Microsoft or GCC[4] __fastcall[5] convention (aka __msfastcall) passes the first two arguments (evaluated left to right) that fit into ECX and EDX. Remaining arguments are pushed onto the stack from right to left."

Borland fastcall Evaluating arguments from left to right, it passes three arguments via EAX, EDX, ECX. Remaining arguments are pushed onto the stack, also left to right.[6] It is the default calling convention of the 32 bit compiler of Embarcadero Delphi, where >it is known as register.

摘自: http://en.wikipedia.org/wiki/X86_calling_conventions

这就是问题所在,borland fastcall 和 microsoft __fastcall 是不同的。

所以我想我需要在 Hook 函数中使用一段汇编代码来对齐寄存器或其他东西,但我还无法弄清楚这一点。

如有任何帮助,我们将不胜感激。

编辑1:大卫·赫弗南的答案部分有效。 (它只在显示消息之前有效)

     var FTextMessage : procedure(Modo: integer;Msg: PAnsiChar); register;

procedure onTextMessage(Modo: integer;Msg: PAnsiChar); register;
begin
ShowMessage(inttostr(Modo) + ' - ' + string(Msg));
asm
MOV ECX,Modo
MOV EDX,Msg
JMP FTextMessage
end; // I got a crash trying or without trying to restore the registers before executing the JMP FTextMessage
// FTextMessage(Modo,Msg); // < Also this method doesnt work either, if I call the Original function from here (without executing asm code above) i got a crash too. (this is what i was meaning with "to correct the registers")
end;

procedure onTextMessageWrapper(Modo: Integer;Msg: PAnsiChar); register;
asm
MOV EDX,ECX // < Moving ECX to EDX, I'm able to Access Modo and Msg correctly in onTextMessage procedure.
JMP onTextMessage
end;

begin
HookCode(Ptr($574210), @onTextMessageWrapper, @FTextMessage);
end.

最佳答案

C++ 函数正在 ECXEDX 中传递参数。因此,您只需将它们分别复制到 Delphi 所需的寄存器:EAXEDX 即可。由于第二个参数已经在正确的寄存器中,因此您所需要的就是:

procedure onTextMessage(Modo: Integer; Msg: PAnsiChar); register;
begin
...
end;

procedure onTextMessageWrapper(Modo: Integer; Msg: PAnsiChar); register;
asm
MOV EAX,ECX
JMP onTextMessage
end;

我在两个函数中完成了此操作,以便我可以编写一个纯 asm 函数来进行寄存器交换。我们想要纯 asm 以避免所有前导码。所以,onTextMessageWrapper 是你的钩子(Hook)函数。

另请注意,由于您使用的是 Unicode Delphi,因此您将希望 PAnsiCharchar* 匹配。

我所知道的有关调用约定的最佳引用是 Agner Fog 。你会在那里找到所有血淋淋的细节。重要的一点是,在 Windows x86 上,EAX、ECX 和 EDX 寄存器是 volatile 寄存器或暂存寄存器。这意味着被调用者可以修改这些寄存器而无需恢复它们。这就是为什么我修改了上面的EAX并且懒得把它放回去。

关于visual-studio-2010 - 通过注入(inject)的 Delphi dll 启用 __fastcall 来 Hook 在 MSVC++ 上制作的应用程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13703303/

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