Home

Awesome

richprint

Print compiler information stored in Rich Header of PE executables.

What is that "Rich Header of PE executables"?

It's a (usually small) section of binary data created by Microsoft linker. The data is located between old MZ header stub (also called DOS stub) and PE header. The data is encoded using a simple key, the only readable part of the whole section being the word "Rich".

The section is ubiquitous: you can find it in almost any type of PE (portable executable) file: .EXE, .DLL. .CPL (control panel applets), etc. Yet, if the file was created by a non-Microsoft linker, it will not have a Rich header.

The official name for this section is not known for sure, most likely it is something similar to "build prodid block".

The unofficial names for this section are "Rich Header" or "Rich Section", for obvious reasons.

The format of Rich Header and the gory details of decoding it can be found in the excellent article by Daniel Pistelli.

So, what does it contain after all?

Short and useless answer: the Rich Header contains the list of all @comp.id's used to create the executable file, together with their counts.

Long and elaborate answer:

Sources of information

I gathered some @comp.id's from my own collection of Visual Studio editions.

Some were interpolated using open sources (e.g., an excellent list of Visual Studio versions by @yumetodo. In this list, _MSC_FULL_VER contains the build number, so it is easy to interpolate the @comp.id's when you know the numbering scheme for different tools.

"Interpolated" values are most likely to be correct. I checked some interpolated @comp.id's against real-world values, and they matched. Yet, interpolated values are marked with (*) for - ehm... - completeness?

How can this information be used?

In any way you like. For example, to satisfy your curiosity by inspecting the binaries in your system. Also, Rich Headers can allegedly be used in forensics.

Can I prevent Microsoft tools from emitting this header?

Yes you can. Provide this undocumented option to the linker: /emittoolversioninfo:no.

Thanks to Oliver Schneider for pointing this out.