PARTIE 4 : Entête facultatif
Date de publication : 08/10/2005
Par
Iczelion (Iczelion's Win32 Assembly Homepage)
Traduction et adaptation par Olivier Lance (Accueil)
Nous avons vu l'entête DOS et quelques membres de l'entête PE. Voici le dernier, le plus gros et certainement le plus important membre de l'entête PE : l'entête facultatif.
Article original :
Retour à
Tutoriel précédent :
Tutoriel suivant :
Pour mémoire, l'entête facultatif est le dernier membre de la structure
TImageNtHeaders. Il contient des informations
sur l'organisation logique du fichier
PE. Cette structure comporte 31 champs.
Certains d'entre eux sont cruciaux et d'autres ne sont pas utiles. Nous verrons uniquement les champs qui sont réellement
utiles.
Un mot revient fréquemment en relation avec le format
PE :
RVA.
RVA signifie
Relative Virtual Address. Vous savez ce qu'est une adresse virtuelle
(1).
RVA est un terme un peu rebutant pour un concept aussi simple. Pour parler simplement, une
RVA est une distance
à partir d'un point de référence dans l'espace d'adressage virtuel. J'imagine que vous savez ce qu'est un offset fichier : une
RVA est exactement la même chose qu'un offset fichier. Toutefois, elle est relative à une adresse virtuelle plutôt
qu'au début d'un fichier.
Voici un exemple :
Si un fichier
PE est chargé à l'adresse $400000 dans l'espace d'adressage virtuel et que le programme commence son
exécution à l'adresse $401000, on peut dire que le programme débute à la
RVA $1000. Une
RVA est relative à
l'adresse virtuelle du premier octet du module.
Pourquoi le format
PE utilise-t-il des
RVA ?
Le but est de réduire le temps de chargement du
PE Loader. Sachant qu'un module peut être déplacé n'importe où dans
l'espace d'adressage virtuel, ce serait infernal pour le
PE Loader de fixer les adresses de chaque élément à position
variable du module
(2). Par opposition, si tous les éléments ayant une position variable dans le fichier
utilisent des
RVA, le
PE Loader n'a alors pas besoin de fixer quoi que ce soit : il déplace simplement tout le
module à une nouvelle adresse virtuelle. Tout cela rejoint le concept de chemin relatif et chemin absolu : une
RVA est
assimilable à un chemin relatif, une adresse virtuelle à un chemin absolu.
Voici les champs intéressants de l'entête facultatif :
| Champ |
Contenu |
| AddressOfEntryPoint |
Il s'agit de la RVA de la première instruction qui sera exécutée lorsque le PE Loader sera prêt à lancer le fichier. Si vous souhaitez détourner le flux d'exécution dès le démarrage du programme, vous devez changer cette valeur pour une autre RVA, et l'instruction à cette nouvelle RVA sera alors exécutée en premier. |
| ImageBase |
C'est l'adresse de chargement souhaitable pour le fichier PE. Par exemple, si la valeur de ce champ est $400000, le PE Loader tentera de charger le fichier dans l'espace d'adressage virtuel à l'adresse $400000. Le mot "souhaitable" signifie que le PE Loader peut ne pas charger le fichier à cette adresse si un autre module l'occupe déjà. |
| SectionAlignment |
La granularité de l'alignement des sections en mémoire. Par exemple, si la valeur est 4096 ($1000), chaque section doit débuter à un multiple de 4096 octets. Si la première section est à l'adresse $401000 et que sa taille est de 10 octets, la prochaine section doit se trouver à l'adresse $402000, même si l'espace entre $401000 et $402000 sera pour la plupart inutilisé. |
| FileAlignment |
La granularité de l'alignement des sections dans le fichier. Par exemple, si la valeur est 512 ($200), chaque section doit débuter à un multiple de 512 octets. Si la première section est à l'adresse $200 et que sa taille est de 10 octets, la prochaine section doit se trouver à l'offset fichier $400 : l'espace entre les offset 522 et 1024 est inutilisé/indéfini. |
MajorSubSystemVersion MinorSubSystemVersion |
La version du système Win32. Si le fichier PE a été créé pour Win32, la version doit être 4.0 sans quoi les dialogues n'auront pas d'apparence 3D. |
| SizeOfImage |
La taille totale du fichier PE en mémoire. C'est la somme de tous les entêtes et des sections alignées avec la valeur SectionAlignment. |
| SizeOfHeaders |
La taille de tous les entêtes et de la table des sections. Cette valeur est égale à la taille du fichier moins la taille de toutes les sections du fichier. Vous pouvez utiliser cette valeur comme l'offset fichier de la première section dans le fichier PE. |
| Subsystem |
Donne pour quel sous-système NT le fichier PE est prévu. Pour la plupart des programmes Win32, seules deux valeurs sont utilisées : Windows GUI (IMAGE_SUBSYSTEM_WINDOWS_GUI) et Windows GUI (console) (IMAGE_SUBSYSTEM_WINDOWS_CUI). |
| DataDirectory |
Un tableau de structures IMAGE_DATA_DIRECTORY. Chaque structure fournit la RVA d'une structure de données importantes, comme la table d'importation. |
Liens
| (1) | Pour ceux qui
ne savent pas : il s'agit de l'adresse de données non pas sur un disque logique, mais dans la mémoire vive. |
| (2) | La position de certains éléments varie du fait de la taille également variable de certains
champs des entêtes. |


Copyright © 2005 Olivier Lance. Aucune reproduction, même partielle, ne peut être faite
de ce site et de l'ensemble de son contenu : textes, documents, images, etc
sans l'autorisation expresse de l'auteur.
Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E
de dommages et intérêts.
Cette page est déposée à la
SACD.