PE File Format

Transcription

PE File Format
PE File Format ...
Addr/Offset
0x00000000
0x00000040
Informations
Valeurs lues dans le fichier EXE_1.exe compilé en release ...
IMAGE_DOS_HEADER ► 0x5a4d ► e_magic; ► nombre magique
Divers
Longueur : 64
octets
En-tête utilisée pour qu'un
programme 32 bits soit
compatible avec un système
16 bits (msdos)
0x3c ►
0x0090 ► e_cblp; ► nbre octets sur dernière page du fichier
MSDOS Stub programm ►
Programme appelé en mode 16 bits par DOS, afin d'afficher une chaine de caractères « This program cannot Longueur
run in DOS mode. » Avec l'option -STUB du linkeur, on peut choisir un autre programme à insérer, que
variable ...
winstub.exe.
0x0003 ► e_cp; ► nbre de pages ds le fichier
(30*2+4)
...
0x000000e8 ► e_lfanew; ► offset de la nouvelle en-tête PE file header : 0xe8 = 232
ESPACE ... rempli de 00 00 00 00 ...
0x000000e8
PE File Signature
0x000000eb
IMAGE_FILE_HEADER ► 0x014c ► Machine ► Type de machine pour lequel l'exe est prévu
0x014c → Intel i386
0x0162 → MIPS R3000
0x0183 → DEC Alpha AXP ...
Début :
0xeb = 235
0x00004550 ► 'PE00' ► IMAGE_NT_SIGNATURE
0x454c → LE → IMAGE_OS2_SIGNATURE_LE
0x454e → NE → IMAGE_OS2_SIGNATURE
0x5a4d → MZ→ IMAGE_DOS_SIGNATURE
Longueur : 4
octets utilisé pour
différencier NT
de OS2, car le
format est le
même.
Longueur : 20
octets
0x0004 ► NumberOfSections ► Nombre de sections du fichier
Dernier :
235+20=255
255=0xff
0x450816a3 ► TimeDateStamp ► Date d'écriture de ce fichier par le linkeur, donnée en secondes depuis le
31 décembre 1969 à 16h00
0x00000000 ► PointerToSymbolTable ► Offset de fichier de la table des symbols COFF.
Utilisé uniquement en fichiers OBJ et exe, avec les infos de debug COFF. Aucun en release.
Section
suivante en
0xff + 1 =
0x100
0x00000000 ► NumberOfSymbols ► Nombre de symbols dans la table des symbols COFF.
Aucun en release.
0x00e0 ► SizeOfOptionalHeader ► Taille du header optionel qui suit cette structure. Dans les fichiers
OBJ, c'est à 0. Sinon, dans les autres, c'est 0x00e0 = 224 octets.
0x010f ► Characteristics ► Flags concernant ce fichier :
0x0001 → pas de relocation dans ce fichier
0x0002 → c'est un executable (ni un OBJ ou une LIB)
0x2000 → c'est une DLL, pas un programme
Il y est aussi expliqué aussi comment sont organisées les informations de debug, pour le debuguer.
Ainsi, les infos de debug sont déplacées de l'exe vers le PDB (IMAGE_FILE_DEBUG_STRIPPED). Mais
ces infos peuvent être stockées dans l'exe, dans une section nommée .debug.
Lorsque le PDB est généré, un numéro unique ID est écrit dans le PDB, et l'EXE.
0x00000100
Début :
0x100=256
Dernier:
256 + 224 =
480 = 0x1e0
Section
suivante en
0x1e0 + 1 =
0x1e1
IMAGE_OPTIONAL_HEADER ►
0x010b ► Magic ► Signature !
0x06 ► MajorLinkerVersion ► 6.0, version du linker ayant produit ce fichier
0x00 ► MinorLinkerVersion
0x0104
0x00001000 ► SizeOfCode ► Somme arondie supérieure de toutes les sections code .text
0x0108
0x00003000 ► SizeOfInitializedData ► Taille totale sections données initialisées
0x010c
0x00000000 ► SizeOfUnitializedData ► Taille à prévoir pour sections .bss
0x0110
0x000018e0 ► AddressOfEntryPoint ► RVA utilisée par le loader pour l'execution
0x0114
0x00001000 ► BaseOfCode ► RVA où se trouve le début de la section code
0x0118
0x00002000 ► BaseOfData ► RVA où se trouve le début de la section data, en fin de fichier
Champs additionnels ...
0x011c
0x00400000 ► ImageBase ► Adresse souhaitée où copier le code dans espace mémoire du process lors du
chargement par le loader. Option : -BASE : linker switch
0x0120
0x00001000 ► SectionAlignment ► Qd les sections sont mappées en mémoire, elles sont garanties de
commencer à des adresses multiples de cette valeur. 0X00001000 est utilisé par défaut.
Option : -ALIGN : linker switch
0x0124
0x00001000 ► FileAlignment ► Alignement utilisé par les données brutes des sections.
0x0128
0x0004 ► MajorOperatingSystemVersion ► OS minimum requis pour cet executable
0x0000 ► MinorOperatingSystemVersion
0x012c
0x0000 ► MajorImageVersion ► Champs défini par l'user, pour différencier les EXE/DLL
0x0000 ► MinorImageVersion
ainsi on peut avoir : « LINK /VERSION:2.0 toto.obj »
0x0130
0x0004 ► MajorSubsystemVersion ► Sous-system minimum requis pour cet executable
0x0000 ► MinorSubsystemVersion
0x0134
0x00000000 ► Reserved1 ► ???
0x0138
0x00005000 ► SizeOfImage ► Taille totale de ???
0x013c
0x00001000 ► SizeOfHeaders ► Taille PE Header et tables de section (object)
0x0140
0x00000000 ► Checksum ► Normalement, CRC du fichier, 0 sauf dans certains cas précis !
Il est sensé servir afin de vérifier l'executable lors de son chargement ! Algo de calcul CRC secret ...
Longueur : 224
octets
ulong = 4*19 =
76
ushort = 2*9 = 18
byte = 1*2 = 2
data = 16*8 =
128
► TTL = 224
octets
224=0xe0
PE File Format ...
0x0144
0x0002 ► SubSystem ► Sous system utilisé par cet executable.
1 → NATIVE : pas de sub system requis, utilisé par les drivers
2 → WINDOWS_GUI : Utilise le GUI Windows
3 → WINDOWS_CUI : Utilise le sous system caractères, applications consoles.
5 → OS2_CUI : Utilise le sous system caractères OS2, OS2 1.X uniquement
7 → POSIX_CUI : Utilise le sous system caractères Posix
0x0146
0x0000 ► DllCharactéristics ► Détermine comment est lancé le DllMain d'une DLL. Tjs à 0.
0x0148
0x00100000 ► SizeOfStackReserve ► Quantité de mémoire virtuelle à allouer pour la stack du thread
initial. 0X00100000 = 1Mo.
0x014c
0x00001000 ► SizeOfStackCommit ► Quantité de mémoire initialement remise pour la stack du thread
initial. 0X00001000 = 0x1000 octets = 1 page
0x0150
0x00100000 ► SizeOfHeapReserve ► Quantité de mémoire virtuelle à allouer pour le heap du thread
initial. 0X00100000 = 1Mo.
0x0154
0x00001000 ► SizeOfHeapCommit ► Quantité de mémoire initialement remise pour le heap du thread
initial. 0X00001000 = 0x1000 octets = 1 page, par défaut
0x0158
0x00000000 ► LoaderFlags ► Utilisé par le debugguer. (Rarement utilisé)
1 → invoque une instruction point d'arrêt avant le démarrage du process.
2 → invoque un deboguer sur le process après son chargement
0x015c
0c00000010 ► NumberOfRvaAndSizes ► Nombre d'entrées dans le tableau DataDirectory. 16 est utilisé
par défaut actuellement.
0x0160
16 * 8 octets = 128 octets, utilisés pour stocker les 16 structures IMAGE_DATA_DIRECTORY. Dans ces
structures se trouvent les endroits où trouver des composants importants de l'executable. 16 entrées sont
disponibles, mais 11 utilisées. Chacune d'elle est une structure IMAGE_DATA_DIRECTORY.
0x0160 : 0x0000000000000000 = 0 → IMAGE_DIRECTORY_ENTRY_EXPORT
0x0168 : 0x0000008c00002660 = 1 → IMAGE_DIRECTORY_ENTRY_IMPORT
0x0170 : 0x00000bd800004000 = 2 → IMAGE_DIRECTORY_ENTRY_RESOURCE
0x0178 : 0x0000000000000000 = 3 → IMAGE_DIRECTORY_ENTRY_EXCEPTION
0x0180 : 0x0000000000000000 = 4 → IMAGE_DIRECTORY_ENTRY_SECURITY
0x0188 : 0x0000000000000000 = 5 → IMAGE_DIRECTORY_ENTRY_BASERELOC
0x0190 : 0x0000000000000000 = 6 → IMAGE_DIRECTORY_ENTRY_DEBUG
0x0198 : 0x0000000000000000 = 7 → IMAGE_DIRECTORY_ENTRY_COPYRIGHT
0x01a0 : 0x0000000000000000 = 8 → IMAGE_DIRECTORY_ENTRY_GLOBALPTR
0x01a8 : 0x0000000000000000 = 9 → IMAGE_DIRECTORY_ENTRY_TLS
0x01b0 : 0x0000000000000000 = 10 → IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG
structure IMAGE_DATA_DIRECTORY ► (ULONG VirtualAddress + ULONG Size) = 8 octets
Pour trouver un répertoire donné, il faut utiliser VirtualAddress, qui est une RVA.
Debut :
0x0160
Suivant :
0x160=352
352 + 128 =
480 = 0x1e0
0x000001e0
En-têtes des
différentes
sections
écrites dans
le fichier.
Les sections
sont triées
selon leur
RVA
SECTIONS table .text
0x2e74657874000000 ► UCHAR Name [8] '.text' ► Nom de la section, utilisé uniquement par les codeurs
0x01e8 0x00000b92 = 2962 ► Union PhysicalAddress / VirtualSize ► Taille à réserver pour la section en mémoire
0x01ec 0x00001000 ► VirtualAddress ► Addresse virtuelle RVA de la section, où se trouve la section lors de son
chargement en mémoire.
0x01f0 0x00001000 ► SizeOfRawData ►Taille réellement occupée dans le fichier par la section
0x01f4 0x00001000 ►PointerToRawData ► Offset du début de la section
0x01f8 0x00000000 ► PointerToRelocations ► Addr de l'entrée de la section ds la table des relocations, 0 si EXE
0x01fc 0x00000000 ► PointerToLinenumbers ► Addr vers nb de ligne de la section. Souvent 0.
0x0200 0x0000 ► NumberOfRelocations ► Nb de relocations, 0 si EXE.
0x0202 0x0000 ► NumberOfLinenumbers ► Nb de structures « Linenumbers »
0x0204 0x60000020 ► Characteritics ► Attributs de la section (correspondance avec constantes PE)
0x00000020 → Section de code
0x00000040 → Section données initialisées
0x00000080 → Section données non initialisées
0x20000000 → Section executable
0x40000000 → Section en lecture
0x80000000 → Section en écriture ...
0x000000208 .rdata
0x208+0x28
= 0x230
0x0210
0x0214
0x0218
0x021c
0x0220
0x0224
0x0228
0x022a
0x022c
Longueur : 40
octets
Chacune des
sections fait 40
octets de long.
Il y a autant de
sections qu'on
veut, elles se
suivent toutes.
L'en-tête les
décrit.
0x2e72646174610000 ► '.rdata ► section des données en lecture seules : literal strings, constantes, debug
directory information
0x00000b22 = 2850 ► VirtualSize ► Taille de la section en mémoire
0x00002000 ► VirtualAddress ► RVA où se trouve la section en mémoire lors du chargement
0x00001000 ► SizeOfRawData ► Taille réellement occupée dans le fichier par la section
0x00002000 ► PointerToRawData ► Offset du début de la section
0x00000000 ► PointerToRelocations ► Addr de l'entrée de la section ds la table des relocations, 0 si EXE
0x00000000 ► PointerToLinenumbers ► Addr vers nb de ligne de la section. Souvent 0.
0x0000 ► NumberOfRelocations ► Nb de relocations, 0 si EXE.
0x0000 ► NumberOfLinenumbers ► Nb de structures « Linenumbers »
0x40000040 ► Characteritics ► Lecture seule + données initialisées
40 octets
0x00000230
0x230+0x28
= 0x258
.data
0x2e64617461000000 ► '.data' ► contient toutes les variables autres.
0x0238 0x00000118 = 280 ► VirtualSize ► Taille de la section en mémoire
0x00003000 ► VirtualAddress ► RVA où se trouve la section en mémoire lors du chargement
0x00001000 ► SizeOfRawData ► Taille réellement occupée dans le fichier par la section
0x00003000 ► PointerToRawData ► Offset du début de la section
0x00000000 ► PointerToRelocations ► Addr de l'entrée de la section ds la table des relocations, 0 si EXE
0x00000000 ► PointerToLinenumbers ► Addr vers nb de ligne de la section. Souvent 0.
0x0000 ► NumberOfRelocations ► Nb de relocations, 0 si EXE.
0x0000 ► NumberOfLinenumbers ► Nb de structures « Linenumbers »
0xc0000040 ► Characteritics ► Lecture/Ecriture + données initialisées
40 octets
0x00000258
0x258+0x28
=0x280
.rsrc
0x2e72737263000000 ► '.rsrc' ► ressources de l'executable, organisées en arbre.
0x0260 0x00000bd8 = 3032 ► VirtualSize ► Taille de la section en mémoire
0x00004000 ► VirtualAddress ► RVA où se trouve la section en mémoire lors du chargement
0x00001000 ► SizeOfRawData ► Taille réellement occupée dans le fichier par la section
40 octets
PE File Format ...
0x00004000 ► PointerToRawData ► Offset du début de la section
0x00000000 ► PointerToRelocations ► Addr de l'entrée de la section ds la table des relocations, 0 si EXE
0x00000000 ► PointerToLinenumbers ► Addr vers nb de ligne de la section. Souvent 0.
0x0000 ► NumberOfRelocations ► Nb de relocations, 0 si EXE.
0x0000 ► NumberOfLinenumbers ► Nb de structures « Linenumbers »
0x40000040 ► Characteritics ► Lecture seule + données initialisées
ESPACE ... rempli de 00 00 00 00 ...
0x00001000
Fin en :
0x00001b92
► Début de la section .text
Lg : 2962 octets
► Début de la section .rdata
Lg : 2850 octets
► Début de la section data
Lg : 280 octets
► Début de la section .rsrc
Lg : 3032 octets
ESPACE ... rempli de 00 00 00 00 ...
0x00002000
Fin en :
0x00002b22
ESPACE ... rempli de 00 00 00 00 ...
0x00003000
Fin en :
0x00003118
ESPACE ... rempli de 00 00 00 00 ...
0x00004000
Fin en :
0x00004bd8
ESPACE ... rempli de 00 00 00 00 ...
Fin du fichier EXE