Search code examples
windowscoff

COFF byte ordering in PE formatted executable


I have a hexdump of a Windows binary and identified the COFF header in this executable by looking at the COFF offset:

0000080: 4550 0000 014c 0003 6ec8 3add 0000 0000
0000090: 0000 0000 00e0 010f 010b 0301 2000 0000

We can further verify this is the file header because of its 4 byte signature: 'PE' followed by two NULL bytes. Clearly, the format appears to be expressed in little endian because if we were to write PE explicitly, we would have the hex 50 45.

If we look at the PE format specification and carry this observation though, the NumberOfSections field (offset 2 bytes from the end of the signature that are skipped for the Machine field), we determine there are 768 sections (03 00 in little endian). This contradicts the spec, stating that the Windows loader limits the number of sections to 96.

Furthermore, byte ordering in the Timestamp field (next 4 bytes) seems odd because only the permutation 3add 6ec8 produces a Unix timestamp that is in the past.

Is there a more explicitly defined byte ordering that I'm missing? Why do the byte orderings between the fields seem inconsistent?


Solution

  • Your hexdump is using a misleading format. Try again with byte format (-c option)

    In the dump you have, the output is already byte swapped. Things appear in the order

    (byte1)(byte0) ' ' (byte3)(byte2) ' ' (byte5)(byte4) ' '

    and so on.

    The PE header is, as you mentioned

    50 45

    Hexdump's default display rules take these two bytes and interpret them as a 16-bit little endian integer, 0x4550, which is why the display is 4550

    The number of sections is 3, (03 00 in the file). I don't know why you said 03 00 is 768 in little endian because that's just wrong. In this case, the 16-bit LE default format of hexdump actually worked because it is a 16-bit field, the decode of 0x0003 is correct.

    The timestamp is displayed as 6ec8 3add but the actual bytes in the file are c8 6e dd 3a. Now the 32-bit field size and the 16-bit hexdump format mismatch, leading to your total confusion.