questo il mio programma:rifiuti in allocazione di memoria per le variabili locali
void test_function(int a, int b, int c, int d){
int flag;
char buffer[10];
flag = 31337;
buffer[0] = 'A';
}
int main() {
test_function(1, 2, 3, 4);
}
compilo questo programma con l'opzione di debug:
gcc -g my_program.c
Io uso gdb e smontare il test_function con la sintassi Intel:
(gdb) disassemble test_function
Dump of assembler code for function test_function:
0x08048344 <test_function+0>: push ebp
0x08048345 <test_function+1>: mov ebp,esp
0x08048347 <test_function+3>: sub esp,0x28
0x0804834a <test_function+6>: mov DWORD PTR [ebp-12],0x7a69
0x08048351 <test_function+13>: mov BYTE PTR [ebp-40],0x41
0x08048355 <test_function+17>: leave
0x08048356 <test_function+18>: ret
End of assembler dump.
E io smontare il principale:
(gdb) disassemble main
Dump of assembler code for function main:
0x08048357 <main+0>: push ebp
0x08048358 <main+1>: mov ebp,esp
0x0804835a <main+3>: sub esp,0x18
0x0804835d <main+6>: and esp,0xfffffff0
0x08048360 <main+9>: mov eax,0x0
0x08048365 <main+14>: sub esp,eax
0x08048367 <main+16>: mov DWORD PTR [esp+12],0x4
0x0804836f <main+24>: mov DWORD PTR [esp+8],0x3
0x08048377 <main+32>: mov DWORD PTR [esp+4],0x2
0x0804837f <main+40>: mov DWORD PTR [esp],0x1
0x08048386 <main+47>: call 0x8048344 <test_function>
0x0804838b <main+52>: leave
0x0804838c <main+53>: ret
End of assembler dump.
Inserisco un punto di interruzione in questo indirizzo: 0x08048355 (lascia istruzioni per la funzione test) e eseguo il programma.
guardo la pila così:
(gdb) x/16w $esp
0xbffff7d0: 0x00000041 0x08049548 0xbffff7e8 0x08048249
0xbffff7e0: 0xb7f9f729 0xb7fd6ff4 0xbffff818 0x00007a69
0xbffff7f0: 0xb7fd6ff4 0xbffff8ac 0xbffff818 0x0804838b
0xbffff800: 0x00000001 0x00000002 0x00000003 0x00000004
0x0804838b rappresenta l'indirizzo di ritorno, 0xbffff818 è il puntatore fotogramma salvato (EBP principale) e variabile di flag è fornito ulteriore 12 byte. Perché 12?
Non capisco questa istruzione:
0x0804834a <test_function+6>: mov DWORD PTR [ebp-12],0x7a69
perché non magazzino il contenuto della variabile 0x00007a69 in EBP-4 invece di 0xbffff8ac?
Stessa domanda per buffer. Perché 40?
Non sprechiamo la memoria? 0xb7fd6ff4 0xbffff8ac e 0xb7f9f729 0xb7fd6ff4 0xbffff818 0x08049548 0xbffff7e8 0x08048249 non vengono utilizzati?
Questo l'output del comando gcc -Q -v -g my_program.c
:
Reading specs from /usr/lib/gcc-lib/i486-linux-gnu/3.3.6/specs
Configured with: ../src/configure -v --enable-languages=c,c++ --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-gxx-include-dir=/usr/include/c++/3.3 --enable-shared --enable-__cxa_atexit --with-system-zlib --enable-nls --without-included-gettext --enable-clocale=gnu --enable-debug i486-linux-gnu
Thread model: posix
gcc version 3.3.6 (Ubuntu 1:3.3.6-15ubuntu1)
/usr/lib/gcc-lib/i486-linux-gnu/3.3.6/cc1 -v -D__GNUC__=3 -D__GNUC_MINOR__=3 -D__GNUC_PATCHLEVEL__=6 notesearch.c -dumpbase notesearch.c -auxbase notesearch -g -version -o /tmp/ccGT0kTf.s
GNU C version 3.3.6 (Ubuntu 1:3.3.6-15ubuntu1) (i486-linux-gnu)
compiled by GNU C version 3.3.6 (Ubuntu 1:3.3.6-15ubuntu1).
GGC heuristics: --param ggc-min-expand=99 --param ggc-min-heapsize=129473
options passed: -v -D__GNUC__=3 -D__GNUC_MINOR__=3 -D__GNUC_PATCHLEVEL__=6
-auxbase -g
options enabled: -fpeephole -ffunction-cse -fkeep-static-consts
-fpcc-struct-return -fgcse-lm -fgcse-sm -fsched-interblock -fsched-spec
-fbranch-count-reg -fcommon -fgnu-linker -fargument-alias
-fzero-initialized-in-bss -fident -fmath-errno -ftrapping-math -m80387
-mhard-float -mno-soft-float -mieee-fp -mfp-ret-in-387
-maccumulate-outgoing-args -mcpu=pentiumpro -march=i486
ignoring nonexistent directory "/usr/local/include/i486-linux-gnu"
ignoring nonexistent directory "/usr/i486-linux-gnu/include"
ignoring nonexistent directory "/usr/include/i486-linux-gnu"
#include "..." search starts here:
#include <...> search starts here:
/usr/local/include
/usr/lib/gcc-lib/i486-linux-gnu/3.3.6/include
/usr/include
End of search list.
gnu_dev_major gnu_dev_minor gnu_dev_makedev stat lstat fstat mknod fatal ec_malloc dump main print_notes find_user_note search_note
Execution times (seconds)
preprocessing : 0.00 (0%) usr 0.01 (25%) sys 0.00 (0%) wall
lexical analysis : 0.00 (0%) usr 0.01 (25%) sys 0.00 (0%) wall
parser : 0.02 (100%) usr 0.01 (25%) sys 0.00 (0%) wall
TOTAL : 0.02 0.04 0.00
as -V -Qy -o /tmp/ccugTYeu.o /tmp/ccGT0kTf.s
GNU assembler version 2.17.50 (i486-linux-gnu) using BFD version 2.17.50 20070103 Ubuntu
/usr/lib/gcc-lib/i486-linux-gnu/3.3.6/collect2 --eh-frame-hdr -m elf_i386 -dynamic-linker /lib/ld-linux.so.2 /usr/lib/gcc-lib/i486-linux-gnu/3.3.6/../../../crt1.o /usr/lib/gcc-lib/i486-linux-gnu/3.3.6/../../../crti.o /usr/lib/gcc-lib/i486-linux-gnu/3.3.6/crtbegin.o -L/usr/lib/gcc-lib/i486-linux-gnu/3.3.6 -L/usr/lib/gcc-lib/i486-linux-gnu/3.3.6/../../.. /tmp/ccugTYeu.o -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/lib/gcc-lib/i486-linux-gnu/3.3.6/crtend.o /usr/lib/gcc-lib/i486-linux-gnu/3.3.6/../../../crtn.o
NOTA: ho letto il libro "The art of exploitation" e io uso la VM fornisce con il libro.
Allineamento pila ... – Macmade
Sebbene tu abbia accettato una risposta, sono ancora molto curioso del _GCC_ che stai utilizzando. Potresti dirci il tuo sistema operativo (e la versione del sistema operativo) e puoi aggiungere l'output di questo comando alla fine della tua domanda 'gcc -Q -v -g my_program.c' per fornirci informazioni che potrebbero essere utili per sapere esattamente perché hai ottenuto questo particolare codice assembly dal compilatore? –
Grazie per aver fornito le informazioni aggiuntive. Quando avrò la possibilità farò delle indagini. –