There is a simple trick to see the bitness of a Portable Executable file immediately by looking into a hex editor. But why does it even work? And is it reliable?
Recently I was approached on Twitter by @living_pirate with a question about PE bitness. Aparently there is a trick to see in a hex editor whether you are dealing with a 32 or 64 bit PE file. I had never heard of such a trick before, so I was intrigued.
The claim is that 32 bit PE files have the letter 'L' right after the PE signature, which is 'PE\0\0' or in hex 50 45 00 00. 64 bit PE files on the other hand have allegedly the letter 'd' appended to the PE signature.
If we open up a hex editor and look at some 32 and 64 bit samples, this seems to be correct (32 bit on the left, 64 bit on the right side). But why is this the case and what are we actually looking at?
Taking a peek into the PE COFF specification by Microsoft, we see that the COFF File Header starts right after the PE signature. The first field of the COFF File Header is 2 bytes long and denotes the machine type.
The specification distinguishes 25 different machine types, defined by constants. The PE Header values are little endian, so the least significant byte is written first. The letter 'd' is 0x64. That means three of those machine type constants will result in 'PE\0\0d' because they end with 0x64. I marked those constants below in red.
There is exactly one machine type constant that will have the letter 'L' or 0x4c as least significant bit and that's IMAGE_FILE_MACHINE_I386. I marked this constant in blue in the image below.
Now we know how it works and what it means, but is it a reliable way to determine the bitness of a PE file? Well, firstly, not every machine type is covered. Other machine types will neither show up as 'L' nor 'd' after the PE signature. In this case you will know that you need to look further.
However, if there is a 'PE\0\0d' or 'PE\0\0L', can you be sure of the bitness? While working on my thesis about Portable Executable anomalies, I discovered that the PE COFF specification is often more strict than the values Windows actually allows. Windows is very fault-tolerant with files that violate the specification because it needs to be backwards compatible. Especially malware and malware packers make use of this because it may deflect reversing and analysis tools whereas Windows still happily executes the file. However, if you put this to the test and change the value of the machine field, you will see that the file cannot be executed anymore.
That means, yes, this trick is reliable, just not encompassing all PE files.
So what do you do, if you encounter a PE file whose bitness you cannot determine this way?
You use one of the many PE viewers out there and check the Magic Number in the Optional Header. If the value is 0x10b or PE32, the file is 32 bit. If the value is 0x20b or PE32+, it's a 64 bit file.
My personal favourites for PE viewers are: