-------[  RtC Mag, At the end of the universe  ]

--------------[  Infection Win32 : Part 3  ]
--------------[  Introduction au format Portable Executable  ]
---------[ fvrier 2001 ]
----[  by Doxtor L. <>  ]


-------[  Sommaire

    Voici le troisime volet de notre srie d'articles consacrs aux programmes auto-reproducteurs (aussi appels virus informatiques) sous Win32.

Voila ce que vous trouverez dans cet article :
    1)  Prambule
    2)  Introduction
    3)  En-tte Msdos et le Dos stub
    4)  En-tte PE
    5)  En-tte optionnel
    6)  En-ttes des sections
    7)  Sections   
    8)  Conclusion


-------[  1) Prambule


    Au tout dbut de l're PC (Personnal computer) de IBM, les programmes non crits en langage batch, ce langage dont on voit des commandes dans le fichier autoexec.bat taient pour la plupart des fichiers ".com". On peut se demander  quoi ressemble l'intrieur d'un tel fichier. La structure est simple, il n'y en a tout simplement pas ! L'organisation d'un fichier ".com"  est du ressort du programmeur, pour Msdos,  priori, le contenu est du code pur.
    La simplicit d'un fichier ".com" a un revers important, Msdos ne tolre pas que ce type de fichier contienne plus de 64 Kilo octets! Pour des questions de gestions de la mmoire, les fichiers excutables ont fini par avoir une structure pour pouvoir contenir plus de 64 Kilos octets et pour bnficier de la scurit induite par le passage du mode rel au mode protg, ce dernier mode tant le mode de prdilection de Windows.

    Nous nous intressons aux fichiers excutables seulement sous Win32. Nous voulons pouvoir modifier ce genre de fichiers pour leur ajouter des fonctionnalits. Aprs modification nous voulons que l'excutable soit encore fonctionnel. Pour ce faire, nous devons respecter la structure du fichier pour que Windows soit encore capable de l'excuter aprs l'intervention du programme auto-reproducteur qui l'a pris pour cible.
    Pour que l'opration soit un succs il n'il y a pas de grand mystre, nous devons en savoir suffisemment pour pouvoir faire des modifications tolres par Windows. Nous devons examiner le format des fichiers excutables sous Win32, ceci sont appels aussi P.E, Portable Excutable (Ce format est utilis sur d'autres plateformes, o par exemple, Win NT a t port par Microsoft).

    Ici je voudrais souligner une chose essentielle qui fait qu'un programme infect ne peut tre garantie 100% stable, c'est  dire avoir gard toutes ses fonctionnalits d'avant l'infection. Si dans un fichier .com vous remplacez les 5 premiers octets par les codes ASCII des lettres composant le mot: "DEBUT", vous tes assur d'un joli crash. Pourtant du point de vue de Msdos,  priori, le fichier modifi est un .com rgulier. Il en est de mme pour un fichier P.E. Un fichier modifi en respectant le format de celui-ci peut, mme s'il ne provoque pas d'erreur, au moment du chargement en mmoire, lorsque Windows teste sa validit, s'avrer tre inutilisable. Il peut y avoir une multitude de raisons  cela, par exemple le code du programme peut contenir une routine qui teste l'intgrit du fichier et ainsi refuser de fonctionner si le fichier a t modifi. Sans connaissance trs prcise du contenu d'un fichier on ne peut tre sr de ne pas le rendre inutilisable si on le modifie, mme "proprement".

    Ecrire des programmes auto-reproducteurs n'est pas une science exacte mais empirique. Ce qui suit est un peu plus thorique que le contenu des articles prcdants mme si je l'ai limit  ce qui est vraiment utile pour notre propos.


-------[  2) Introduction


    Un fichier PE a une organisation comparable  un disque dur. Voici un schma qui montre cette organisation :


              +-----------------------------------+
              |           en-tte MsDos           |
              +-----------------------------------+
              |             Dos stub              |
              +-----------------------------------+
              |            en-tte PE             |
              +-----------------------------------+
              |        en-tte optionnel          |
              |     en-tte des rpertoires  (*)  |
              +-----------------------------------+                       
              | tables des (en-tte des) sections |
              +-----------------------------------+
              |             section 1             |
              +-----------------------------------+
              |             section 2             |
              +-----------------------------------+
              |               (...)               |
              +-----------------------------------+
              |         dernire section          |
              +-----------------------------------+


    (*) La plupart des descriptions publies du format P.E regroupent ces deux parties en une seule : en-tte optionnel. Nous ne drogeront pas  cette "tradition".

    Il faut faire attention  une chose importante, un fichier P.E charg en mmoire n'occupe pas le mme nombre d'octets sur le disque et en mmoire. Lorsque je fais rfrence  ce qui ce passe sur le disque dur, j'utilise le modle naf suivant : Un fichier est stock sur disque en un seul groupe d'octets qui se suivent. On peut numroter les octets d'un fichier de telle faon que le premier octet ait le numro 0 et ainsi de suite. (En fait un fichier est rarement stock sur disque en un seul morceau et l'espace rellement occup est plus important que la taille relle du fichier !)
    En gnral, la taille en octets d'un fichier P.E sur disque est un multiple de 512. Alors qu'en mmoire la taille est en gnral un multiple de 4096. Est-ce besoin de prciser qu'un fichier aussi bien sur disque qu'en mmoire contient beaucoup d'octets qui ne servent  rien pour l'excution du programme ? C'est du remplissage ! On parle d'alignement.
    On l'avait dja constat en assemblant notre premier programme qui ne "faisait rien" et qui occupait, pourtant, 4096 octets sur le disque !

    La mmoire vive est vue par un programme comme tant constitue d'un norme bloc de 4 Giga octets, numrots par un nombre qui tient dans un double mot. On appelle ce numro ADRESSE VIRTUELLE. Pourquoi virtuelle ? en fait l'organisation relle de la mmoire est diffrente on peut s'en convaincre facilement : La DLL, Kernel32.dll est toujours prsente en mmoire puisqu'elle contient les fonctions fondamentales du systme d'exploitation, chaque programme charg en mmoire croit qu'il dispose de sa propre copie de cette DLL en fait cette DLL existe qu'en un seul exemplaire dans la mmoire vive, cela prouve bien que le modle D'ADRESSE VIRTUELLE n'est pas "rel".
    Et puis qui possde 4 GIGA octets de mmoire vive ? En fait, la mmoire virtuelle n'est pas que de la mmoire vive! Lorsque par exemple la mmoire vive est sature le systme d'exploitation va utiliser de l'espace disque pour combler le manque de mmoire vive (phnomne de swapping). C'est transparent pour un programme. Celui-ci ne se rend pas compte 
que la mmoire utilise n'est pas de la mmoire vive, l encore c'est le miracle des ADRESSES VIRTUELLES qui opre !

    Il nous faut mentionner un autre concept celui d'ADRESSE VIRTUELLE RELATIVE. Un fichier P.E contient diffrentes informations sur le fichier, entre autre l'adresse o doit tre charg en mmoire le fichier P.E. Les informations relatives  la structure d'un fichier P.E qui sont incluses dans celui-ci, contiennent des rfrences  des adresses en mmoire. Ces rfrences sont en fait des ADRESSES VIRTUELLES RELATIVES.
    Initialement, le format P.E devait permettre la relocation en mmoire, c'est  dire que le fichier pouvait tre charg  un autre emplacement que celui prvu par le champ qui le specifie dans ce fichier. Cela permet de simplifier la tche de Windows dans le calcul des adresses ncessaires pour charger un fichier P.E en mmoire.
    Pour obtenir une ADRESSE VIRTUELLE  partir d'une ADRESSE VIRTUELLE RELATIVE rien de plus simple il suffit de lui ajouter l'ADRESSE DE BASE du fichier P.E. Cette adresse est celle o sera charg le fichier en mmoire. Dans la pratique, cette relocation n'a jamais lieu pour un fichier P.E .exe  d  la manire dont est gre la mmoire par Windows. Dans le cas contraire, la section (voir plus loin pour ce concept), souvent nomme .reloc par les compilateurs contient tous les ajustements  faire pour que le fichier P.E soit correctement charg en mmoire et prt  fonctionner.

    Un fichier P.E est le plus souvent charg  l'adresse prvue. Lorqu'un excutable P.E est cr sans spcification particulire pour l'ADRESSE DE BASE, celle-ci est mise  la valeur par dfaut: 401000h. Ceci dit, vous ne pouvez spcifier n'importe qu'elle adresse. Elles doivent au moins tre alignes sur 1000h (4096 octets) c'est  dire multiple de 1000h. Nammoins, Windows n'autorise pas qu'un fichier P.E soit charg  n'importe qu'elle adresse, mme multiple de 1000h. Sous NT, par exemple, certaine zones mmoire sont rserves pour les DLL (Dynamic Link Library) autres fichiers P.E.


-------[  3) L'en-tte Msdos et le Dos stub


    Pour garder une compatibilit ascendante, un fichier P.E contient aussi une structure d'excutable .exe de Msdos. Les deux premiers octets sont les codes ASCII des caractres M et Z dans cet ordre. Ce qui suit, juste aprs, est l'en-tte .exe Msdos du fichier. Nous n'avons pas besoin de connaitre le contenu de cet en-tte en dtail.
    On trouve  la suite: le Dos stub. C'est du code qui est excut lorsque le fichier est dans un environnement 
Msdos pur. Ce code consiste en gnral en l'affichage d'un message qui dit en subtance : "Ce programme requiert Win32". En fait, ce code pourrait tre conu pour faire autre chose. C'est le concepteur du programme qui choisit, au moment du dveloppement.
    Le seul champ qui nous importe ici est situ  la fin de l'en-tte Msdos. Il contient une adresse de fichier vers l'en-tte PE. Cette adresse est situe  l'offset 3ch du dbut du fichier. Une adresse de fichier est la position d'un octet dans un fichier compt  partir du dbut, c'est un double mot. On rappelle que le premier octet dans un fichier est  l'offset 0 c'est  dire que son adresse de fichier est 0.


-------[  4) En-tte PE


    Comme nous venons juste de le voir, l'adresse de fichier du dbut de cet en-tte peut tre lu dans l'en-tte Msdos.
    L'en-tte PE commence par la chaine de caractres: "PE",0,0 (il s'agit bien de 0 et pas de "0" !). Voici un tableau qui dtaille les champs de cet en-tte:


+-------+----------------------+----+-----------------------------------+
| offs. |    nom du champ      | D? |           signification           |
+-------+----------------------+----+-----------------------------------+
|  00h  | PE_Magic             | DD | "PE",0,0                      (1) |
|  04h  | Machine              | DW | Type de machine               (2) |
|  06h  | NumberOfSections     | DW | Nombre de sections            (3) |
|  08h  | TimeDateStamp        | DD | Date et Temps                 (4) |
|  0ch  | PointerToSymbolTable | DD | Utilis pour dboguer         (5) |
|  10h  | NumberOfSymbols      | DD | Utilis pour dboguer         (6) |
|  14h  | SizeOfOptionalHeader | DW | Taille de l'en-tte optionnel (7) |
|  16h  | Characteristics      | DW | Caractristiques du fichier   (8) |
+-------+----------------------+----+-----------------------------------+
taille totale=18h   (24 en criture dcimale)


    Remarque : les nombres de la colonne offsets sont calculs par rapport au dbut de l'en-tte et non pas, par rapport au dbut du fichier.


    ** Explication des champs **

(1) la chaine "PE",0,0 permet d'identifier un fichier de type P.E

(2) le type de plateforme pour lequel est destin cet excutable c'est  dire le type de microprocesseur (intel, alpha...).

(3) Comme nous le verrons plus loin, les donnes et le code inclus dans un fichier PE sont regroups dans plusieurs parties du fichier appeles sections.
       
(4) Date et heure de cration du fichier.

(5) (6) Ces champs font rfrence  quelque chose qui simplifie la mise au point et le dbogage d'un programme, inutiles pour notre propos.

(7) L'en-tte optionnel contient la plupart des informations qui nous sont utiles comme nous allons le voir. Sa taille est en fait souvent fixe.

(8) Prcise la nature du fichier : ce peut tre un fichier .exe mais pas seulement, cela peut tre aussi une .dll. Ces deux types de fichiers sont un peu diffrents. Seul ici nous intresse les fichiers .exe PE.


    Parmi tout ces champs seulement (1),(3),(7) seront utiles pour notre but :

(1) Va servir  nous assurer que nous sommes bien en prsence d'un fichier PE et non pas d'un fichier .exe Msdos ou d'un fichier .exe de Windows 3.x

(3) Pour avoir facilement le nombre de sections.

(7) Permet de connaitre avec prcision la taille de l'en-tte optionnel.


-------[  5) En-tte optionnel


    Malgr son nom, il n'est pas optionnel du tout. La plupart des informations utiles pour notre but sont contenues dans cet en-tte. Il est situ juste aprs l'en-tte PE dja vu.

    Voici un tableau avec les champs pour cet en-tte : (tous les champs ne sont pas comments, c'est inutile pour notre propos)

+-------+--------------------------------+----+------------------------------+
| offs. |        nom du champ            | D? |          description         |
+-------+--------------------------------+----+------------------------------+
|  00h  | OH_Magic                       | DW |                              |
|  02h  | OH_MajorLinkerVersion          | DB |                              |
|  03h  | OH_MinorLinkerVersion          | DB |                              |
|  04h  | OH_SizeOfCode                  | DD |                              |
|  08h  | OH_SizeOfInitializedData       | DD |                              |
|  0ch  | OH_SizeOfUninitializedData     | DD |                              |
|  10h  | OH_AddressOfEntryPoint         | DD | Point d'entre           (1) |
|  14h  | OH_BaseOfCode                  | DD |                              |
|  18h  | OH_BaseOfData                  | DD |                              |
|  1ch  | OH_ImageBase                   | DD | Base de l'image          (2) |
|  20h  | OH_SectionAlignment            | DD | Alignement de la section (3) |
|  24h  | OH_FileAlignment               | DD | Alignement du fichier    (4) |
|  28h  | OH_MajorOperatingSystemVersion | DW |                              |
|  2ah  | OH_MinorOperatingSystemVersion | DW |                              |
|  2ch  | OH_MajorImageVersion           | DW |                              |
|  2eh  | OH_MinorImageVersion           | DW |                              |
|  30h  | OH_MajorSubsystemVersion       | DW |                              |
|  32h  | OH_MinorSubsystemVersion       | DW |                              |
|  34h  | OH_Win32VersionValue           | DD |                              |
|  38h  | OH_SizeOfImage                 | DD | Taille de l'image        (5) |
|  3ch  | OH_SizeOfHeaders               | DD | Taille des en-tte       (6) |
|  40h  | OH_CheckSum                    | DD |                              |
|       | OH_Subsystem                   | DW |                              |
|       | OH_DllCharacteristics          | DW |                              |
|       | OH_SizeOfStackReserve          | DD |                              |
|       | OH_SizeOfStackCommit           | DD |                              |
|       | OH_SizeOfHeapReserve           | DD |                              |
|       | OH_SizeOfHeapCommit            | DD |                              |
|       | OH_LoaderFlags                 | DD |                              |
|       | OH_NumberOfRvaAndSizes         | DD |   Nombre de rpertoires      |
+-------+--------------------------------+----+------------------------------+

    Remarques : Les nombres figurant dans la colonne offsets sont calculs par par rapport au dbut de la section. Les champs que nous n'utiliseront pas ne sont pas dcrits.


    ** Description des champs **

(1) Point d'entre :  ADRESSE VIRTUELLE RELATIVE de la premire instruction, du microprocesseur,  tre excuter lorsque le programme dmarre.

(2) Base de l'image : ADRESSE VIRTUELLE de dbut du fichier P.E en mmoire.

(3) Alignement de la section : La taille de chacunes des sections charges en mmoire est un multiple de ce nombre. Le plus souvent il s'agit de 1000h (4096 octets).

(4) Alignement du fichier : La taille du fichier, sur disque, est un multiple de ce nombre. Les sections, sur disque, ont aussi une taille multiple de ce nombre. Le plus souvent c'est 200h (512 octets).

(5) Taille de l'image : C' est la taille en mmoire de tout le fichier P.E Pour que le fichier soit reconnu comme valide, aprs modification, par Windows NT, vous devez prendre soin de bien renseigner ce champ.

(6) Taille des en-tte, la taille totale de tous les en-ttes d'un fichier P.E. 


    ** Table des rpertoires **

    Un rpertoire est un ensemble de groupes d'octets qui sont utiles aux fonctionnement du fichier P.E. Il ne peut y'en avoir qu'au plus 16. Chaque rpertoire a sa propre struture interne suivant sa fonction. Un rpertoire peut se situer  l'intrieur d'une section qui lui a t rserve ou bien tre inclus dans une autre section. Un rpertoire n'est pas une section ! Mme si trs souvent, un rpertoire est une section en lui-mme.

    Le rpertoire qui est toujours prsent dans un fichier P.E est le rpertoire IMPORT. Il contient les informations ncessaires  l'obtention dynamique des adresses de fonctions issues d'autres DLL ncessaires au bon fonctionnement du fichier P.E. Ce rpertoire a souvent une section pour lui tout seul, qui porte en gnral le nom: .idata. Parfois ce rpertoire se trouve inclus dans la section code du programme. Une DLL contient une section EXPORT. Elle contient la liste des fonctions exportes.

    La fin de l'en tte optionnel est constitu d'un groupe de 16 sous-parties contenant chacunes 2 double mots. Voici le dtail des 2 doubles mots:

    dd  Adresse Virtuelle relative du rpertoire.
    dd  Taille du rpertoire en mmoire.


    Voici l'enchanement de cette table de rpertoires:

+-------+----------+-----------------+
| offs. |  taille  |       nom       |
+-------+----------+-----------------+
|  00h  | 8 octets | Table d'export. |
|  08h  | 8 octets | Table d'import. |
| (...) |   (..)   |      (...)      |
+-------+----------+-----------------+
total= 256 octets occups par cette table
  
    Remarque : Mme si un rpertoire n'existe pas, il a tout de mme une entre dans la table. Les deux champs correspondants sont nuls.
 

-------[  6) Table des en-tte des sections


    Une section reflte la division d'un programme entre donnes et code. Dans un fichier P.E on trouve en gnral qu'une section contenant du code. Mais il peut y'avoir plusieurs sections diffrentes contenant des donnes.

+-------+-------------------------+-------+-------------------------------------+
| offs. |      nom du champ       |  D?   |            signification            |
+-------+-------------------------+-------+-------------------------------------+
|  00h  | SH_Name                 | DB(8) | Nom de la section               (1) |
|  08h  | SH_VirtualSize          |  DD   | Taille de la section en mmoire (2) |
|  0ch  | SH_VirtualAddress       |  DD   | Son ADRESSE VIRTUELLE RELATIVE  (3) |
|  10h  | SH_SizeOfRawData        |  DD   | Taille de la section sur disque (4) |
|  14h  | SH_PointerToRawData     |  DD   | Offset dans le fichier          (5) |
|  18h  | SH_PointerToRelocations |  DD   |                                     |
|  1ch  | SH_PointerToLinenumbers |  DD   |                                     |
|  20h  | SH_NumberOfRelocations  |  DW   |                                     |
|  22h  | SH_NumberOfLinenumbers  |  DW   |                                     |
|  24h  | SH_Characteristics      |  DD   | Attributs de la section.        (6) |
+-------+-------------------------+-------+-------------------------------------+

    Remarque : seuls les champs utiles  connaitre pour notre propos sont comments.


    ** Explication des champs **

(1) Le nom de la section, souvent les noms commencent par un point. le point est compt dans la taille du nom. Si le nom possde moins de 8 caractres, les octets restants sont mis  zro. Dans un fichier P.E on trouve souvent les noms de sections suivants: ".code" ,".text"  pour la section code.

(2) Taille de la section, une fois charge en mmoire. C'est un multiple de la valeur contenue dans le champ "Alignement d'une section" comme on l'a vu lors de l'tude de l'en-tte optionnel. Ainsi, c'est le plus souvent un multiple de 1000h (4096 octets).

(3) ADRESSE VIRTUELLE RELATIVE de la section en mmoire. C'est son adresse en mmoire, dont on a soustrait l'ADRESSE DE BASE du fichier P.E.  

(4) Taille de la section sur disque, c'est une taille en octets multiple de la valeur contenue dans le champ "Alignement du fichier" dans l'en-tte optionnel. C'est ainsi, Le plus souvent un multiple de 200h (512 octets).

(5) Offset dans le fichier. La section sur le disque commence  cette valeur. Rappelons que si un octet est  l'offset 0 dans un fichier, c'est le premier octet du fichier, sur le disque.
    
(6) Attributs de la section. Nous l'avons dja voqu dans un article prcdant. Il y'a plusieurs sortes d'attributs, ceux qui nous intressent sont "LECTURE", "ECRITURE". Pour pouvoir crire dans une section celle-ci doit avoir l'attribut ECRITURE, sinon gare  la faute de page ! Pour pouvoir lire dans une section, celle-ci doit avoir l'attribut LECTURE sinon risque de faute de page si tentative de lecture. L'attribut ECRITURE permet d'excuter du code plac dans n'importe quelle section. (c'est une remarque essentielle!). Quand je dis excuter, il faut evidemment que l'on ait aussi que, soit le point  d'entr du fichier P.E corresponde  une adresse dans cette section ou bien que la section code qui contient le point d'entre contienne galement un "jump" vers la section dont on a mis l'attribut ECRITURE et que ce "jump" soit excut ! Ils existent d'autres attributs mais nous n'en avons pas besoin pour notre propos.
    

-------[  7) Sections


    Les sections contiennent la subtance du programme comme dja mentionn. Une section peut tre totalement virtuelle. c'est  dire qu'elle n'a pas d'quivalent sur le disque. En effet rien n'interdit de renseigner les champs correspondants  l'offset de fichier et  la taille sur disque de la section avec zro !
    La place d'une section repre dans la table des en-tte de section est un reflet de sa position en mmoire. Si une section est dclare aprs une autre dans cette table, en mmoire son adresse sera plus leve que la section qui est dclare juste avant dans la table. Par contre, on ne peut rien dduire de leur enchainement rel dans le fichier sur le disque ! Mme si en gnral, il y a correspondance, il ne faut pas considrer que c'est une obligation.


-------[  8) Conclusion


    J'espre que vous serez parvenu sans raccourci jusqu' ce point de l'article, que je sais aride. J'ai essay de ne considrer que les points essentiels dans la description du format P.E en faisant l'impasse sur les choses qui ne jouent pas un rle direct pour notre but. Il est vrai que nous ne pouvons faire l'impasse sur tout, afin que la suite ne soit pas une suite de recettes obscures. Je vous donne rendez-vous dans le prochain article de notre srie o nous allons encaisser les dividendes de ce que nous avons appris jusqu' ce point.

     A bientt.


-------[  EOF