GDB und EIP Frage



  • Hallo,

    mal folgendes kleiner Programm :

    #include <stdio.h>
    
    void f(void)
    {
    	printf("f()\n");
    }
    
    int main(void)
    {
    	f();
    	return 0;
    }
    

    Ich debugge es nun :

    * setze einen Break auf 5, also bei printf("f()\n");
    * nun ein run
    * nun ein info reg

    (gdb) info reg
    eax 0x1 1
    ecx 0xbf81e770 -1082005648
    edx 0xbf81e790 -1082005616
    ebx 0xb7fbbff4 -1208238092
    esp 0xbf81e740 0xbf81e740
    ebp 0xbf81e748 0xbf81e748
    esi 0xb7feece0 -1208029984
    edi 0x0 0
    eip 0x804837a 0x804837a <f+6>

    Also, im eip steht 0x804837a, an die müsste er ja zurückspringen, die Adresse wurde ja per push vor dem Aufruf von f() auf den Stack gepusht ( also call ) und das ret holt sich nun die Adresse und die Fortführung geht dort weiter.

    Soweit richtig ! ( oder ? )

    Nun habe ich mir mittels disas main die Adressen angeschaut, die lauten :

    (gdb) disas main
    Dump of assembler code for function main:
    0x08048388 <main+0>: lea 0x4(%esp),%ecx
    0x0804838c <main+4>: and $0xfffffff0,%esp
    0x0804838f <main+7>: pushl 0xfffffffc(%ecx)
    0x08048392 <main+10>: push %ebp
    0x08048393 <main+11>: mov %esp,%ebp
    0x08048395 <main+13>: push %ecx
    0x08048396 <main+14>: sub $0x4,%esp
    0x08048399 <main+17>: call 0x8048374 <f>
    0x0804839e <main+22>: mov $0x0,%eax
    0x080483a3 <main+27>: add $0x4,%esp
    0x080483a6 <main+30>: pop %ecx
    0x080483a7 <main+31>: pop %ebp
    0x080483a8 <main+32>: lea 0xfffffffc(%ecx),%esp
    0x080483ab <main+35>: ret

    An dieser Stelle wird die Funktion f() aufgerufen

    0x08048399 <main+17>: call 0x8048374 <f>

    Nun meine Frage, die Adresse 0x804837a die in EIP steht, müsste doch in main vorkommen, tut sie aber nicht, wieso 😕



  • Überleg nur folgendes :

    -> Ist (auf Assembler-Ebene) in der Funktion 'void f(void)' die Anweisung 'printf("f()\n")' auch wirklich das erste, was ausgeführt wird ? <-



  • Laut debugger kommt vorher folgendes :

    (gdb) disas f
    Dump of assembler code for function f:
    0x08048374 <f+0>: push %ebp
    0x08048375 <f+1>: mov %esp,%ebp
    0x08048377 <f+3>: sub $0x8,%esp
    0x0804837a <f+6>: movl $0x804846c,(%esp)
    0x08048381 <f+13>: call 0x80482d4 puts@plt
    0x08048386 <f+18>: leave
    0x08048387 <f+19>: ret
    End of assembler dump.

    Die Ausgabe, müsste daher das sein

    0x0804837a <f+6>: movl $0x804846c,(%esp)
    0x08048381 <f+13>: call 0x80482d4 puts@plt

    Trotzdem komme ich nicht dahinter, aus was EIP zeigt ?

    Ich versuche mir grad etwas näher die Thematik "Stack Smashing" anzuschauen, daher meine Frage !



  • eip 0x804837a 0x804837a <f+6>
    

    Wenn Du in f() bei printf() angehalten hast, ist EIP logischerweise gerade an der Stelle, wo in f() die printf()-Funktion aufgerufen wird. Das steht auch dort: <f+6>

    Die Stelle hast Du ja schon gefunden:

    0x0804837a <f+6>: movl $0x804846c,(%esp)
    0x08048381 <f+13>: call 0x80482d4 <puts@plt>
    

    Warum sollte EIP innerhalb von f() einen Wert enthalten, der in die main() zeigt?!



  • Okay,

    wo finde ich dann die Rücksprungadresse in f(), damit der Prozess weiß, wohin er in main zurück springen muss ?


Anmelden zum Antworten