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  RETN
    

    Statt 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   RETN
    

    Das 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   RETN
    

    Das 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


Anmelden zum Antworten