JavascriptProva

venerdì 18 maggio 2012

Le variabili globali in C++ studiate con OllyDbg

Le variabili.
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