def test_get_context(self): # FIXME, move to reverser # print ''.join(['%s\n'%(m) for m in _memory_handler]) with self.assertRaises(ValueError): context.get_context_for_address(self.memory_handler, 0x0) with self.assertRaises(ValueError): context.get_context_for_address(self.memory_handler, 0xb76e12d3) # [heap] heap_address = context.get_context_for_address(self.memory_handler, 0xb84e02d3)._heap_start self.assertEquals(heap_address, self.memory_handler.get_mapping_for_address(0xb84e02d3).start)
def test_get_context(self): # FIXME, move to reverser # print ''.join(['%s\n'%(m) for m in _memory_handler]) with self.assertRaises(ValueError): context.get_context_for_address(self.memory_handler, 0x0) with self.assertRaises(ValueError): context.get_context_for_address(self.memory_handler, 0xb76e12d3) # [heap] self.assertEquals( context.get_context_for_address(self.memory_handler, 0xb84e02d3).heap, self.memory_handler.get_mapping_for_address(0xb84e02d3))
def reverse_record(self, heap_context, _record): ptr_value = _record.address # targets = set(( '%x'%ptr_value, '%x'%child.target_struct_addr ) # for child in struct.getPointerFields()) #target_struct_addr # target_struct_addr pointer_fields = [f for f in _record.get_fields() if f.is_pointer()] for f in pointer_fields: pointee_addr = f._child_addr # we always feed these two self._graph.add_edge(hex(_record.address), hex(pointee_addr)) self._master_graph.add_edge(hex(_record.address), hex(pointee_addr)) # but we only feed the heaps graph if the target is known heap = self._memory_handler.get_mapping_for_address(pointee_addr) try: heap_context = context.get_context_for_address( self._memory_handler, pointee_addr) except ValueError as e: continue #heap_context = self._memory_handler.get_reverse_context().get_context_for_heap(heap) if heap_context is None: continue try: pointee = heap_context.get_record_at_address(pointee_addr) except IndexError as e: continue except ValueError as e: continue self._heaps_graph.add_edge(hex(_record.address), hex(pointee_addr)) return
def reverse_record(self, heap_context, _record): ptr_value = _record.address # targets = set(( '%x'%ptr_value, '%x'%child.target_struct_addr ) # for child in struct.getPointerFields()) #target_struct_addr # target_struct_addr pointer_fields = [f for f in _record.get_fields() if f.is_pointer()] for f in pointer_fields: pointee_addr = f._child_addr # we always feed these two self._graph.add_edge(hex(_record.address), hex(pointee_addr)) self._master_graph.add_edge(hex(_record.address), hex(pointee_addr)) # but we only feed the heaps graph if the target is known heap = self._memory_handler.get_mapping_for_address(pointee_addr) try: heap_context = context.get_context_for_address(self._memory_handler, pointee_addr) except ValueError as e: continue #heap_context = self._memory_handler.get_reverse_context().get_context_for_heap(heap) if heap_context is None: continue try: pointee = heap_context.get_record_at_address(pointee_addr) except IndexError as e: continue except ValueError as e: continue self._heaps_graph.add_edge(hex(_record.address), hex(pointee_addr)) return
def setUpClass(cls): # context.get_context('test/src/test-ctypes3.dump') cls.context = None cls.memory_handler = dump_loader.load(putty_7124_win7.dumpname) cls.putty7124 = context.get_context_for_address(cls.memory_handler, putty_7124_win7.known_heaps[0][0]) cls.dsa = dsa.FieldReverser(cls.putty7124.memory_handler) cls.memory_handler = cls.putty7124.memory_handler
def setUpClass(cls): cls.dumpname = zeus_856_svchost_exe.dumpname #config.remove_cache_folder(cls.dumpname) cls.memory_handler = dump_loader.load(zeus_856_svchost_exe.dumpname) ## cls.offset = zeus_856_svchost_exe.known_records[0][0] cls._context = context.get_context_for_address(cls.memory_handler, cls.offset) return
def _iterate_contexts(self): """ Override to change the list of contexts """ # for ctx in self._memory_handler.get_cached_context(): finder = self._memory_handler.get_heap_finder() heaps = finder.get_heap_mappings() # we need to get then either from memory_handler or from file or from scratch for heap in heaps: ctx = context.get_context_for_address(self._memory_handler, heap.get_marked_heap_address()) yield ctx
def _iterate_contexts(self): """ Override to change the list of contexts """ # for ctx in self._memory_handler.get_cached_context(): finder = self._memory_handler.get_heap_finder() walkers = finder.list_heap_walkers() # we need to get then either from memory_handler or from file or from scratch for heap_walker in walkers: ctx = context.get_context_for_address(self._memory_handler, heap_walker.get_heap_address()) yield ctx
def setUp(self): # os.chdir() self.memory_handler = dump_loader.load('test/src/test-ctypes3.32.dump') self._load_offsets_values(self.memory_handler.get_name()) finder = self.memory_handler.get_heap_finder() walkers = finder.list_heap_walkers() self.context = context.get_context_for_address(self.memory_handler, walkers[0]) ## self.dsa = dsa.FieldReverser(self.memory_handler)
def setUpClass(cls): cls.dumpname = zeus_856_svchost_exe.dumpname #config.remove_cache_folder(cls.dumpname) cls.memory_handler = folder.load(zeus_856_svchost_exe.dumpname) ## cls.offset = zeus_856_svchost_exe.known_records[0][0] cls._context = context.get_context_for_address(cls.memory_handler, cls.offset) return
def get_record_at_address(memory_handler, record_address): """ Returns the record athe specified address. :param memory_handler: :param record_address: :return: """ heap_context = context.get_context_for_address(memory_handler, record_address) return heap_context.get_record_at_address(record_address)
def setUpClass(cls): cls.dumpname = zeus_856_svchost_exe.dumpname cls.memory_handler = dump_loader.load(zeus_856_svchost_exe.dumpname) cls.process_context = cls.memory_handler.get_reverse_context() cls.process_context.create_record_cache_folder() ## cls.offset = zeus_856_svchost_exe.known_records[0][0] cls._context = context.get_context_for_address(cls.memory_handler, cls.offset) api.reverse_instances(cls.memory_handler) return
def setUp(self): # os.chdir() self.memory_handler = folder.load('test/src/test-ctypes3.32.dump') self._load_offsets_values(self.memory_handler.get_name()) finder = self.memory_handler.get_heap_finder() walkers = finder.list_heap_walkers() self.context = context.get_context_for_address(self.memory_handler, walkers[0]) ## self.dsa = dsa.FieldReverser(self.memory_handler)
def setUpClass(cls): cls.dumpname = zeus_856_svchost_exe.dumpname cls.memory_handler = folder.load(zeus_856_svchost_exe.dumpname) cls.process_context = cls.memory_handler.get_reverse_context() cls.process_context.create_record_cache_folder() ## cls.offset = zeus_856_svchost_exe.known_records[0][0] cls._context = context.get_context_for_address(cls.memory_handler, cls.offset) api.reverse_instances(cls.memory_handler) return
def setUpClass(cls): cls.dumpname = 'test/src/test-ctypes3.32.dump' config.remove_cache_folder(cls.dumpname) cls.memory_handler = dump_loader.load(cls.dumpname) finder = cls.memory_handler.get_heap_finder() heap_walker = finder.list_heap_walkers()[0] heap_addr = heap_walker.get_heap_address() cls.context = context.get_context_for_address(cls.memory_handler, heap_addr) cls.target = cls.context.memory_handler.get_target_platform() cls.dsa = dsa.FieldReverser(cls.context.memory_handler) cls.pta = pointertypes.PointerFieldReverser(cls.context.memory_handler) return
def setUpClass(cls): cls.dumpname = 'test/src/test-ctypes3.32.dump' config.remove_cache_folder(cls.dumpname) cls.memory_handler = folder.load(cls.dumpname) finder = cls.memory_handler.get_heap_finder() heap_walker = finder.list_heap_walkers()[0] heap_addr = heap_walker.get_heap_address() cls.context = context.get_context_for_address(cls.memory_handler, heap_addr) cls.target = cls.context.memory_handler.get_target_platform() cls.dsa = dsa.FieldReverser(cls.context.memory_handler) cls.pta = pointertypes.PointerFieldReverser(cls.context.memory_handler) return
def test_closestFloorValue(self): lst = numpy.asarray(range(0, 100, 10)) self.assertEquals(utils.closestFloorValue(41, lst), (40, 4)) self.assertEquals(utils.closestFloorValue(40, lst), (40, 4)) with self.assertRaises(ValueError): utils.closestFloorValue(-1, lst) memory_handler = dump_loader.load('test/src/test-ctypes3.32.dump') finder = memory_handler.get_heap_finder() heap = finder.get_heap_mappings()[0] heap_addr = heap.get_marked_heap_address() ctx = context.get_context_for_address(memory_handler, heap_addr) lst = ctx._structures_addresses
def setUpClass(cls): cls.memory_handler = folder.load(zeus_856_svchost_exe.dumpname) cls._context = context.get_context_for_address(cls.memory_handler, 0x90000) cls.process_context = cls.memory_handler.get_reverse_context() fr = dsa.FieldReverser(cls.memory_handler) fr.reverse() tfc = dsa.TextFieldCorrection(cls.memory_handler) tfc.reverse() doublelink = reversers.DoubleLinkedListReverser(cls.memory_handler) doublelink.reverse() doublelink.rename_all_lists() pfr = pointertypes.PointerFieldReverser(cls.memory_handler) pfr.reverse()
def setUp(self): self.memory_handler = dump_loader.load('test/src/test-ctypes5.64.dump') self._load_offsets_values(self.memory_handler.get_name()) sys.path.append('test/src/') self.offset = self.offsets['struct_d'][0] self.m = self.memory_handler.get_mapping_for_address(self.offset) self._context = context.get_context_for_address(self.memory_handler, self.offset) # reverse the heap if not os.access(config.get_record_cache_folder_name(self._context.dumpname), os.F_OK): os.mkdir(config.get_record_cache_folder_name(self._context.dumpname)) log.info("[+] Cache created in %s", config.get_cache_folder_name(self._context.dumpname))
def setUpClass(cls): from haystack import dump_loader cls.memory_handler = dump_loader.load(zeus_856_svchost_exe.dumpname) cls.context = context.get_context_for_address(cls.memory_handler, 0x90000) cls.target = cls.memory_handler.get_target_platform() cls.zeroes = dsa.ZeroFields(cls.memory_handler) cls.utf16 = dsa.UTF16Fields(cls.memory_handler) cls.ascii = dsa.PrintableAsciiFields(cls.memory_handler) cls.ints = dsa.IntegerFields(cls.memory_handler) # new test from real case zeus.856 @0xb2e38 cls.real = '\xc81\x0b\x00\xa8*\x0b\x00\x01\x00\x00\x00\x00\x00\x00\x00f \x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00\x00\xe0\xa9`\x9dz3\xd0\x11\xbd\x88\x00\x00\xc0\x82\xe6\x9a\xed\x03\x00\x00\x01\x00\x00\x00\xc8\xfc\xbe\x02p\x0c\x00\x00\x08\x00\x00\x00\x1d\x00\x02\x00L\xfd\xbe\x02\xd8\x91\x1b\x01\x00\x00\x00\x00\x06\x00\x00\x00\x02\x00\x00\x00\x10\x00\x00\x00\x10\x00\x00\x00\x01\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00R\x00S\x00V\x00P\x00 \x00T\x00C\x00P\x00 \x00S\x00e\x00r\x00v\x00i\x00c\x00e\x00 \x00P\x00r\x00o\x00v\x00i\x00d\x00e\x00r\x00\x00\x00f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xab\xe9\x90|\xf2\x94\x80|\x00P\xfd\x7f\x00\x00\x1c\x00\x08\x00\x00\x00\x00\x00\x00\x00t\xfc\xbe\x02\\\r\x91|\x00\x00\x1c\x00\x00\x00\xc3\x00\x00\x00\x00\x00\x88\xb0\xd2\x01\\\r\x91|\x00\x00\x1c\x00\x91\x0e\x91|\x08\x06\x1c\x00m\x05\x91|h^\xd0\x01\x00\x00\x00\x00\x08\x00\x00\x00\x00\x00\xc3\x00\x01\x00\x00\x000\x02\x1c\x00\x02\x00\x00\x00\x90\xb0\xd2\x01\x03\x00\x00\x00\x02\x00\x00\x00h^\xd0\x010\x02\x1c\x00\xd8>\xd4\x010\xf0\xfc\x00\xb8\x02\x1c\x00\xe8?\xd4\x01\xd8\x01\x1c\x00\x00\x00\x00\x00\x10\x00\x00\x00\xe8?\xd4\x01\x0c\x00\x00\x00\x05\x00\x00\x00\xf0\x06\x91|\xe0\x01\x1c\x00\x18\x00\x00\x00\xe0>\xd4\x01\x00\x00\x1c\x00\x01\x00\x00\x00\x08\x00\x00\x00\xe0\x01\x1c\x00@\x00\x00\x00\xf0?\xd4\x01\xa8\x04\x1c\x00\x00\x00\x1c\x00Om\x01\x01\x84^\xd0\x01`\x00\x00\x00\xb8\x02\x1c\x00\x00\x00\x00\x00\xd8>\xd4\x01\x88\xfc\xbe\x02F\x0f\x91|\r\x00\x00\x00\xd8>\xd4\x01\x00\x00\x1c\x00\x10<\xd4\x01\x00\x00\x00\x00\\\xfd\xbe\x02\\\r\x91|\x00\x00\x1c\x00\x91\x0e\x91|\x08\x06\x1c\x00m\x05\x91|`\xab\xf0\x00\x00\x00\x00\x00\xec<\xca\x02\x00\x00\xc3\x00\x0c\x00\x00\x00\x10<\xd4\x01\x00\x00\x00\x00\x00\x00\x00\x00\xd0\x0c\x00\x00\x00\x00\x00\x00\x18<\xd4\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd0\x0c\x00\x00(\xfd\xbe\x02\xa8\x04\x1c\x00\xd0\x0c\x00\x00@\x00\x00\x00\x03\x00\x00\x00\x18<\xd4\x01\xa8\x04\x1c\x00`\xab\xf0\x00\xc8\x02\x00\x00\xec<\xca\x02\x0c\x00\x0e\x00<V_u\x00\x00\x00\x00\xf8\xfc\xbe\x02\xec<\xca\x02\x00\x00\x00\x00`\xab\xf0\x00P\xfd\xbe\x02l\xfb\x90|q\xfb\x90|`\xab\xf0\x00\x00\x00\x00\x00\xec<\xca\x02,\xfd\xbe\x02%SystemRoot%\\system32\\rsvpsp.dll\x00\x003\x00B\x006\x004\x00B\x007\x00}\x00\x00\x00\xbe\x02\x05\x00\x00\x00\xe6-\xfd\x7f\x96\x15\x91|\xeb\x06\x91|\xa4\xfd\xbe\x02 8\xd4\x01\x10\x00\x00\x00\t\x04\x00\x00\x00\x01\x00\x00\xdc\xfa\xbe\x02\x00\x00\x00\x00\x96\x15\x91|\xeb\x06\x91|\x01\x00\x00\x00\xa4\xfd\xbe\x02\x04\x00\x00\x00\xaf\x9f\xd4w\xdc\xfa\xbe\x02\x05\x00\x00\x00\x96\x15\x91|\xeb\x06\x91|\x01\x00\x00\x00\xa4\xfd\xbe\x02\x96\x15\x91|\xeb\x06\x91|\x00\x00\x00\x00\x00\x00\x00\x00X\x00\x00\x00\xeb\x06\x91|\x01\x00\x00\x00\xa4\xfd\xbe\x02\x01\x00\x00\x00\xff\xff\xff\xff\xd8\xa2\x92w\x08\xa3\x92w\xdc\xfa\xbe\x02\xd8\xfa\xbe\x02\x02\x00\x00\x80\x9c\xfa\xbe\x02\x90\x01\x1c\x00\xb0\x01\x00\x00\xe4\xfa\xbe\x02\xff\xff\xff\xff\xe0\xfc\xbe\x02\xab\xa5\x92wh^\xd0\x01\xdc\xfa\xbe\x02\x88\x01\x1c\x00\x00\x00\xc3\x00\x01\x00\x00\x00\x96\x15\x91|\x00\x00\x00\x00' cls.test1 = structure.AnonymousRecord(cls.memory_handler, 0xb2e38, 904, prefix=None) cls.test2 = structure.AnonymousRecord(cls.memory_handler, 0xb2e38 + 636, 100, prefix=None) pass
def setUpClass(cls): #self.context3 = context.get_context('test/src/test-ctypes3.dump') cls.dumpname = 'test/src/test-ctypes6.32.dump' config.remove_cache_folder(cls.dumpname) cls.memory_handler = dump_loader.load(cls.dumpname) cls._target = cls.memory_handler.get_target_platform() finder = cls.memory_handler.get_heap_finder() heap_walker = finder.list_heap_walkers()[0] heap_addr = heap_walker.get_heap_address() cls._load_offsets_values(cls.memory_handler.get_name()) cls.context6 = context.get_context_for_address(cls.memory_handler, heap_addr) cls.dsa = dsa.FieldReverser(cls.context6.memory_handler) cls.st = cls.context6.listStructures()[0]
def reverse_record(self, heap_context, _record): ptr_value = _record.address # targets = set(( '%x'%ptr_value, '%x'%child.target_struct_addr ) # for child in struct.getPointerFields()) #target_struct_addr # target_struct_addr pointer_fields = [ f for f in _record.get_fields() if f.type.is_pointer() ] for f in pointer_fields: pointee_addr = f.value # f._child_addr # we always feed these two # TODO: if a Node is out of heap/segment, replace it by a virtual node & color representing # the foreign heap/segment self._graph.add_edge(hex(_record.address), hex(pointee_addr)) # add a colored node self._master_graph.add_edge(hex(_record.address), hex(pointee_addr)) # but we only feed the heaps graph if the target is known heap = self._memory_handler.get_mapping_for_address(pointee_addr) try: heap_context = context.get_context_for_address( self._memory_handler, pointee_addr) except ValueError as e: continue #heap_context = self._memory_handler.get_reverse_context().get_context_for_heap(heap) if heap_context is None: continue # add a heap color context_heap = hex(heap_context._heap_start) self._graph.add_node(hex(pointee_addr), heap=context_heap) self._master_graph.add_node(hex(pointee_addr), heap=context_heap) self._heaps_graph.add_node(hex(pointee_addr), heap=context_heap) try: pointee = heap_context.get_record_at_address(pointee_addr) except IndexError as e: continue except ValueError as e: continue self._heaps_graph.add_edge(hex(_record.address), hex(pointee_addr)) # add a weight self._graph.add_node(hex(pointee_addr), weight=len(_record)) self._master_graph.add_node(hex(pointee_addr), weight=len(_record)) self._heaps_graph.add_node(hex(pointee_addr), weight=len(_record)) return
def setUp(self): self.memory_handler = folder.load('test/src/test-ctypes5.64.dump') self._load_offsets_values(self.memory_handler.get_name()) sys.path.append('test/src/') self.offset = self.offsets['struct_d'][0] self.m = self.memory_handler.get_mapping_for_address(self.offset) self._context = context.get_context_for_address( self.memory_handler, self.offset) # reverse the heap if not os.access( config.get_record_cache_folder_name(self._context.dumpname), os.F_OK): os.mkdir( config.get_record_cache_folder_name(self._context.dumpname)) log.info("[+] Cache created in %s", config.get_cache_folder_name(self._context.dumpname))
def reverse_record(self, heap_context, _record): ptr_value = _record.address # targets = set(( '%x'%ptr_value, '%x'%child.target_struct_addr ) # for child in struct.getPointerFields()) #target_struct_addr # target_struct_addr pointer_fields = [f for f in _record.get_fields() if f.is_pointer()] for f in pointer_fields: pointee_addr = f._child_addr # we always feed these two # TODO: if a Node is out of heap/segment, replace it by a virtual node & color representing # the foreign heap/segment self._graph.add_edge(hex(_record.address), hex(pointee_addr)) # add a colored node self._master_graph.add_edge(hex(_record.address), hex(pointee_addr)) # but we only feed the heaps graph if the target is known heap = self._memory_handler.get_mapping_for_address(pointee_addr) try: heap_context = context.get_context_for_address(self._memory_handler, pointee_addr) except ValueError as e: continue #heap_context = self._memory_handler.get_reverse_context().get_context_for_heap(heap) if heap_context is None: continue # add a heap color context_heap = hex(heap_context._heap_start) self._graph.add_node(hex(pointee_addr), heap=context_heap) self._master_graph.add_node(hex(pointee_addr), heap=context_heap) self._heaps_graph.add_node(hex(pointee_addr), heap=context_heap) try: pointee = heap_context.get_record_at_address(pointee_addr) except IndexError as e: continue except ValueError as e: continue self._heaps_graph.add_edge(hex(_record.address), hex(pointee_addr)) # add a weight self._graph.add_node(hex(pointee_addr), weight=len(_record)) self._master_graph.add_node(hex(pointee_addr), weight=len(_record)) self._heaps_graph.add_node(hex(pointee_addr), weight=len(_record)) return
def test_get_context(self): """ :return: """ # print ''.join(['%s\n'%(m) for m in _memory_handler]) with self.assertRaises(ValueError): context.get_context_for_address(self.memory_handler, 0x0) with self.assertRaises(ValueError): context.get_context_for_address(self.memory_handler, 0xb76e12d3) #[heap] children heap_address = context.get_context_for_address(self.memory_handler, 0x0062d000)._heap_start self.assertEquals(heap_address, self.memory_handler.get_mapping_for_address(0x005c0000).start) heap_address = context.get_context_for_address(self.memory_handler, 0x0063e123)._heap_start self.assertEquals(heap_address,self.memory_handler.get_mapping_for_address(0x005c0000).start)
def reverse_heap(memory_handler, heap_addr): """ Reverse a specific heap. :param memory_handler: :param heap_addr: :return: """ from haystack.reverse import context log.info('[+] Loading the memory dump for HEAP 0x%x', heap_addr) heap_context = context.get_context_for_address(memory_handler, heap_addr) try: # decode bytes contents to find basic types. log.info('Reversing Fields') fr = dsa.FieldReverser(memory_handler) fr.reverse_context(heap_context) log.info('Fixing Text Fields') tfc = dsa.TextFieldCorrection(memory_handler) tfc.reverse_context(heap_context) # try to find some logical constructs. log.info('Reversing DoubleLinkedListReverser') # why is this a reverse_context ? doublelink = reversers.DoubleLinkedListReverser(memory_handler) doublelink.reverse_context(heap_context) doublelink.rename_all_lists() # save to file save_headers(heap_context) # etc except KeyboardInterrupt as e: # except IOError,e: log.warning(e) log.info('[+] %d structs extracted' % (heap_context.get_record_count())) raise e pass pass return heap_context
def test_get_context(self): """ :return: """ # print ''.join(['%s\n'%(m) for m in _memory_handler]) with self.assertRaises(ValueError): context.get_context_for_address(self.memory_handler, 0x0) with self.assertRaises(ValueError): context.get_context_for_address(self.memory_handler, 0xb76e12d3) #[heap] children self.assertEquals( context.get_context_for_address(self.memory_handler, 0x0062d000).heap, self.memory_handler.get_mapping_for_address(0x005c0000)) self.assertEquals( context.get_context_for_address(self.memory_handler, 0x0063e123).heap, self.memory_handler.get_mapping_for_address(0x005c0000))
def setUpClass(cls): cls.memory_handler = folder.load(zeus_856_svchost_exe.dumpname) cls._context = context.get_context_for_address(cls.memory_handler, 0x90000)
def setUpClass(cls): from haystack import dump_loader cls.memory_handler = dump_loader.load(zeus_856_svchost_exe.dumpname) cls.heap_context = context.get_context_for_address( cls.memory_handler, 0x90000) cls.target = cls.memory_handler.get_target_platform()
def reverse_record(self, _context, _record): """ @returns structure, with enriched info on pointer fields. For pointer fields value: (-) if pointer value is in _memory_handler ( well it is... otherwise it would not be a pointer.) + if value is unaligned, mark it as cheesy + ask _memory_handler for the context for that value - if context covers a data lib, it would give function names, .data , .text ( CodeContext ) - if context covers a HEAP/heap extension (one context for multiple mmap possible) it would give allocators + ask context for the target structure or code info - if retobj is structure, enrich pointer with info """ # If you want to cache resolved infos, it still should be decided by # the caller pointer_fields = [field for field in _record.get_fields() if field.is_pointer()] log.debug('got %d pointer fields', len(pointer_fields)) for field in pointer_fields: value = _record.get_value_for_field(field) field.set_pointee_addr(value) # default # FIXME field.set_resolved() # What ? # + if value is unaligned, mark it as cheesy if value % self._target.get_word_size(): field.comment = 'Unaligned pointer value' # + ask _memory_handler for the context for that value try: ctx = context.get_context_for_address(self._memory_handler, value) # no error expected. # + ask context for the target structure or code info except ValueError as e: # value is a pointer, but not to a heap. m = self._memory_handler.get_mapping_for_address(value) # field.set_child_desc('ext_lib @%0.8x %s' % (m.start, m.pathname)) field.set_pointer_to_ext_lib() field.set_pointee_ctype('void') # TODO: Function pointer ? field.name = 'ptr_ext_lib_%d' % field.offset # if value in self.__functions_pointers: # size, bbs, name = self.__functions_pointers[value] # field.name = 'func_ptr_%s_%d' % (name, field.offset) continue tgt = None try: # get enclosing structure @throws KeyError tgt = ctx.get_record_at_address(value) # there is no child structure member at pointed value. except (IndexError, ValueError) as e: log.debug('there is no child structure enclosing pointed value %0.8x - %s', value, e) field.set_pointee_desc('MemoryHandler management space') field.set_pointee_ctype('void') field.name = 'ptr_void_%d' % field.offset continue # structure found ## log.debug('Looking at child id:0x%x str:%s', tgt.address, tgt.to_string()) # we always point on structure, not field field.set_pointee_addr(tgt.address) offset = value - tgt.address try: tgt_field = tgt.get_field_at_offset(offset) # @throws IndexError except IndexError as e: # there is no field right there log.debug('there is no field at pointed value %0.8x. May need splitting byte field - %s', value, e) field.set_pointee_desc('Badly reversed field') field.set_pointee_ctype('void') field.name = 'ptr_void_%d' % field.offset continue # do not put exception for field 0. structure name should appears # anyway. field.set_pointee_desc('%s.%s' % (tgt.name, tgt_field.name)) # TODO: # do not complexify code by handling target field type, # lets start with simple structure type pointer, # later we would need to use tgt_field.ctypes depending on field # offset field.set_pointee_ctype(tgt.name) # field.name = '%s_%s_%d' % (tgt.name, tgt_field.name, field.offset) field.name = 'ptr_%s_%d' % (tgt.name, field.offset) # all _record.set_reverse_level(self._reverse_level) return
def setUpClass(cls): from haystack import dump_loader cls.memory_handler = dump_loader.load(zeus_856_svchost_exe.dumpname) cls.heap_context = context.get_context_for_address(cls.memory_handler, 0x90000) cls.target = cls.memory_handler.get_target_platform()
def reverse_record(self, _context, _record): """ @returns structure, with enriched info on pointer fields. For pointer fields value: (-) if pointer value is in _memory_handler ( well it is... otherwise it would not be a pointer.) + if value is unaligned, mark it as cheesy + ask _memory_handler for the context for that value - if context covers a data lib, it would give function names, .data , .text ( CodeContext ) - if context covers a HEAP/heap extension (one context for multiple mmap possible) it would give allocators + ask context for the target structure or code info - if retobj is structure, enrich pointer with info """ # If you want to cache resolved infos, it still should be decided by # the caller pointer_fields = [ field for field in _record.get_fields() if field.is_pointer() ] log.debug('got %d pointer fields', len(pointer_fields)) for field in pointer_fields: value = _record.get_value_for_field(field) field.set_pointee_addr(value) # default # FIXME field.set_resolved() # What ? # + if value is unaligned, mark it as cheesy if value % self._target.get_word_size(): field.comment = 'Unaligned pointer value' # + ask _memory_handler for the context for that value try: ctx = context.get_context_for_address( self._memory_handler, value) # no error expected. # + ask context for the target structure or code info except ValueError as e: # value is a pointer, but not to a heap. m = self._memory_handler.get_mapping_for_address(value) # field.set_child_desc('ext_lib @%0.8x %s' % (m.start, m.pathname)) field.set_pointer_to_ext_lib() field.set_pointee_ctype('void') # TODO: Function pointer ? field.name = 'ptr_ext_lib_%d' % field.offset # if value in self.__functions_pointers: # size, bbs, name = self.__functions_pointers[value] # field.name = 'func_ptr_%s_%d' % (name, field.offset) continue tgt = None try: # get enclosing structure @throws KeyError tgt = ctx.get_record_at_address(value) # there is no child structure member at pointed value. except (IndexError, ValueError) as e: log.debug( 'there is no child structure enclosing pointed value %0.8x - %s', value, e) field.set_pointee_desc('MemoryHandler management space') field.set_pointee_ctype('void') field.name = 'ptr_void_%d' % field.offset continue # structure found ## log.debug('Looking at child id:0x%x str:%s', tgt.address, tgt.to_string()) # we always point on structure, not field field.set_pointee_addr(tgt.address) offset = value - tgt.address try: tgt_field = tgt.get_field_at_offset( offset) # @throws IndexError except IndexError as e: # there is no field right there log.debug( 'there is no field at pointed value %0.8x. May need splitting byte field - %s', value, e) field.set_pointee_desc('Badly reversed field') field.set_pointee_ctype('void') field.name = 'ptr_void_%d' % field.offset continue # do not put exception for field 0. structure name should appears # anyway. field.set_pointee_desc('%s.%s' % (tgt.name, tgt_field.name)) # TODO: # do not complexify code by handling target field type, # lets start with simple structure type pointer, # later we would need to use tgt_field.ctypes depending on field # offset field.set_pointee_ctype(tgt.name) # field.name = '%s_%s_%d' % (tgt.name, tgt_field.name, field.offset) field.name = 'ptr_%s_%d' % (tgt.name, field.offset) # all _record.set_reverse_level(self._reverse_level) return
def setUpClass(cls): cls.memory_handler = dump_loader.load(zeus_856_svchost_exe.dumpname) cls._context = context.get_context_for_address(cls.memory_handler, 0x90000)