def parse_pe_fetch_pdb(symbol_server, file_path): ''' Attempt to fetch a symbol that relates to a PE file. The file must have a valid IMAGE_DEBUG_DIRECTORY and as well as a IMAGE_DEBUG_TYPE_CODEVIEW directroy entry. ''' try: guid = None pdb_filename = None pe = PE(file_path, fast_load=True) pe.parse_data_directories(directories=[DIRECTORY_ENTRY['IMAGE_DIRECTORY_ENTRY_DEBUG']]) code_view_entry = None for debug_entry in pe.DIRECTORY_ENTRY_DEBUG: if DEBUG_TYPE[debug_entry.struct.Type] == "IMAGE_DEBUG_TYPE_CODEVIEW": code_view_entry = debug_entry break if code_view_entry == None: logger.warn("%s doesn't have symbol information", basename(file_path)) return None, None symbol_type_offset = code_view_entry.struct.PointerToRawData symbol_type_size = code_view_entry.struct.SizeOfData symbol_type_data = pe.__data__[symbol_type_offset:symbol_type_offset+symbol_type_size] if symbol_type_data[:4] == "RSDS": rsds = CV_RSDS_HEADER.parse(symbol_type_data) guid = "%08x%04x%04x%s%x" % (rsds.GUID.Data1, rsds.GUID.Data2, rsds.GUID.Data3, rsds.GUID.Data4.encode('hex'), rsds.Age) pdb_filename = ntbasename(rsds.Filename) elif symbol_type_data[:4] == "NB10": nb10 = CV_NB10_HEADER.parse(symbol_type_data) guid = "%x%x" % (nb10.Timestamp, nb10.Age) pdb_filename = ntbasename(nb10.Filename) else: logger.error("%s unsupported symbol type", symbol_type_data[:4]) return None, None assert guid assert pdb_filename symbol = __fetch__(symbol_server, guid, file_path, pdb_filename) if symbol[:4] == 'MSCF': # TODO, unpack cabinet else: logger.error("Excpected symbol server to return a cabinet file") return None, None return symbol, basename(pdb_filename) except Exception: logger.error(format_exc()) return None, None
def path_leaf(self, path): head, tail = ntsplit(path) return os.path.splitext(tail)[0] or os.path.splitext(ntbasename(head))[0]