def ParseOMAP(self, omap_stream_id): """Build an OMAP lookup table. The OMAP is a translation between the original symbol's offset to the final offset. When the linker builds the executable, it reorders the original object files in the executable section. This translation table tells us where the symbols end up. """ self.omap = utils.SortedCollection(key=lambda x: x[0]) omap_stream = self.root_stream_header.GetStream(omap_stream_id) if omap_stream is None: return omap_address_space = addrspace.BufferAddressSpace( session=self.session, data=omap_stream.read(0, omap_stream.size)) omap_array = self.profile.Array( vm=omap_address_space, count=omap_stream.size // self.profile.get_obj_size("_OMAP_DATA"), max_count=omap_stream.size, target="_OMAP_DATA") for i, omap in enumerate(omap_array): src = int(omap.rva) dest = int(omap.rvaTo) self.omap.insert((src, dest)) self.session.report_progress( " Extracting OMAP Information %s%%", lambda: i * 100 // omap_array.count)
def __init__(self, session=None, address_space=None): self.session = session # This is a cache of tables. We can quickly find the table responsible # for a particular chunk. self.tables = utils.SortedCollection(key=lambda x: x[0]) self._chunk_offset = 0 self.chunk_size = 32 * 1024 # 32kb * 100 = 3.2mb cache size. self.chunk_cache = utils.FastStore(max_size=100) self.address_space = address_space self.profile = EWFProfile(session=session) self.file_header = self.profile.ewf_file_header_v1( offset=0, vm=self.address_space) # Make sure the file signature is correct. if not self.file_header.EVF_sig.is_valid(): raise RuntimeError("EVF signature does not match.") # Now locate all the sections in the file. first_section = self.profile.ewf_section_descriptor_v1( vm=self.address_space, offset=self.file_header.obj_end) for section in first_section.walk_list("next"): if section.type == "header2": self.handle_header2(section) elif section.type == "header": self.handle_header(section) elif section.type in ["disk", "volume"]: self.handle_volume(section) elif section.type == "table": self.handle_table(section) # How many chunks we actually have in this file. self.size = self._chunk_offset * self.chunk_size
def _format_type(self, module, symbol, offset): """Use the type information to format the address within the struct.""" result = symbol member_obj = module.profile.get_constant_object(symbol) while offset > member_obj.obj_offset: if isinstance(member_obj, obj.Struct): members = [ getattr(member_obj, x, None) for x in member_obj.members ] member_collection = utils.SortedCollection( (x.obj_offset, x) for x in members) member_offset, member_below = ( member_collection.get_value_smaller_than(offset)) # No member below this offset? if member_offset is None: result += "+%s" % (offset - member_obj.obj_offset) break result += ".%s" % member_below.obj_name member_obj = member_below elif isinstance(member_obj, obj.Array): # Next lowest index is a whole number of items. item = member_obj[0] next_lowest_index = (offset - member_obj.obj_offset) // item.obj_size result += "[%s]" % next_lowest_index member_obj = member_obj[next_lowest_index] else: result += "+%s" % (offset - member_obj.obj_offset) break return result
def __init__(self, *args, **kwargs): super(InspectHeap, self).__init__(*args, **kwargs) self.segments = utils.SortedCollection()