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>: retAn 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@pltTrotzdem 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 ?