Iniziamo con una variabile semplice semplice
#include<stdio.h> int variabile; void main(){ variabile=0xCACACACA; getc(stdin); }La variabile viene dichiarata (e definita) inizialmente. E' una variabile globale in quanto viene dichiarata al di fuori di funzioni.
Nel contesto della funzione main viene inizializzata.
Ecco in OllyDbg quello che accade.
Questo è il codice assembly della funzione main:
00061390 > 55 PUSH EBP
00061391 8BEC MOV EBP,ESP
00061393 81EC C0000000 SUB ESP,0C0
00061399 53 PUSH EBX
0006139A 56 PUSH ESI
0006139B 57 PUSH EDI
0006139C 8DBD 40FFFFFF LEA EDI,DWORD PTR SS:[EBP-C0]
000613A2 B9 30000000 MOV ECX,30
000613A7 B8 CCCCCCCC MOV EAX,CCCCCCCC
000613AC F3:AB REP STOS DWORD PTR ES:[EDI]
000613AE C705 38710600 CA>MOV DWORD PTR DS:[variabile],CACACACA
000613B8 8BF4 MOV ESI,ESP
000613BA FF15 B4820600 CALL DWORD PTR DS:[<&MSVCR100D.__iob_fun>; MSVCR100.__iob_func
000613C0 3BF4 CMP ESI,ESP
000613C2 E8 6AFDFFFF CALL Studio.00061131
In rosso l'istruzione che inizializza la variabile globale.il nome della variabile è riportato nel disassemblato.
Mediante un'istruzione del menu popup di OllyDbg posso andare nella finestra del Dump alla locazione della variabile, prima ancora di eseguire l'istruzione nel debugger.
Ecco il disassemblato:
00067138 >00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00067148 >00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00067158 >00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00067168 >00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00067178 >00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00067188 >00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00067198 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................Ora imposto un punto di origine dell'esecuzione all'inizio della procedura main. Ed eseguo con il tasto F8 passo-passo:
00061390 > 55 PUSH EBP
00061391 8BEC MOV EBP,ESP
00061393 81EC C0000000 SUB ESP,0C0
00061399 53 PUSH EBX
0006139A 56 PUSH ESI
0006139B 57 PUSH EDI
0006139C 8DBD 40FFFFFF LEA EDI,DWORD PTR SS:[EBP-C0]
000613A2 B9 30000000 MOV ECX,30
000613A7 B8 CCCCCCCC MOV EAX,CCCCCCCC
000613AC F3:AB REP STOS DWORD PTR ES:[EDI]
000613AE C705 38710600 CA>MOV DWORD PTR DS:[variabile],CACACACA
000613B8 8BF4 MOV ESI,ESP
000613BA FF15 B4820600 CALL DWORD PTR DS:[<&MSVCR100D.__iob_fun>; MSVCR100.__iob_func
000613C0 3BF4 CMP ESI,ESP
Sono arrivato a questa istruzione, e il dump è ancora come prima.La eseguo ed ecco come cambia il dump:
00067138 >CA CA CA CA 00 00 00 00 00 00 00 00 00 00 00 00 ÊÊÊÊ............
00067148 >00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00067158 >00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00067168 >00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00067178 >00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00067188 >00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00067198 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
Conclusione: La variabile globale dichiarata e definita all'inizio, ha occupato un posto ben preciso, che è noto prima ancora che venga chiamata l'istruzione che la inizializza.
Adesso inizializzo la variabile globale al di fuori della funzione.
#include<stdio.h> int variabile=0xCACACACA;; void main(){ variabile=0xBABABABA; getc(stdin); }Vediamo in Olly:
009C7000 >CA CA CA CA 01 00 00 00 01 00 00 00 01 00 00 00 ÊÊÊÊ ... ... ...
009C7010 01 00 00 00 01 00 00 00 00 00 00 00 FE FF FF FF ... .......þÿÿÿ
009C7020 >01 00 00 00 FF FF FF FF FF FF FF FF 00 00 00 00 ...ÿÿÿÿÿÿÿÿ....
009C7030 >4E E6 40 BB B1 19 BF 44 00 00 00 00 00 00 00 00 Næ@»± ¿D........
009C7040 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
Dopo l'istruzione che ne cambia il valore:
009C7000 >BA BA BA BA 01 00 00 00 01 00 00 00 01 00 00 00 ºººº ... ... ...
009C7010 01 00 00 00 01 00 00 00 00 00 00 00 FE FF FF FF ... .......þÿÿÿ
009C7020 >01 00 00 00 FF FF FF FF FF FF FF FF 00 00 00 00 ...ÿÿÿÿÿÿÿÿ....
009C7030 >4E E6 40 BB B1 19 BF 44 00 00 00 00 00 00 00 00 Næ@»± ¿D........
009C7040 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
Benissimo! Una conferma in più che la locazione della variabile è predestinata già quando il programma è stato caricato in memoria.
Qui ho una tabella della mappa di memoria che contiene i vari segmenti del programma:
Memory map
Address Size Owner Section Contains Type Access Initial Mapped as
00010000 00010000 Map RW RW
00030000 00004000 Map R R
00040000 00001000 Map R R
0022D000 00001000 Priv RW Guar RW
0022E000 00002000 stack of mai Priv RW Guar RW
00390000 00005000 Priv RW RW
00490000 0037F000 Map R R \Device\HarddiskVolume2\Windows\System32\locale.nls
009B0000 00001000 Studio PE header Imag R RWE
009B1000 00010000 Studio .textbss code Imag R RWE
009C1000 00004000 Studio .text SFX Imag R RWE
009C5000 00002000 Studio .rdata Imag R RWE
009C7000 00001000 Studio .data data Imag R RWE
009C8000 00001000 Studio .idata imports Imag R RWE
009C9000 00001000 Studio .rsrc resources Imag R RWE
009CA000 00001000 Studio .reloc relocations Imag R RWE
00B70000 00004000 Priv RW RW
53280000 00001000 MSVCR100 PE header Imag R RWE
53281000 0015D000 MSVCR100 .text code,imports Imag R RWE
533DE000 00006000 MSVCR100 .data data Imag R RWE
533E4000 00001000 MSVCR100 .rsrc resources Imag R RWE
533E5000 0000D000 MSVCR100 .reloc relocations Imag R RWE
769C0000 00001000 kernel32 PE header Imag R RWE
769C1000 000CD000 kernel32 .text code,imports Imag R RWE
76A8E000 00003000 kernel32 .data data Imag R RWE
76A91000 00001000 kernel32 .rsrc resources Imag R RWE
76A92000 0000A000 kernel32 .reloc relocations Imag R RWE
77C00000 00001000 ntdll PE header Imag R RWE
77C01000 000C3000 ntdll .text code,exports Imag R RWE
77CC4000 00001000 ntdll RT Imag R RWE
77CC5000 0000B000 ntdll .data data Imag R RWE
77CD0000 00053000 ntdll .rsrc resources Imag R RWE
77D23000 00005000 ntdll .reloc relocations Imag R RWE
7F6F0000 00006000 Map R R
7FFB0000 00023000 Map R R
7FFDE000 00001000 data block o Priv RW RW
7FFDF000 00001000 Priv RW RW
7FFE0000 00001000 Priv R R
la quale dimostra che l'indirizzo attribuito alla variabile globale è l'indirizzo di inizio del segmento data.
Nessun commento:
Posta un commento