pefile: parsing version information from the resources directory
Ero Carrera (ero) <erocarreragmailcom> Thursday, February 22 2007 14:10.00 CST


A while ago I got some inquiries on how to go about reading the version information stored in PE files.

I had an idea of it being just a bunch of unicode strings without much of a structure but to follow along the rest of the PE file format, it does indeed have some structure. The only inconvenient was to find proper resources on how to parse it as Microsofts docs mainly amount to, understandably, "just use the API". I eventually found a couple of references where a parser for the version information stored with a Portable Executables resources directory was implemented.

After finally understanding how that information was stored, I added support in pefile so now a dictionary is conveniently returned whenever parseable version information exists in a PE file.

Some of the links in which I based my parsing implementation are:



From those last two links one can follow into definitions for the other structures.

Now, before I forget how this all goes. The version info structure in composed of a list of substructures. Those substructures can be of StringFileInfo or VarFileInfo type. The former contains the usual textual information that can be seen on the Version tab on the Properties dialog for a PE image. The later specifies version information in a way that does not depend on the language and codepage.



StringFileInfo contains a list of StringTable structures and each of those contains a String structure. This last structure contains the Key, Value pairs that make for the textual version information.
VarFileInfo contains a list of Var structures (although normally is only one) and each of those contains a list of pairs of Word values with version information.

  • VS_VERSIONINFO(VS_FIXEDFILEINFO)
    • StringFileInfo
      • StringTable (LangID)
        • String
    • VarFileInfo
      • Var
        • WORD, WORD


Example

If the file has version information, the following attributes will exist in the PE instance returned.

  • VS_VERSIONINFO will contain the first three fields of the main structure: Length, ValueLength, and Type

  • VS_FIXEDFILEINFO will hold the rest of the fields, accessible as sub-attributes: Signature, StrucVersion, FileVersionMS, FileVersionLS,
    ProductVersionMS, ProductVersionLS, FileFlagsMask, FileFlags, FileOS, FileType, FileSubtype, FileDateMS, FileDateLS

  • FileInfo is a list of all StringFileInfo and VarFileInfo structures.

  • StringFileInfo structures will have a list as an attribute named StringTable containing all the StringTable structures. Each of those structures contains a  dictionary entries with all the key/value version information string pairs.

  • VarFileInfo structures will have a list as an attribute named Var containing all Var structures. Each Var structure will have a dictionary as an attribute named entry which will contain the name and value of the Var.


print hex(pe.VS_VERSIONINFO.Length)
print hex(pe.VS_VERSIONINFO.Type)
print hex(pe.VS_VERSIONINFO.ValueLength)

print hex(pe.VS_FIXEDFILEINFO.Signature)
print hex(pe.VS_FIXEDFILEINFO.FileFlags)
print hex(pe.VS_FIXEDFILEINFO.FileOS)


for fileinfo in pe.FileInfo:
  
  if fileinfo.Key == StringFileInfo:
    for st in fileinfo.StringTable:
      for entry in st.entries.items():
        print %s: %s % (entry[0], entry[1])

  if fileinfo.Key == VarFileInfo:
    for var in fileinfo.Var:
      print %s: %s % var.entry.items()[0]


0x35c
0x0
0x34

0xfeef04bdL
0x0
0x4

LegalCopyright: Mozilla Corporation
InternalName: Firefox
FileVersion: 1.8.1: 2006101023
CompanyName: Mozilla Corporation
LegalTrademarks: Firefox is a Trademark of The Mozilla Foundation.
Comments:
ProductName: Firefox
ProductVersion: 2.0
FileDescription: Firefox
OriginalFilename: firefox.exe

Translation: 0x0000 0x04b0


This should come quite handy, for instance, to people interested in creating databases of version information of collections of DLLs and EXEs...

Comments
Posted: Wednesday, December 31 1969 18:00.00 CST