API Aufruf mir Inline Assembler / Rücksprungaddresse ermitteln
-
Hallo!
Da ich jetzt schon mehere Stunden verzweifelt damit verbracht habe,
einen simplen API Aufruf mit Inline Assembler zu realisieren, setze
ich meine ganze Hoffnung in Euch. Mein Probleme:1. Frage
Ich benutze den BCB 6 und möchte GetForegroundWindow aufrufen und
den Rückgabewert (in EAX) in einer Variable speichern. Das ganze
geschieht innerhalb eines Hooks, was aber für meine Frage unerheblich
ist.HWND APIENTRY new_GetForegroundWindow( void ) { HWND RetVal = 0x12346789; // init __asm { call org_GetForegroundWindow; MOV RetVal, EAX; } return RetVal; }Das hooken klappt und lässt sich schön im Debugger verfolgen. Nur
der Rückgabewert (RetVal) wird nicht gesetzt (obwohl er definitiv
in EAX steht). Soweit ich im Debugger verfolgen konnte, wird der
Wert im Aufruf ( MOV RetVal, EAX ) nicht ans Offset von RetVak
im Speicher geschrieben, sondern etwas dahinter (ein paar bytes).Bei einem DWORD/HWND (wie oben im Code) sieht die Anweisung so
aus:0040137C PUSH EBX 0040137D PUSH ECX 0040137E MOV DWORD PTR SS:[ESP],12346789 <-- INIT, offset == 0x0012FF74 00401385 CALL DWORD PTR DS:[40E7C0] <-- CALL hooked, return value in EAX 0040138B MOV DWORD PTR SS:[EBP],EAX <-- 0x0012FF88 != 0x0012FF88 0040138E MOV EAX,DWORD PTR SS:[ESP] 00401391 POP EDX 00401392 POP EBX 00401393 RETNStatt an offset 0x0012FF74, wird an 0x0012FF88 gespeichert. Mir ist
nicht klar, wieso. Und egal wie ich es drehe und wende, nie funktioniert
es.2. Frage:
Neben dem Rückgabewert möchte ich auch ermitteln, woher der Call kam.
In VC++ gibt es dafür die Anweisung:extern "C" void * _ReturnAddress(void); #pragma intrinsic(_ReturnAddress) HWND APIENTRY new_GetForegroundWindow( void ) { DWORD RetAddr=(DWORD)_ReturnAddress(); }Der Scheiss BCB meldet mir aber unresolved external. Also vermutlich
MS spezifisch. Natürlich lässt sich das in __asm machen, allerdings
weiss ich nicht wie und angesicht derart merkwürdiger Probleme (siehe
oben) kann ich es auch nicht ausprobieren.Ideen?
-
Kleiner fehler: Statt
0040138B MOV DWORD PTR SS:[EBP],EAX <-- 0x0012FF88 != 0x0012FF88
muss es
0040138B MOV DWORD PTR SS:[EBP],EAX <-- 0x0012FF74 != 0x0012FF88
heissen
-
Ich bin zwar kein Assembler-Experte, aber sollte es nicht heißen:
mov [RetVal], eax;
-
Muss das denn sein
??? Asm für Api-Calls zu verwenden ist sowas von unnötig. Vielleicht solltest du alles noch ma überdenken. Im übrigen verbirgt sich hinter HWND ein Pointer auf struct HWND__. Also rechnet mit Zeigern und nicht mit Daten... 
mfg
-
Das klappt auch nicht, der Dreckscompiler macht anscheinend was er will.
Borland eben...Übrigens so geht es (aber das ist ABSOLUTER PFUSCH):
HWND APIENTRY new_GetForegroundWindow( void ) { HWND RetVal; __asm { mov RetVal, 0; call org_GetForegroundWindow; MOV DWORD PTR SS:[ESP],EAX } return RetVal; }Das sieht das in ASM so aus:
0040137C PUSH EBX 0040137D PUSH ECX 0040137E MOV DWORD PTR SS:[EBP],0 <--- @0x0012FF88 (Anw. muss drin sein, sonst siehe unten) 00401385 CALL DWORD PTR DS:[40E7C0] 0040138B MOV DWORD PTR SS:[ESP],EAX <--- HARDCORE @0x0012FF74 (the real offset of RetVal) 0040138F MOV EAX,DWORD PTR SS:[ESP] <--- ist auch Rückgabewert (ok) 00401392 POP EDX 00401393 POP EBX 00401394 RETNDas MOV retVal,0 muss drinbleiben, sonst vermurkst der Compiler alles,
dh. er optimiert die Anweisung komplett weg und nichts geht mehr:0040137C PUSH EBX 0040137D PUSH ESI 0040137E CALL DWORD PTR DS:[40E7C0] 00401384 MOV DWORD PTR SS:[ESP],EAX <--- @0x0012FF74 (ok) 00401388 MOV EAX,ESI <--- wtf kommt das her?! == return SCHROTT!! 0040138A POP ESI 0040138B POP EBX 0040138C RETNDas ist doch nur noch zum kotzen. Hätte mir doch den VC++ statt BCB kaufen sollen...
-
CanDL schrieb:
Muss das denn sein
??? Asm für Api-Calls zu verwenden ist sowas von unnötig. Vielleicht solltest du alles noch ma überdenken. Im übrigen verbirgt sich hinter HWND ein Pointer auf struct HWND__. Also rechnet mit Zeigern und nicht mit Daten... 
mfg
Und die Rücksprungadresse kriege ich mit 0815 API auch, was? Wenn Du wüsstest, wofür ich den Code einsetze, würdest Du sowas nicht schreiben.
-
jetzt hast du mich neugierig gemacht ! wofür willst du denn den code einsetzen ?
Weil ich denk auch dann besser nicht über asm zu machen (vor allem den api aufruf solltest du dem compiler allein überlassen).
und die rücksprungadresse wird ja normal glaub ich auf den stack gelegt und da musst du sie nur noch runterholen.MFG O-G