Compago

...free knowledge

 
  • Increase font size
  • Default font size
  • Decrease font size
Home Manuali Programmazione Struttura di un data loader

Struttura di un data loader

E-mail Stampa PDF


All'offset 1Ch del PEB (Process Enviroment Block) troviamo il puntatore ai dati del loader (PEB_LDR_DATA)
Questi dati sono strutturati in questo modo:

PEB_LDR_DATA = packed record                     
  Length: Cardinal;                             //Dimensione struttura
  Initialized: BOOLEAN;                         
  SsHandle: Pointer;                            
  FirstInLoadOrderModuleList: PLDR_MODULE; //Puntatore al primo LDR_MODULE in ordine di caricamento
LastInLoadOrderModuleList: PLDR_MODULE; //Puntatore all'ultimo LDR_MODULE in ordine di caricamento
FirstInMemoryOrderModuleList: PLDR_MODULE; //Puntatore al primo LDR_MODULE in ordine di posizione in memoria
LastInMemoryOrderModuleList: PLDR_MODULE; //Puntatore all'ultimo LDR_MODULE in ordine di posizione in memoria
FirstnInitializationOrderModuleList: PLDR_MODULE; //Puntatore al primo LDR_MODULE in ordine di inizializzazione
LastnInitializationOrderModuleList: PLDR_MODULE; //Puntatore all'ultimo LDR_MODULE in ordine di inizializzazione
end;                                            
PPEB_LDR_DATA =^PEB_LDR_DATA;

Un esempio di PEB_LDR_DATA è il seguente

Dump - 00240000..00245FFF
Indirizzo Dati         Dati dec.    Commenti                           
00241EA0  28 00 00 00  00000028    //Length
00241EA4  01 F0 AD BA  BAADF001    //Initialized
00241EA8  00 00 00 00  00000000    //SsHandle
00241EAC E0 1E 24 00 00241EE0 //InLoadOrderModuleList primo elemento
00241EB0 60 25 24 00 00242560 //InLoadOrderModuleList ultimo elemento
00241EB4 E8 1E 24 00 00241EE8 //InMemoryOrderModuleList primo elemento
00241EB8 68 25 24 00 00242568 //InMemoryOrderModuleList ultimo elemento
00241EBC 58 1F 24 00 00241F58 //InInitializationOrderModuleList primo elemento
00241EC0 E8 20 24 00 002420E8 //InInitializationOrderModuleList ultimo elemento
00241EC4  00 00 00 00  00000000


I dati più importanti contenuti sono sicuramente i puntatori agli LDR_MODULE i quali saranno tanti quanti sono i moduli caricati in memoria. Questi dati sui moduli sono collegati in liste concatenate.
Le liste che contengono le informazioni sui moduli differiscono solo l'ordine in cui vengono elencati.
La prima lista li elenca in ordine di caricamento, la seconda in ordine di disposizione in memoria, la terza in ordine di inizializzazione, ma i nodi della lista sono sempre gli stessi.

Vediamo la struttura di un nodo LDR_MODULE:

LDR_MODULE = packed record                                                                                    
  NextInLoadOrderModuleList: PLDR_MODULE; //puntatore al successivo in ordine di caricamento
PreviousInLoadOrderModuleList: PLDR_MODULE; //puntatore al precedente in ordine di caricamento
NextInMemoryOrderModuleList: PLDR_MODULE; //puntatore al successivo in ordine di posizione in memoria
PreviousInMemoryOrderModuleList: PLDR_MODULE; //puntatore al precedente in ordine di posizione in memoria
NextInInitializationOrderModuleList: PLDR_MODULE; //puntatore al successivo in ordine di inizializzazione
PreviousInInitializationOrderModuleList: PLDR_MODULE; //puntatore al precedente in ordine di inizializzazione
BaseAddress: pointer;                                                 
  EntryPoint: pointer;                                                   
  SizeOfImage: cardinal;                                                 
  FullDllName: UNICODE_STRING ;                               
  BaseDllName: UNICODE_STRING ;                              
  Flags: cardinal;                                                            
  LoadCount: word;                                                     
  TlsIndex: word;
  HashTableEntry: PLDR_MODULE;                                                      
  HashTableEntry: PLDR_MODULE;                                 
  TimeDateStamp: cardinal;                                             
end;                                                                              
PLDR_MODULE = ^LDR_MODULE 


Esempio pratico, prendiamo il primo LDR_MODULE che corrisponde proprio allo stesso eseguibile, il quale viene sempre caricato per primo in memoria:

Dump - 00240000..00245FFF                                                             
Indirizzo Dati         Dati dec.    Commenti                                     
00241EE0  48 1F 24 00  00241F48     //puntatore al successivo in ordine di caricamento        
00241EE4 AC 1E 24 00 00241EAC //puntatore al precedente in ordine di caricamento
00241EE8 50 1F 24 00 00241F50 //puntatore al successivo in ordine di posizione in memoria
00241EEC B4 1E 24 00 00241EB4 //puntatore al precedente in ordine di posizione in memoria
00241EF0 00 00 00 00 00000000 //puntatore al successivo in ordine di inizializzazione
00241EF4 00 00 00 00 00000000 //puntatore al precedente in ordine di inizializzazione
00241EF8  00 00 40 00  00400000     //BaseAddress                 
00241EFC  34 91 40 00  00409134     //EntryPoint                  
00241F00  00 50 01 00  00015000     //SizeOfImage                 
                                    //FullDllName: UNICODE_STRING ;   (nome completo eseguibile)
00241E04  74 00        0074         //Length
00241E04  76 00        0076         //MaxLength
00241E08  58 08 02 00  00020858     //FullDllName - puntatore al nome
                                    //BaseDllName: UNICODE_STRING ;   (nome eseguibile)
00241E0C  3A 00        003A         //Length
00241E0C  3C 00        003C         //MaxLength  
00241F10  92 08 02 00  00020892     //BaseDllName - puntatore al nome  
00241E14  00 50 00 00  00005000     //Flags: cardinal;                             
00241E18  FF FF        FFFF         //LoadCount: word;           
00241E1A  FF FF        FFFF         //TlsIndex: word;         
00241E1C  4C 20 24 00  0024204C     //HashTableEntry 
00241F20  10 C2 98 7C  7C98C210     //HashTableEntry   
00241E24  CF DA 13 4B  4B13DACF     //TimeDateStamp
00241E28  00 00 00 00  00000000    
00241E2C  00 00 00 00  00000000    


Se seguiamo la lista concatenata, per esempio in ordine di caricamento troveremo i dati relativi al modulo ntdll.dll:

Indirizzo Dati          Dati dec.     Commenti        
00241F48  10 20 24 00   00242010  |   //puntatore al successivo in ordine di caricamento        
00241F4C E0 1E 24 00 00241EE0 | //puntatore al precedente in ordine di caricamento
00241F50 18 20 24 00 00242018 | //puntatore al successivo in ordine di posizione in memoria
00241F54 E8 1E 24 00 00241EE8 | //puntatore al precedente in ordine di posizione in memoria
00241F58 20 20 24 00 00242020 | //puntatore al successivo in ordine di inizializzazione
00241F5C BC 1E 24 00 00241EBC | //puntatore al precedente in ordine di inizializzazione
00241F60  00 00 91 7C   7C910000  |   //BaseAddress                 
00241F64  56 31 92 7C   7C923156  |   //EntryPoint                  
00241F68  00 60 0B 00   000B6000  |   //SizeOfImage                 
00241F6C  3A 00         003A      |   //FullDllName: UNICODE_STRING ;   
00241F6E  08 02         0208      |   //FullDllName - length
00241F70  E8 DE 98 7C   7C98DEE8  |   //FullDllName - puntatore
00241F74  12 00         0012      |   //BaseDllName: UNICODE_STRING ;    ntdll.dll
00241F76  14 00         0014      |   //BaseDllName - length  
00241F78  A4 26 93 7C   7C9326A4  |   //BaseDllName - puntatore
00241F7C  04 40 08 80   80084004  |   //Flags: cardinal;
00241F80  FF FF         FFFF      |   //LoadCount
00241F82  00 00         0000      |   //TlsIndex
00241F84  28 C2 98 7C   7C98C228  |   //HashTableEntry
00241F88  28 C2 98 7C   7C98C228  |   //HashTableEntry
00241F8C  01 2C 25 41   41252C01  |   //TimeDateStamp
00241F90  00 00 00 00   00000000  |


Per verificare i puntatori delle unicode string riportiamo il dump dell'area di memoria puntata:

Dump - ntdll:.data
Indirizzo  Dati                                             ASCII
7C98DEE8   46 00 3A 00|5C 00 57 00|49 00 4E 00|44 00 4F 00| F.:.\.W.I.N.D.O.
7C98DEF8   57 00 53 00|5C 00 73 00|79 00 73 00|74 00 65 00| W.S.\.s.y.s.t.e.
7C98DF08   6D 00 33 00|32 00 5C 00|6E 00 74 00|64 00 6C 00| m.3.2.\.n.t.d.l.
7C98DF18   6C 00 2E 00|64 00 6C 00|6C 00 00 00|             l...d.l.l...

 

Dump - ntdll:.text
Indirizzo  Dati                                             ASCII
7C9326A4   6E 00 74 00|64 00 6C 00|6C 00 2E 00|64 00 6C 00| n.t.d.l.l...d.l.
7C9326B4   6C 00 00 00|                                     l...              

Se seguiamo ulteriormente la lista concatenata, per esempio in ordine di caricamento, troveremo i dati relativi al modulo kernel32.dll:

Dump - 00240000..00245FFF                                                 
Indirizzo Dati          Dati dec.   Commenti                                
00242010  D8 20 24 00   002420D8    //puntatore al successivo in ordine di caricamento          
00242014 48 1F 24 00 00241F48 //puntatore al precedente in ordine di caricamento
00242018 E0 20 24 00 002420E0 //puntatore al successivo in ordine di posizione in memoria
0024201C 50 1F 24 00 00241F50 //puntatore al precedente in ordine di posizione in memoria
00242020 A8 21 24 00 002421A8 //puntatore al successivo in ordine di inizializzazione
00242024 58 1F 24 00 00241F58 //puntatore al precedente in ordine di inizializzazione
00242028  00 00 80 7C   7C800000    //BaseAddress                                                 
0024202C  AE B5 80 7C   7C80B5AE    //EntryPoint                                                  
00242030  00 00 10 00   00100000    //SizeOfImage                                                 
00242034  40 00         0040        //FullDllName: UNICODE_STRING ;                               
00242036  42 00         0042        //FullDllName - length                                        
00242038  B0 1F 24 00   00241FB0    //FullDllName - puntatore                                     
0024203C  18 00         0018        //BaseDllName: UNICODE_STRING ;                      
0024203E  1A 00         001A        //BaseDllName - length                                        
00242040  D8 1F 24 00   00241FD8    //BaseDllName - puntatore                                     
00242044  04 40 08 80   80084004    //Flags: cardinal;                                            
00242048  FF FF         FFFF        //LoadCount                                                   
0024204A  00 00         0000        //TlsIndex                                                    
0024204C  10 C2 98 7C   7C98C210    //HashTableEntry                                              
00242050  1C 1F 24 00   00241F1C    //HashTableEntry                                              
00242054  E9 09 00 45   450009E9    //TimeDateStamp                                               

Verifichiamo il nome della libreria:

Dump - 00240000..00245FFF                                                  
Indirizzo  Dati                                             ASCII          
00241FD8   6B 00 65 00|72 00 6E 00|65 00 6C 00|33 00 32 00| k.e.r.n.e.l.3.2.
00241FE8   2E 00 64 00|6C 00 6C 00|00 00                    ..d.l.l...    

E così via per tutti i moduli caricati in memoria.

Ultimo aggiornamento ( Sabato 19 Giugno 2010 17:16 )