Solution au PEAnalysis de Kharneth

Outils utilisés  :
Vous trouverez le fichier corrigé ici


1. Les en-têtes du fichier

En-tête DOS
On ouvre le fichier avec Stud_PE et on a une erreur.



On ouvre donc le fichier avec notre éditeur hexadécimal. Puis on effectue les modifications suivantes afin de faire reconnaître à Stud_PE qu'il s'agit bien du fichier exécutable PE.

Offset Type Champ Valeur Commentaires
00000000 WORD e_magic 0x5A4D MZ
0000003C WORD e_lfanew 0x00C0 Offset de l'en-tête PE (PE\0\0 -> 0x00004550)

Malgré quelques messages d'erreur, nous pouvons désormais ouvrir le fichier avec Stud_PE.



En cliquant sur le bouton "Basic HEADERS tree view in hexeditor" nous pourrons parcourir tous les champs des différents en-têtes du fichier afin de les vérifier.
Vous devez donc avoir un espace de travail qui ressemble à ça :



Avec la fenêtre "Executable Headers" nous allons maintenant examiner chaque champs. Afin d'alléger ce tutoriel, je ne vais énumérer que les champs à corriger.

Signature PE
Rien à signaler.

En-tête de l'image
Offset Type Champ Valeur Commentaires
000000C6 WORD NumberOfSection 0x0004
En parcourant la fenêtre "Stud_PE Hex Viewer..." on trouve à l'offset 000001B8 (début de l'en-tête des sections) les noms des sections. On s'aperçoit alors qu'il y en a 4 :
- ".text"
- ".rdata"
- ".data"
- ".rsrc"
000000D4 WORD SizeOfOptionnalHeader 0x00E0 C'est la taille de l'en-tête optionnel. Commence en 000000D8 et se termine en 000001B7 (inclus) => 1B7 + 1 - D8 = E0



Attention : Stud_PE sépare de l'en-tête optionnelle le Data_Directories qui en fait cependant partie.
000000D6 WORD Characteristics 0x010F
IMAGE_FILE_RELOCS_STRIPPED 0x0001
IMAGE_FILE_EXECUTABLE_IMAGE 0x0002
IMAGE_FILE_LINE_NUMS_STRIPPED 0x0004
IMAGE_FILE_LOCAL_SYMS_STRIPPED 0x0008
IMAGE_FILE_32BIT_MACHINE 0x0100
0x010F

En-tête optionnelle
Offset Type Champ Valeur Commentaires
000000F4 DWORD Imagebase 0x00400000 Adresse à laquelle les RVA doivent être relative. Généralement 0x400000
00000110 DWORD SizeOfImage 0x000040B8 Il s'agit de la taille du fichier (en-tête+sections).
Dans Stud_PE, cliquez sur l'onglet "Sections" :



La taille du fichier est donc la somme de la taille de la dernière section et son adresse.
B8 + 4000 = 40B8
00000114 DWORD SizeOfHeaders 0x00000400 C'est la taille en octet de toutes les en-têtes. Ce qui revient donc à l'offset de la première section.
Nous allons donc ouvrir à nouveau notre fichier avec l'éditeur hexadécimal.

En défilant jusqu'au début de l'en-tête des section (000001B8) nous pouvons voir que celle-ci est suivie de "00", il s'agit de padding qui complète l'en-tête jusqu'au début de la 1ère section.
Le padding s'arrête en 000003FF0, la 1ère section commence donc en 00000400.
0000011C WORD Subsystem 0x0002 Nous allons devoir déterminer si le fichier est un drivers, une application console, graphique...

Toujours avec l'éditeur hexadécimal, si l'on parcours le fichier un peu plus loin, on voit dans la partie "ASCCI" le mot "user32.dll". Il s'agit donc d'une application console.

IMAGE_SUBSYSTEM_WINDOWS_GUI -> 0x02
00000134 DWORD NumberOfRvaAndSizes 0x00000010 Nombre d'entrées du Data_Directories (toujours 16 éléments donc 0x10).

2. Les sections
Nous allons maintenant examiner les sections.

Comme nous l'avons vu précédemment elles sont au nombre de 4.


La section ".text"

Cette fonction est celle qui contient le code du programme.

Nous avons trois valeurs à retrouver : VirtualOffset, RawSize et RawOffset.

  • VirtualOffset

    Il s'agit de l'adresse virtuelle de la section. Comme c'est la section de code, la valeur sera celle du champ BaseOfCode de l'en-tête optionnel.
    Soit 0x1000

  • RawOffset

    Là c'est l'adresse physique de la section. Comme c'est la première section, ce sera la même valeur que celle du champ SizeOfHeaders de l'en-tête optionnel.
    Soit 0x400

  • RawSize

    C'est la taille de la section. Nous pouvons facilement la retrouver en fonction de l'adresse de la section suivante (".rdata").
    Soit 0x600 - 0x400 = 0x200

3. La table des importations

Dernière chose qu'il nous reste à faire, corriger l'Import Table.

Dans Stud_PE, cliquez sur l'onglet "Functions".



On s'aperçoit rapidement qu'il y a un problème : aucun modules, aucune fonctions.

L'Import Table est un tableau dont la taille n'est pas fixe, mais qui se termine toujours par un élément vide. Le fait que Stud_PE ne trouve aucune entrée signifie donc que le première élément du tableau est vide.

Ce tableau est situé dans la section ".rdata".



Pour connaître l'emplacement et la taille de notre Import Table, nous allons consulter l'élément correspondant dans le Data_Directories.

   - Emplacement : 0x2010 (RVA) soit l'offset 00000610
   - Taille : 0x3C

Nous aurons également besoin de connaître l'emplacement de l'IAT

   - Emplacement : 0x2000 (RVA) soit l'offset 00000600

Ainsi que de l'ImageThunkData

   - Emplacement : adresse de l'Import Table + sa taille = 0x610 + 0x3C soit l'offset 0000064C

Et enfin pour la Hint/Name Table

   - Emplacement : offset pointé par le 1er élément de l'ImageThunkData = 0x205C soit l'offset 0000065C


Offset Type Champ Valeur Commentaires
00000610 DWORD OriginalFirstThunk
0x204C Il s'agit d'une RVA qui pointe vers le premier membre de l'ImageThunkData.
Soit la RVA de l'offset 0000064C = 0x204C
0000061C DWORD Name 0x206A RVA qui pointe vers l'adresse du nom de la DLL.
Soit la RVA de l'offset 0000066A = 0x206A
00000620 DWORD FirstThunk 0x2000 Idem que pour l'OriginalFirstThunk mais avec l'IAT.
Soit la RVA de l'offset 00000600 = 0x2000


Et voila. On teste... et là, monter d'adrénaline, ÇA MARCHE. On voit une MessageBox qui nous félicite :)