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

2010/01/16

With a rebel yell! more, more, more!

Description of a compiled PE header
In my previous posts, I started exploring PE Headers with a minimum amount of information (as opposed to the official specifications). On the other hand, standard compilers like MASM add more elements (not necessarily documented), on top of defining, as you would expect, mosts elements of the structures.

To understand things correctly, I assembled and linked a simple HelloWorld code source in Masm, and reproduce the complete structure of the executable with a YASM source (that defines every byte of the header manually).

Between the DOS header and the FILE Header lies the DOS stub, written in 16 bits. It should be aligned to 16, as its entrypoint is defined by the amount of paragraphs. In short, the DOS code can only start at X0, and the value of DOS_HEADER.e_cparhdr will be X (no zero):
DOS_HEADER.e_cparhdr dw (dos_stub - DOS_HEADER) >> 4
...
dos_stub:
bits 16
push cs
pop ds
mov dx, dos_msg - dos_stub
mov ah, 9
int 21h
mov ax, 4c01h
int 21h
dos_msg
db 'This program cannot be run in DOS mode.', 0dh, 0dh, 0ah, '$'

Right after this (16-aligned too) lies the 'undocumented' Rich Header/Signature, which is a signature generated by the compiler with the symbols presents in the file, among other things. Even the padding is not constant, and the whole block is xored with the checksum, which makes it quite odd altogether.
RichHeader:
RichKey EQU 092033d19h
dd "DanS" ^ RichKey , 0 ^ RichKey, 0 ^ RichKey , 0 ^ RichKey
dd 0131f8eh ^ RichKey , 7 ^ RichKey, 01220fch ^ RichKey, 1 ^ RichKey
dd "Rich", 0 ^ RichKey , 0, 0

The rest of the file is clean (no other extra stuff), and only 2 directories are defined, Imports and Imports Table (Some compiler like OpenWatcom define the Copyright directory, just a pointer to a copyright string).

After covering such a 'bloated' header, I can go back to unsual PE files again.
Binaries and Sources

[...]

Description d'un en-tête PE compilé

Dans mes billets précédents, j'ai commencé à explorer des en-têtes PE avec un minimum d'informations (par rapport aux spécifications officielles). A l'opposé, des compilateurs standards comme MASM rajoutent des éléments (pas forcément documentés), en plus de définir - comme on s'y attend - la plupart des éléments de la structure des en-têtes.

Pour comprendre correctement, j'ai assemblé et linké un code source simple de Hello World en Masm, puis reproduit la structure complète de l'exécutable avec un source YASM (qui définit manuellement chaque octet de l'en-tête).

Entre les en-têtes DOS et FILE, il y a le code DOS, en 16 bits. Il doit être aligné sur 16 octets, car son EntryPoint est défini par le nombre de paragraphe. En gros, le code DOS débute forcement à X0, et la valeur de DOS_HEADER.e_cparhdr sera X (pas de zéro) :
DOS_HEADER.e_cparhdr dw (dos_stub - DOS_HEADER) >> 4
...
dos_stub:
bits 16
push cs
pop ds
mov dx, dos_msg - dos_stub
mov ah, 9
int 21h
mov ax, 4c01h
int 21h
dos_msg
db 'This program cannot be run in DOS mode.', 0dh, 0dh, 0ah, '$'

Juste après (aligne sur 16 octets également) se trouve l'en-tête/signature Rich, qui est une signature générée par le compilateur à partir des symboles présents dans le fichier, entre autres. Même le padding n'est pas constant, et le bloc entier est xore avec une somme de contrôle, ce qui rend le tout plutôt étrange..
RichHeader:
RichKey EQU 092033d19h
dd "DanS" ^ RichKey , 0 ^ RichKey, 0 ^ RichKey , 0 ^ RichKey
dd 0131f8eh ^ RichKey , 7 ^ RichKey, 01220fch ^ RichKey, 1 ^ RichKey
dd "Rich", 0 ^ RichKey , 0, 0

Le reste du fichier est propre (plus rien de rajouté), et seul 2 data directories sont définis Imports et Imports Table (des compilateurs comme OpenWatcom définissent le Copyright directory, juste un pointeur vers une chaîne de copyright).

Après avoir couvert un tel en-tête 'superflu', je peux retourner à mes fichiers PE inhabituels.
Binaires et Sources

No comments:

Post a Comment