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