Delphi 2010 dll から __fastcall を有効にして、Microsoft Visual Studio 2010 でコンパイルされたアプリケーション内で関数をフックしようとしていますが、次の問題を回避する方法を理解するスキルがありません。
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 または GCC[4] __fastcall[5] 規則 (別名 __msfastcall) は、ECX および EDX に適合する最初の 2 つの引数 (左から右に評価) を渡します。残りの引数は右から左にスタックにプッシュされます。」
Borland fastcall 引数を左から右に評価し、EAX、EDX、ECX を介して 3 つの引数を渡します。残りの引数も左から右にスタックにプッシュされます。[6] これは、Embarcadero Delphi の 32 ビット コンパイラのデフォルトの呼び出し規約であり、レジスタとして知られています。
出典: http://en.wikipedia.org/wiki/X86_calling_conventions
これが問題です。borland fastcall と microsoft __fastcall は異なります。
そのため、フック関数内でアセンブリ コードを使用してレジスタなどを整列させる必要があると考えていますが、まだこれを理解することはできません。
どんな助けでも大歓迎です。
Edit1: David Heffernan Answer は部分的に機能します。(showmessage までしか機能しません)
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.