Les documents sur le sujet abondent, mais j'ai choisi de vous présenter une synthèse des informations utiles du point de vue du vxer.. Si l’anglais ne vous fait pas peur, vous pourrez consulter des documentations telles Peering inside the PE: a tour of the win32 portable executable file format de Matt Pietrek, ou encore le Pecoff de Microsoft.
Pour notre propos, ce qui suit est largement suffisant. J’ai délibérément choisi de garder les noms anglais, car la plupart des documents que vous trouverez par la suite sont en anglais.
1) Sept notions importantes avant de commencer:
IMAGE BASE: C’est l’adresse à laquelle un fichier est chargé en mémoir.
RVA: Relative Virtual Address. Ce sont des références à des adresses en mémoire.
VA: C’est l’adresse de quelque chose en mémoire.
Ces 3 notions ne sont pas forcément évidentes à assimiler, mais elles restent néanmoins indispensables pour la suite. En fait, on peut dire qu’une RVA indique une distance à partir de l’image_base.
Voici un exemple imagé qui sera plus parlant:
Prenons un livre. Considérons que ce livre soit un programme. Vous décidez d’ouvrir le livre (on va dire qu’ouvrir la couverture de ce livre est semblable au lancement d’un programme, il est donc chargé en mémoire): Le début de ce livre est l’image_base du programme. Dans ce livre, il y a un index, et chaque élément important est référencé dans cet index. Quand nous cherchons un élément précis nous allons voir notre index, et ensuite nous nous rendons à la page indiquée par l’index. Eh bien la ligne qui nous dit à quelle page est l’élément qu nous cherchons est l’équivalent d’une RVA. Et la page en question, c’est la VA. Ensuite, nous allons à la page indiquée. Pour un programme, c’est pareil: on additionne l’image_base à la RVA, et nous trouvons l’adresse de l’élément voulu.
D’où: VA=RVA+image_base
Prenons on exemple concret: l’image base du programme test.exe est 401000h.
La première section de ce programme a pour RVA 1000h.
Donc, la première section sera chargée à l’adresse 401000h + 1000h, soit 402000h.
Les trois autres notions sont plus simples:
RAW DATA: Ce sont les données physiques, c’est à dire sur le disque (les données sur disque et en mémoire sont différentes).
VIRTUAL DATA: Ce sont les données une fois qu’elles ont été chargées en mémoire.
FILE MAPPING: C’est une technique qui consiste à créer en mémoire l’image exacte d’un fichier sur disque en vue de sa modification: un premier jeu d’API va créer la copie en mémoire, et un autre jeu va faire en sorte que les modifications effectuées sur la copie en mémoire soient appliquées au fichier original sur disque.
Sections: «Les données et le code inclus dans un fichier PE sont regroupés dans plusieurs parties de ce fichier appelées SECTIONS.» (tiré d'un tuto de Doxtor L)
2) Structure

Ouch! Voilà la bête! J’ai mis entre parenthèse les autre noms qu’on peu trouver dans d’autres documents. Les couleurs c’est juste pour la clarté.
Le premier champ n’est plus très important de nos jour, il sert à garder une compatibilité avec les exécutables Msdos. Les 2 éléments de ce champs à connaître sont:
à l’offset 00000000h: Les caractères MZ (très utile pour le virus)
à l’offset 0000003Ch: On y trouve l’adresse du début du PE HEADER
Le deuxième champ (PE_HEADER, qui débute à l’adresse indiquée à l’offset 3Ch) possède 3 éléments importants, à savoir:
"PE",0,0: cette signature est présente dans tous les fichiers PE. Elle permet au virus de savoir si il a affaire à un fichier PE ou pas.
nombre de sections du fichiers
taille de l’OPTIONAL HEADER
Le troisième champ, l’OPTIONAL_HEADER, a 6 éléments à connaître:
ENTRY POINT: C’est l’adresse (une RVA!) de la première instruction qui sera exécutée quand on lance le programme.
IMAGE BASE: C’est l’adresse (c’est aussi une RVA, mais elle compte comme une VA car c’est l’image_base, voir les notions du dessus) à laquelle le programme sera chargé en mémoire.
SECTION ALIGNEMENT : Lorsqu’une section est chargée en mémoire, elle doit avoir une taille qui est un multiple de cette valeur. Par défaut cette valeur est 1000h.
FILE ALIGNMENT: Toutes les RAW DATA (ainsi que toutes les sections sur disque) doivent avoir une taille qui est un multiple de cette valeur. Cette valeur par défaut est 200h.
IMAGE SIZE: C’est la taille de l’image (= fichier chargé en mémoire) du fichier PE. Cette valeur est liée au SECTION ALIGNMENT, nous verrons ça plus tard.
HEADER SIZE: C’est la taille du gros rectangle que je vous ai schématisé, c’est à dire à partir du «OLD DOS […]» jusqu’à la fin de «OBJECT TABLE»
Le quatrième champ, OBJECT TABLE ou SECTION_TABLE se compose de plusieurs champs dont 6 sont à retenir. Il y a autant de SECTION_TABLE qu’il y a de sections, le nombre de sections étant indiqué dans le PE HEADER.
SECTION NAME: le nom de la section
VIRTUAL SIZE: Taille de la section une fois qu’elle est chargée en mémoire, et cette taille est un multiple de la valeur FILE ALIGNEMENT.
RELATIVE VIRTUAL ADDRESS: RVA à laquelle la section est chargée en mémoire. Pour trouver l’adresse à laquelle la section commence réellement, on ajoute l’image_base
SIZE OF RAW DATA: Taille de la section (sur disque) une fois l’alignement avec le FILE ALIGNEMENT effectué.
POINTER TO RAW DATA: Indique l’offset auquel la section commence.
CHARACTERISTICS (aussi appelé FLAGS) : Indique les attributs de la section, par exemple «readable», «contains initialized data», etc…
Ouf! Ce passage est corsé, mais il est indispensable pour la suite. Si votre cerveau fume, allez vous changer les idées et prenez le temps de le relire plus tard. Je vous assure qu’on ne peut pas vraiment faire plus simple. Si vous ne me croyez pas, allez donc voir le document de Matt Pietrek! De plus, ça va peut-être vous filer le cafard, mais le plus dur reste à venir, avec l’EXPORT_TABLE. Après, ce sera moins ennuyeux puisqu’on commencera le coding, mais juste par petit bout, héhé… Encore une chose que je peux vous révéler maintenant que le PE n’a plus de secret pour vous: le virus que nous réaliserons augmentera la taille de la dernière section du fichier infecté, c’est plus simple que de rajouter une section complète.