Map and projects (the most frequently updated page of this blog)

2010/01/29

It's just a flesh wound

Section-less PE file (updated)
You may not expect a PE to be valid without all its standard structure:
Dos Header, Nt Headers, File Header, Optional Header, Data Directories, Section Headers.
TinyPE already proved that the Data directories are not compulsory, but also sections are not always required.

If the alignment is smaller than 1000h (800h or less), and the number of section is null, the loader loads the file directly as-is (RVA = Offset). And since the number of section is null, you don't need a section table altogether.

To use imports, you usually need just to define the Imports directory (VA only). the IAT directory is not required.
However, in this special section-less case, the IAT is required to set correct priorities on the right memory range, so the IAT size is required too.

To sum up:
  • NumberOfSection = 0
  • Alignment < 1000h
  • RVA = Offset
  • IAT RVA and SIZE are compulsory (if you use imports)
It makes a working PE that many tools will just handle as corrupted.

If you don't use imports, you can drop the whole set of data directories altogether. In this case, the header will be REALLY empty.

Binary Source

Update: SizeOfOptionalHeader has a confusing name. It's not the actual size of the optional header, it's just the delta between the start of the optional header and the section table, as it's used to find the locate it:
SizeOfOptionalHeader = @SectionTable - @Optional_Header

If you move the section table further in the file (even - for example - after the first section), SizeOfOptionalHeader will be huge, much bigger than the whole header itself (as in, SizeOfHeaders).
In this example, on the contrary, there is no (need of) section table, thus SizeOfOptionalHeader can be zero, or anything (even a value bigger than the filesize). But if it's negative, the file won't work.
This confirms that you can't put the section table before the Optional_Header, between the DOS_Header and the NT_Headers.

Yet another unexpectedly weird element in the PE headers...

[...]

Fichier PE sans section (mis à jour)
A priori, on n'imaginerait pas qu'un PE soit valide sans toutes ses structures standards :
Dos Header, Nt Headers, File Header, Optional Header, Data Directories, Section Headers.
TinyPE a déjà prouvé que les Data directories ne sont pas indispensables, mais les sections elles aussi ne sont pas toujours requises.

Si l'alignement est plus petit que 1000h (800h ou moins), et que le nombre de sections est nul, le loader charge le fichier directement tel quel (RVA = Offset). Et puisque le nombre de sections est nul, plus besoin de table de sections.

Pour utiliser les imports, on a d'habitude juste besoin de définir le Imports directory (juste son adresse virtuelle). La table d'imports (IAT directory) n'est pas obligatoire.
Cependant, dans ce cas particulier, la table d'imports est requise pour définir les priorités correctes sur le bon espace mémoire, donc la taille de la table est requise aussi.

Pour résumer :
  • NumberOfSection = 0
  • Alignement < 1000h
  • RVA = Offset
  • IAT RVA et SIZE obligatoires (si vous utilisez les imports)
Cela donne un PE qui marche, que beaucoup d'outils estimeront corrompu.

Si vous n'utilisez pas les imports, vous pouvez abandonner tous les data directories. Dans ce cas, l'en-tête sera VRAIMENT vide.

Binaire Source

Mise à jour : SizeOfOptionalHeader a un nom qui peut prêter à confusion. Ce n'est en fait pas la taille du Optional_Header, c'est juste la différence entre le début du Optional_Header et de la table des sections, puisqu'il est utilisé pour la localiser :
SizeOfOptionalHeader = @SectionTable - @Optional_Header

Si on met la table plus loin dans le fichier (même - par exemple - après la première section), SizeOfOptionalHeader sera énorme, bien plus que l'en-tête tout entier (tel que défini dans SizeOfHeaders).
Dans cet exemple, au contraire, on n'a pas (besoin) de table de sections, donc SizeOfOptionalHeader peut être nul, ou n'importe quoi (même une valeur plus grande que la taille du fichier). Mais si il est négatif, le fichier ne marchera pas.
Cela concorde avec le fait qu'on ne puisse pas mettre la table avant l'Optional_Header, entre le DOS_Header et les NT_Headers.

Encore un élément bien flou dans l'en-tête des PE.

No comments:

Post a Comment