[ MiTo @ 24.06.2006. 15:38 ] @
Pozdrav svima, Ne bih pitao da nisam zaglavio malo, samo malo :) Zaglavio sam na necemu jako jako "jednostavnom". Evo koda programcica iz tutoriala: Code: void function(int a, int b, int c) { char buffer1[5]; char buffer2[10]; int *ret; ret = buffer1 + 12; (*ret) += 8; } void main() { int x; x = 0; function(1,2,3); x = 1; printf("%d\n",x); } i slika stacka bi izgledala ovako: Code: bottom of top of memory memory buffer2 buffer1 sfp ret a b c <------ [ ][ ][ ][ ][ ][ ][ ] top of bottom of stack stack Ok, koliko sam shvatio, buffer jedan zauzima 8 bajtova (4+1=5, po blokovima od 4 bajta to ide u 2 bloka, dakle 8 bajtova), sfp (bp) zauzima 4 bajta. Dakle ukupno je to 12 bajtova i stoga stavimo ret=buffer1+12 da dobijemo EIP. Problem sad nastaje u (*ret)+=8. Mozda moj kalkulator ne valja, ali ja ne vidim kako je on dobio 8 iz ovoga: Citat: [aleph1]$ gdb example3 GDB is free software and you are welcome to distribute copies of it under certain conditions; type "show copying" to see the conditions. There is absolutely no warranty for GDB; type "show warranty" for details. GDB 4.15 (i586-unknown-linux), Copyright 1995 Free Software Foundation, Inc... (no debugging symbols found)... (gdb) disassemble main Dump of assembler code for function main: 0x8000490 <main>: pushl %ebp 0x8000491 <main+1>: movl %esp,%ebp 0x8000493 <main+3>: subl $0x4,%esp 0x8000496 <main+6>: movl $0x0,0xfffffffc(%ebp) 0x800049d <main+13>: pushl $0x3 0x800049f <main+15>: pushl $0x2 0x80004a1 <main+17>: pushl $0x1 0x80004a3 <main+19>: call 0x8000470 <function> 0x80004a8 <main+24>: addl $0xc,%esp 0x80004ab <main+27>: movl $0x1,0xfffffffc(%ebp) 0x80004b2 <main+34>: movl 0xfffffffc(%ebp),%eax 0x80004b5 <main+37>: pushl %eax 0x80004b6 <main+38>: pushl $0x80004f8 0x80004bb <main+43>: call 0x8000378 <printf> 0x80004c0 <main+48>: addl $0x8,%esp 0x80004c3 <main+51>: movl %ebp,%esp 0x80004c5 <main+53>: popl %ebp 0x80004c6 <main+54>: ret 0x80004c7 <main+55>: nop ------------------------------------------------------------------------------ We can see that when calling function() the RET will be 0x8004a8, and we want to jump past the assignment at 0x80004ab. The next instruction we want to execute is the at 0x8004b2. A little math tells us the distance is 8 bytes. Evo kako to izgleda kod mene: Code: int main() { function(1,2,3); printf("a\n"); printf("b\n"); return 0; } i gdb exe daje: Citat: Dump of assembler code for function main: 0x080483aa <main+0>: push %ebp 0x080483ab <main+1>: mov %esp,%ebp 0x080483ad <main+3>: sub $0x18,%esp 0x080483b0 <main+6>: and $0xfffffff0,%esp 0x080483b3 <main+9>: mov $0x0,%eax 0x080483b8 <main+14>: add $0xf,%eax 0x080483bb <main+17>: add $0xf,%eax 0x080483be <main+20>: shr $0x4,%eax 0x080483c1 <main+23>: shl $0x4,%eax 0x080483c4 <main+26>: sub %eax,%esp 0x080483c6 <main+28>: movl $0x3,0x8(%esp) 0x080483ce <main+36>: movl $0x2,0x4(%esp) 0x080483d6 <main+44>: movl $0x1,(%esp) 0x080483dd <main+51>: call 0x8048384 <function> 0x080483e2 <main+56>: movl $0x8048551,(%esp) 0x080483e9 <main+63>: call 0x80482b8 <printf@plt> 0x080483ee <main+68>: movl $0x8048554,(%esp) 0x080483f5 <main+75>: call 0x80482b8 <printf@plt> 0x080483fa <main+80>: mov $0x0,%eax 0x080483ff <main+85>: leave 0x08048400 <main+86>: ret 0x08048401 <main+87>: nop Ako mi netko moze pojasnit ko debilu :) kako se racuna razmak? kalkulator daje 10, tutorial daje 8...a exe daje segmentation fault u svakom slucaju. Aloha! |