class PE(object): def __init__(self, *args, **kwargs): self.pe = PEBase(*args, **kwargs) self.__dump_dict = None self.__symbols = None self.__sections = None @property def dump_dict(self): """dump_dict() cache""" if self.__dump_dict is None: self.__dump_dict = self.pe.dump_dict() return self.__dump_dict @property def symbols(self): """symbols dictionary, {name: RVA}""" # TODO: Add more symbols, not just from exports. # Maybe we should search the symbol server? if self.__symbols is None: if 'Exported symbols' in self.dump_dict: self.__symbols = { sym['Name']: sym['RVA'] for sym in self.dump_dict['Exported symbols'][1:] if sym['Name'] } else: self.__symbols = {} return self.__symbols @property def sections(self): """sections dictionary, {name: (RVA, 'RWX')}""" if self.__sections is None: def prot(flags): prot = '' if 'IMAGE_SCN_MEM_READ' in flags: prot += 'R' if 'IMAGE_SCN_MEM_WRITE' in flags: prot += 'W' if 'IMAGE_SCN_MEM_EXECUTE' in flags: prot += 'X' return prot # avoid pefile.Structure.dump_dict() messing up with strings self.__sections = {sect.Name.rstrip('\x00'): (sect_dump['VirtualAddress']['Value'], prot(sect_dump['Flags'])) \ for (sect, sect_dump) in zip(self.pe.sections, self.dump_dict['PE Sections'])} return self.__sections
__date__ = 20170815 __description__ = "Utility to extract metadata from EXE files" parser = argparse.ArgumentParser(description=__description__, epilog="Developed by {} on {}".format( ", ".join(__authors__), __date__)) parser.add_argument("EXE_FILE", help="Path to exe file") parser.add_argument("-v", "--verbose", help="Increase verbosity of output", action='store_true', default=False) args = parser.parse_args() pe = PE(args.EXE_FILE) ped = pe.dump_dict() file_info = {} for structure in pe.FileInfo: if structure.Key == b'StringFileInfo': for s_table in structure.StringTable: for key, value in s_table.entries.items(): if value is None or len(value) == 0: value = "Unknown" file_info[key] = value print("File Information: ") print("==================") for k, v in file_info.items(): if isinstance(k, bytes): k = k.decode() if isinstance(v, bytes):