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
(self, version_struct)
| 4495 | return resource |
| 4496 | |
| 4497 | def parse_version_information(self, version_struct): |
| 4498 | """Parse version information structure. |
| 4499 | |
| 4500 | The date will be made available in three attributes of the PE object. |
| 4501 | |
| 4502 | VS_VERSIONINFO will contain the first three fields of the main structure: |
| 4503 | 'Length', 'ValueLength', and 'Type' |
| 4504 | |
| 4505 | VS_FIXEDFILEINFO will hold the rest of the fields, accessible as sub-attributes: |
| 4506 | 'Signature', 'StrucVersion', 'FileVersionMS', 'FileVersionLS', |
| 4507 | 'ProductVersionMS', 'ProductVersionLS', 'FileFlagsMask', 'FileFlags', |
| 4508 | 'FileOS', 'FileType', 'FileSubtype', 'FileDateMS', 'FileDateLS' |
| 4509 | |
| 4510 | FileInfo is a list of all StringFileInfo and VarFileInfo structures. |
| 4511 | |
| 4512 | StringFileInfo structures will have a list as an attribute named 'StringTable' |
| 4513 | containing all the StringTable structures. Each of those structures contains a |
| 4514 | dictionary 'entries' with all the key / value version information string pairs. |
| 4515 | |
| 4516 | VarFileInfo structures will have a list as an attribute named 'Var' containing |
| 4517 | all Var structures. Each Var structure will have a dictionary as an attribute |
| 4518 | named 'entry' which will contain the name and value of the Var. |
| 4519 | """ |
| 4520 | |
| 4521 | # Retrieve the data for the version info resource |
| 4522 | # |
| 4523 | try: |
| 4524 | start_offset = self.get_offset_from_rva(version_struct.OffsetToData) |
| 4525 | except PEFormatError: |
| 4526 | self.__warnings.append( |
| 4527 | "Error parsing the version information, " |
| 4528 | "attempting to read OffsetToData with RVA: 0x{:x}".format( |
| 4529 | version_struct.OffsetToData |
| 4530 | ) |
| 4531 | ) |
| 4532 | return |
| 4533 | raw_data = self.__data__[start_offset : start_offset + version_struct.Size] |
| 4534 | |
| 4535 | # Map the main structure and the subsequent string |
| 4536 | # |
| 4537 | versioninfo_struct = self.__unpack_data__( |
| 4538 | self.__VS_VERSIONINFO_format__, raw_data, file_offset=start_offset |
| 4539 | ) |
| 4540 | |
| 4541 | if versioninfo_struct is None: |
| 4542 | return |
| 4543 | |
| 4544 | ustr_offset = version_struct.OffsetToData + versioninfo_struct.sizeof() |
| 4545 | section = self.get_section_by_rva(ustr_offset) |
| 4546 | section_end = None |
| 4547 | if section: |
| 4548 | section_end = section.VirtualAddress + max( |
| 4549 | section.SizeOfRawData, section.Misc_VirtualSize |
| 4550 | ) |
| 4551 | |
| 4552 | versioninfo_string = None |
| 4553 | # These should return 'ascii' decoded data. For the case when it's |
| 4554 | # garbled data the ascii string will retain the byte values while |
no test coverage detected