parameters: (self, version_struct)
docstring: Parse version information structure.
          
          The date will be made available in three attributes of the PE object.
          
          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.
docstring_summary: Parse version information structure.
          
          The date will be made available in three attributes of the PE object.
          
          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.
docstring_tokens: Parse version information structure . The date will be made available in three attributes of the PE object . 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 .
function: def parse_version_information(self, version_struct):
          """Parse version information structure.
          
          The date will be made available in three attributes of the PE object.
          
          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.
          """
      
      
          # Retrieve the data for the version info resource
          #
          start_offset = self.get_offset_from_rva( version_struct.OffsetToData )
          raw_data = self.__data__[ start_offset : start_offset+version_struct.Size ]
          
          
          # Map the main structure and the subsequent string
          #    
          versioninfo_struct = self.__unpack_data__(
              self.__VS_VERSIONINFO_format__, raw_data, 
              file_offset = start_offset )
              
          if versioninfo_struct is None:
              return 
              
          ustr_offset = version_struct.OffsetToData + versioninfo_struct.sizeof()
          try:
              versioninfo_string = self.get_string_u_at_rva( ustr_offset )
          except PEFormatError, excp:
              self.__warnings.append(
                  'Error parsing the version information, ' +
                  'attempting to read VS_VERSION_INFO string. Can\'t ' +
                  'read unicode string at offset 0x%x' % (
                  ustr_offset ) )
                  
              versioninfo_string = None
           
          # If the structure does not contain the expected name, it's assumed to be invalid
          #            
          if versioninfo_string != u'VS_VERSION_INFO':
  
              self.__warnings.append('Invalid VS_VERSION_INFO block')
              return
  
  
          # Set the PE object's VS_VERSIONINFO to this one
          #
          self.VS_VERSIONINFO = versioninfo_struct
  
          # The the Key attribute to point to the unicode string identifying the structure
          #        
          self.VS_VERSIONINFO.Key = versioninfo_string
  
  
          # Process the fixed version information, get the offset and structure
          #
          fixedfileinfo_offset = self.dword_align(
              versioninfo_struct.sizeof() + 2 * (len(versioninfo_string) + 1),
              version_struct.OffsetToData)
          fixedfileinfo_struct = self.__unpack_data__(
              self.__VS_FIXEDFILEINFO_format__,
              raw_data[fixedfileinfo_offset:], 
              file_offset = start_offset+fixedfileinfo_offset )
  
          if not fixedfileinfo_struct:
              return
  
  
          # Set the PE object's VS_FIXEDFILEINFO to this one
          #
          self.VS_FIXEDFILEINFO = fixedfileinfo_struct
          
          
          # Start parsing all the StringFileInfo and VarFileInfo structures
          #
          
          # Get the first one
          #
          stringfileinfo_offset = self.dword_align(
              fixedfileinfo_offset + fixedfileinfo_struct.sizeof(),
              version_struct.OffsetToData)
          original_stringfileinfo_offset = stringfileinfo_offset
          
          
          # Set the PE object's attribute that will contain them all.
          #
          self.FileInfo = list()
  
  
          while True:
          
              # Process the StringFileInfo/VarFileInfo struct
              #
              stringfileinfo_struct = self.__unpack_data__(
                  self.__StringFileInfo_format__, 
                  raw_data[stringfileinfo_offset:], 
                  file_offset = start_offset+stringfileinfo_offset )
                  
              if stringfileinfo_struct is None:
                  self.__warnings.append(
                      'Error parsing StringFileInfo/VarFileInfo struct' )
                  return None
              
              # Get the subsequent string defining the structure.
              #
              ustr_offset = ( version_struct.OffsetToData + 
                  stringfileinfo_offset + versioninfo_struct.sizeof() )
              try:
                  stringfileinfo_string = self.get_string_u_at_rva( ustr_offset )
              except PEFormatError, excp:
                  self.__warnings.append(
                      'Error parsing the version information, ' +
                      'attempting to read StringFileInfo string. Can\'t ' +
                      'read unicode string at offset 0x%x' %  ( ustr_offset ) )
                  break
          
              # Set such string as the Key attribute
              #
              stringfileinfo_struct.Key = stringfileinfo_string
              
              
              # Append the structure to the PE object's list
              #
              self.FileInfo.append(stringfileinfo_struct)
          
          
              # Parse a StringFileInfo entry
              #
              if stringfileinfo_string == u'StringFileInfo':
                  
                  if stringfileinfo_struct.Type == 1 and stringfileinfo_struct.ValueLength == 0:
              
                      stringtable_offset = self.dword_align(
                          stringfileinfo_offset + stringfileinfo_struct.sizeof() + 
                              2*(len(stringfileinfo_string)+1),
                          version_struct.OffsetToData)
                    
                      stringfileinfo_struct.StringTable = list()
  
                      # Process the String Table entries
                      #
                      while True:
                          stringtable_struct = self.__unpack_data__(
                              self.__StringTable_format__,
                              raw_data[stringtable_offset:], 
                              file_offset = start_offset+stringtable_offset )
                              
                          if not stringtable_struct:
                              break
                              
                          ustr_offset = ( version_struct.OffsetToData + stringtable_offset + 
                              stringtable_struct.sizeof() )
                          try:
                              stringtable_string = self.get_string_u_at_rva( ustr_offset )
                          except PEFormatError, excp:
                              self.__warnings.append(
                                  'Error parsing the version information, ' +
                                  'attempting to read StringTable string. Can\'t ' +
                                  'read unicode string at offset 0x%x' % ( ustr_offset ) )
                              break
                          
                          stringtable_struct.LangID = stringtable_string
                          stringtable_struct.entries = dict()
                          stringtable_struct.entries_offsets = dict()
                          stringtable_struct.entries_lengths = dict()
                          stringfileinfo_struct.StringTable.append(stringtable_struct)
              
                          entry_offset = self.dword_align(
                              stringtable_offset + stringtable_struct.sizeof() +
                                  2*(len(stringtable_string)+1),
                              version_struct.OffsetToData)
              
                          # Process all entries in the string table
                          #
              
                          while entry_offset < stringtable_offset + stringtable_struct.Length:
                      
                              string_struct = self.__unpack_data__(
                                  self.__String_format__, raw_data[entry_offset:], 
                                  file_offset = start_offset+entry_offset )
                                  
                              if not string_struct:
                                  break
                                  
                              ustr_offset = ( version_struct.OffsetToData + entry_offset +
                                  string_struct.sizeof() )
                              try:
                                  key = self.get_string_u_at_rva( ustr_offset )
                                  key_offset = self.get_offset_from_rva( ustr_offset )
                              except PEFormatError, excp:
                                  self.__warnings.append(
                                      'Error parsing the version information, ' +
                                      'attempting to read StringTable Key string. Can\'t ' +
                                      'read unicode string at offset 0x%x' % ( ustr_offset ) )
                                  break
                                  
                              value_offset = self.dword_align(
                                  2*(len(key)+1) + entry_offset + string_struct.sizeof(),
                                  version_struct.OffsetToData)
              
                              ustr_offset = version_struct.OffsetToData + value_offset
                              try:
                                  value = self.get_string_u_at_rva( ustr_offset,
                                      max_length = string_struct.ValueLength )
                                  value_offset = self.get_offset_from_rva( ustr_offset )
                              except PEFormatError, excp:
                                  self.__warnings.append(
                                      'Error parsing the version information, ' +
                                      'attempting to read StringTable Value string. ' +
                                      'Can\'t read unicode string at offset 0x%x' % (
                                      ustr_offset ) )
                                  break
                                  
                              if string_struct.Length == 0:
                                  entry_offset = stringtable_offset + stringtable_struct.Length
                              else:
                                  entry_offset = self.dword_align(
                                      string_struct.Length+entry_offset, version_struct.OffsetToData)
                                  
                              key_as_char = []
                              for c in key:
                                  if ord(c)>128:
                                      key_as_char.append('\\x%02x' %ord(c))
                                  else:
                                      key_as_char.append(c)
                              
                              key_as_char = ''.join(key_as_char)
  
                              setattr(stringtable_struct, key_as_char, value)
                              stringtable_struct.entries[key] = value
                              stringtable_struct.entries_offsets[key] = (key_offset, value_offset)
                              stringtable_struct.entries_lengths[key] = (len(key), len(value))
                              
                      
                          stringtable_offset = self.dword_align(
                              stringtable_struct.Length + stringtable_offset,
                              version_struct.OffsetToData)
                          if stringtable_offset >= stringfileinfo_struct.Length:
                              break
                      
              # Parse a VarFileInfo entry
              #
              elif stringfileinfo_string == u'VarFileInfo':
              
                  varfileinfo_struct = stringfileinfo_struct
                  varfileinfo_struct.name = 'VarFileInfo'
              
                  if varfileinfo_struct.Type == 1 and varfileinfo_struct.ValueLength == 0:
                
                      var_offset = self.dword_align(
                          stringfileinfo_offset + varfileinfo_struct.sizeof() +
                              2*(len(stringfileinfo_string)+1),
                          version_struct.OffsetToData)
                          
                      varfileinfo_struct.Var = list()
                
                      # Process all entries
                      #
  
                      while True:
                          var_struct = self.__unpack_data__(
                              self.__Var_format__,
                              raw_data[var_offset:], 
                              file_offset = start_offset+var_offset )
                              
                          if not var_struct:
                              break
                              
                          ustr_offset = ( version_struct.OffsetToData + var_offset + 
                              var_struct.sizeof() )
                          try:
                              var_string = self.get_string_u_at_rva( ustr_offset )
                          except PEFormatError, excp:
                              self.__warnings.append(
                                  'Error parsing the version information, ' +
                                  'attempting to read VarFileInfo Var string. ' +
                                  'Can\'t read unicode string at offset 0x%x' % (ustr_offset))
                              break
  
                          
                          varfileinfo_struct.Var.append(var_struct)
                  
                          varword_offset = self.dword_align(
                              2*(len(var_string)+1) + var_offset + var_struct.sizeof(),
                              version_struct.OffsetToData)
                          orig_varword_offset = varword_offset
                              
                          while varword_offset < orig_varword_offset + var_struct.ValueLength:
                              word1 = self.get_word_from_data(
                                  raw_data[varword_offset:varword_offset+2], 0)
                              word2 = self.get_word_from_data(
                                  raw_data[varword_offset+2:varword_offset+4], 0)
                              varword_offset += 4
          
                              var_struct.entry = {var_string: '0x%04x 0x%04x' % (word1, word2)}
  
                          var_offset = self.dword_align(
                              var_offset+var_struct.Length, version_struct.OffsetToData)
                              
                          if var_offset <= var_offset+var_struct.Length:
                              break
                
                
                
              # Increment and align the offset
              #
              stringfileinfo_offset = self.dword_align(
                  stringfileinfo_struct.Length+stringfileinfo_offset,
                  version_struct.OffsetToData)
            
              # Check if all the StringFileInfo and VarFileInfo items have been processed
              #
              if stringfileinfo_struct.Length == 0 or stringfileinfo_offset >= versioninfo_struct.Length:
                  break
function_tokens: def parse_version_information ( self , version_struct ) : # Retrieve the data for the version info resource # start_offset = self . get_offset_from_rva ( version_struct . OffsetToData ) raw_data = self . __data__ [ start_offset : start_offset + version_struct . Size ] # Map the main structure and the subsequent string #     versioninfo_struct = self . __unpack_data__ ( self . __VS_VERSIONINFO_format__ , raw_data , file_offset = start_offset ) if versioninfo_struct is None : return ustr_offset = version_struct . OffsetToData + versioninfo_struct . sizeof ( ) try : versioninfo_string = self . get_string_u_at_rva ( ustr_offset ) except PEFormatError , excp : self . __warnings . append ( 'Error parsing the version information, ' + 'attempting to read VS_VERSION_INFO string. Can\'t ' + 'read unicode string at offset 0x%x' % ( ustr_offset ) ) versioninfo_string = None # If the structure does not contain the expected name, it's assumed to be invalid #             if versioninfo_string != u'VS_VERSION_INFO' : self . __warnings . append ( 'Invalid VS_VERSION_INFO block' ) return # Set the PE object's VS_VERSIONINFO to this one # self . VS_VERSIONINFO = versioninfo_struct # The the Key attribute to point to the unicode string identifying the structure #         self . VS_VERSIONINFO . Key = versioninfo_string # Process the fixed version information, get the offset and structure # fixedfileinfo_offset = self . dword_align ( versioninfo_struct . sizeof ( ) + 2 * ( len ( versioninfo_string ) + 1 ) , version_struct . OffsetToData ) fixedfileinfo_struct = self . __unpack_data__ ( self . __VS_FIXEDFILEINFO_format__ , raw_data [ fixedfileinfo_offset : ] , file_offset = start_offset + fixedfileinfo_offset ) if not fixedfileinfo_struct : return # Set the PE object's VS_FIXEDFILEINFO to this one # self . VS_FIXEDFILEINFO = fixedfileinfo_struct # Start parsing all the StringFileInfo and VarFileInfo structures # # Get the first one # stringfileinfo_offset = self . dword_align ( fixedfileinfo_offset + fixedfileinfo_struct . sizeof ( ) , version_struct . OffsetToData ) original_stringfileinfo_offset = stringfileinfo_offset # Set the PE object's attribute that will contain them all. # self . FileInfo = list ( ) while True : # Process the StringFileInfo/VarFileInfo struct # stringfileinfo_struct = self . __unpack_data__ ( self . __StringFileInfo_format__ , raw_data [ stringfileinfo_offset : ] , file_offset = start_offset + stringfileinfo_offset ) if stringfileinfo_struct is None : self . __warnings . append ( 'Error parsing StringFileInfo/VarFileInfo struct' ) return None # Get the subsequent string defining the structure. # ustr_offset = ( version_struct . OffsetToData + stringfileinfo_offset + versioninfo_struct . sizeof ( ) ) try : stringfileinfo_string = self . get_string_u_at_rva ( ustr_offset ) except PEFormatError , excp : self . __warnings . append ( 'Error parsing the version information, ' + 'attempting to read StringFileInfo string. Can\'t ' + 'read unicode string at offset 0x%x' % ( ustr_offset ) ) break # Set such string as the Key attribute # stringfileinfo_struct . Key = stringfileinfo_string # Append the structure to the PE object's list # self . FileInfo . append ( stringfileinfo_struct ) # Parse a StringFileInfo entry # if stringfileinfo_string == u'StringFileInfo' : if stringfileinfo_struct . Type == 1 and stringfileinfo_struct . ValueLength == 0 : stringtable_offset = self . dword_align ( stringfileinfo_offset + stringfileinfo_struct . sizeof ( ) + 2 * ( len ( stringfileinfo_string ) + 1 ) , version_struct . OffsetToData ) stringfileinfo_struct . StringTable = list ( ) # Process the String Table entries # while True : stringtable_struct = self . __unpack_data__ ( self . __StringTable_format__ , raw_data [ stringtable_offset : ] , file_offset = start_offset + stringtable_offset ) if not stringtable_struct : break ustr_offset = ( version_struct . OffsetToData + stringtable_offset + stringtable_struct . sizeof ( ) ) try : stringtable_string = self . get_string_u_at_rva ( ustr_offset ) except PEFormatError , excp : self . __warnings . append ( 'Error parsing the version information, ' + 'attempting to read StringTable string. Can\'t ' + 'read unicode string at offset 0x%x' % ( ustr_offset ) ) break stringtable_struct . LangID = stringtable_string stringtable_struct . entries = dict ( ) stringtable_struct . entries_offsets = dict ( ) stringtable_struct . entries_lengths = dict ( ) stringfileinfo_struct . StringTable . append ( stringtable_struct ) entry_offset = self . dword_align ( stringtable_offset + stringtable_struct . sizeof ( ) + 2 * ( len ( stringtable_string ) + 1 ) , version_struct . OffsetToData ) # Process all entries in the string table # while entry_offset < stringtable_offset + stringtable_struct . Length : string_struct = self . __unpack_data__ ( self . __String_format__ , raw_data [ entry_offset : ] , file_offset = start_offset + entry_offset ) if not string_struct : break ustr_offset = ( version_struct . OffsetToData + entry_offset + string_struct . sizeof ( ) ) try : key = self . get_string_u_at_rva ( ustr_offset ) key_offset = self . get_offset_from_rva ( ustr_offset ) except PEFormatError , excp : self . __warnings . append ( 'Error parsing the version information, ' + 'attempting to read StringTable Key string. Can\'t ' + 'read unicode string at offset 0x%x' % ( ustr_offset ) ) break value_offset = self . dword_align ( 2 * ( len ( key ) + 1 ) + entry_offset + string_struct . sizeof ( ) , version_struct . OffsetToData ) ustr_offset = version_struct . OffsetToData + value_offset try : value = self . get_string_u_at_rva ( ustr_offset , max_length = string_struct . ValueLength ) value_offset = self . get_offset_from_rva ( ustr_offset ) except PEFormatError , excp : self . __warnings . append ( 'Error parsing the version information, ' + 'attempting to read StringTable Value string. ' + 'Can\'t read unicode string at offset 0x%x' % ( ustr_offset ) ) break if string_struct . Length == 0 : entry_offset = stringtable_offset + stringtable_struct . Length else : entry_offset = self . dword_align ( string_struct . Length + entry_offset , version_struct . OffsetToData ) key_as_char = [ ] for c in key : if ord ( c ) > 128 : key_as_char . append ( '\\x%02x' % ord ( c ) ) else : key_as_char . append ( c ) key_as_char = '' . join ( key_as_char ) setattr ( stringtable_struct , key_as_char , value ) stringtable_struct . entries [ key ] = value stringtable_struct . entries_offsets [ key ] = ( key_offset , value_offset ) stringtable_struct . entries_lengths [ key ] = ( len ( key ) , len ( value ) ) stringtable_offset = self . dword_align ( stringtable_struct . Length + stringtable_offset , version_struct . OffsetToData ) if stringtable_offset >= stringfileinfo_struct . Length : break # Parse a VarFileInfo entry # elif stringfileinfo_string == u'VarFileInfo' : varfileinfo_struct = stringfileinfo_struct varfileinfo_struct . name = 'VarFileInfo' if varfileinfo_struct . Type == 1 and varfileinfo_struct . ValueLength == 0 : var_offset = self . dword_align ( stringfileinfo_offset + varfileinfo_struct . sizeof ( ) + 2 * ( len ( stringfileinfo_string ) + 1 ) , version_struct . OffsetToData ) varfileinfo_struct . Var = list ( ) # Process all entries # while True : var_struct = self . __unpack_data__ ( self . __Var_format__ , raw_data [ var_offset : ] , file_offset = start_offset + var_offset ) if not var_struct : break ustr_offset = ( version_struct . OffsetToData + var_offset + var_struct . sizeof ( ) ) try : var_string = self . get_string_u_at_rva ( ustr_offset ) except PEFormatError , excp : self . __warnings . append ( 'Error parsing the version information, ' + 'attempting to read VarFileInfo Var string. ' + 'Can\'t read unicode string at offset 0x%x' % ( ustr_offset ) ) break varfileinfo_struct . Var . append ( var_struct ) varword_offset = self . dword_align ( 2 * ( len ( var_string ) + 1 ) + var_offset + var_struct . sizeof ( ) , version_struct . OffsetToData ) orig_varword_offset = varword_offset while varword_offset < orig_varword_offset + var_struct . ValueLength : word1 = self . get_word_from_data ( raw_data [ varword_offset : varword_offset + 2 ] , 0 ) word2 = self . get_word_from_data ( raw_data [ varword_offset + 2 : varword_offset + 4 ] , 0 ) varword_offset += 4 var_struct . entry = { var_string : '0x%04x 0x%04x' % ( word1 , word2 ) } var_offset = self . dword_align ( var_offset + var_struct . Length , version_struct . OffsetToData ) if var_offset <= var_offset + var_struct . Length : break # Increment and align the offset # stringfileinfo_offset = self . dword_align ( stringfileinfo_struct . Length + stringfileinfo_offset , version_struct . OffsetToData ) # Check if all the StringFileInfo and VarFileInfo items have been processed # if stringfileinfo_struct . Length == 0 or stringfileinfo_offset >= versioninfo_struct . Length : break