def reverse_instances(memory_handler): """ Reverse all heaps in process from memory_handler :param memory_handler: :return: """ assert isinstance(memory_handler, interfaces.IMemoryHandler) process_context = memory_handler.get_reverse_context() #for heap in heaps: # # reverse all fields in all records from that heap # ## reverse_heap(memory_handler, heap_addr) log.info('Reversing Fields') fr = dsa.FieldReverser(memory_handler) fr.reverse() log.info('Fixing Text Fields') tfc = dsa.TextFieldCorrection(memory_handler) tfc.reverse() # try to find some logical constructs. log.info('Reversing DoubleLinkedListReverser') # why is this a reverse_context ? doublelink = reversers.DoubleLinkedListReverser(memory_handler) doublelink.reverse() doublelink.rename_all_lists() # then and only then can we look at the PointerFields # identify pointer relation between allocators log.info('Reversing PointerFields') pfr = pointertypes.PointerFieldReverser(memory_handler) pfr.reverse() # save that log.info('Saving reversed records instances') for heap_context in process_context.list_contextes(): heap_context.save_structures() # save to file save_headers(heap_context) log.info('Saving reversed records types') process_context.save_reversed_types() # graph pointer relations between allocators log.info('Reversing PointerGraph') ptrgraph = reversers.PointerGraphReverser(memory_handler) ptrgraph.reverse() # extract all strings log.info('Reversing strings') strout = reversers.StringsReverser(memory_handler) strout.reverse() log.info('Analysis results are in %s', config.get_cache_folder_name(memory_handler.get_name())) return process_context
def test_reversers(self): # order of resolution should be # FieldReverser # DoubleLinkedListReverser # PointerFieldReverser # TypeReverser struct_d = self._context.get_record_for_address(self.offset) sig_1 = struct_d.get_signature_text() # print '1.', self._v(struct_d) # try to find some logical constructs. doublelink = reversers.DoubleLinkedListReverser(self.memory_handler) doublelink.reverse() sig_2 = struct_d.get_signature_text() # print '2.', self._v(struct_d) # no double linked list in here self.assertEqual('', sig_2) # decode bytes contents to find basic types. fr = dsa.FieldReverser(self.memory_handler) fr.reverse() sig_3 = struct_d.get_signature_text() # print '3.', self._v(struct_d) #self.assertEqual(sig_3, 'P8P8P8z24i8z40i8z8i8z40i8z8i8z40i8z8i8z40i8z8i8z40i8z8i8z40i8z8i8z40i8z8i8z40i8z8i8z40i8z8i8z40i8z8i8z8i8z8i8z8i8z8i8z8i8z8i8z8i8z8i8z8P8P8P8P8P8P8P8P8P8P8P8P8u40P8P8P8P8P8P8P8P8P8P8i8P8T14u2z16P8z8P8z8P8z8P8z8P8z8P8z8P8z8P8z8P8z8P8z8P8z8P8z8P8z8P8z8P8z8P8z8P8z8P8z8P8z8P8z16P8') # identify pointer relation between allocators pfr = pointertypes.PointerFieldReverser(self.memory_handler) pfr.reverse() sig_4 = struct_d.get_signature_text() # print '4.', self._v(struct_d) #logging.getLogger("reversers").setLevel(logging.DEBUG) # aggregate field of same type in an array ## FIXME very very long. #afr = reversers.ArrayFieldsReverser(self._context) #afr.reverse() #sig_5 = struct_d.get_signature_text() # print '5.', self._v(struct_d) tr = signature.TypeReverser(self.memory_handler) tr.reverse() sig_6 = struct_d.get_signature_text() # print '6.', self._v(struct_d) # print "tr._similarities", tr._similarities for a, b in tr._similarities: # print self._context.get_record_for_address(a).to_string() # print self._context.get_record_for_address(b).to_string() #import code #code.interact(local=locals()) pass
def setUp(self): dumpname = 'test/src/test-ctypes6.64.dump' self.memory_handler = dump_loader.load(dumpname) process_context = self.memory_handler.get_reverse_context() process_context.create_record_cache_folder() # load TU values self._load_offsets_values(self.memory_handler.get_name()) ## self.dllr = reversers.DoubleLinkedListReverser(self.memory_handler) log.debug('Reversing Fields') fr = dsa.FieldReverser(self.memory_handler) fr.reverse()
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 test_doublelink(self): # reverse first with dsa _record = self._context.get_record_for_address(0xccd00) _record.reset() revdsa = dsa.FieldReverser(self.memory_handler) revdsa.reverse() rev = reversers.DoubleLinkedListReverser(self.memory_handler) # interesting records # SIG:T4i4P4P4i4z12 # struct_bbf78 struct_a6518 struct_cca28 # list goes from 0xccd28, 0xccd00 to 0x98268 #_record = self._context.get_record_for_address(0xccd28) _record = self._context.get_record_for_address(0xccd00) print(_record.to_string()) #_record.set_reverse_level(9) ## rev.reverse_record(self._context, _record) print(_record.to_string()) n1 = self._context.get_record_for_address(0x000ccae8) print(n1.to_string()) tail = self._context.get_record_for_address(0x98268) print(tail.to_string()) expected = [ 0xccd28, 0xccd00, 0xccae8, 0xcca50, 0xcca28, 0xcc428, 0xc6878, 0xdcbc8, 0xdcb40, 0xcd300, 0xbbf78, 0xbefd8, 0xbecd8, 0xbc560, 0xbbee0, 0xbbda8, 0xbbb38, 0xbbae0, 0xa6518, 0xb5d00, 0xb5cd8, 0xb5cb0, 0xb5b70, 0xb1aa8, 0xa20b8, 0x9e2f8, 0xa1920, 0xa1838, 0x98268 ] size_records = len(tail) # offset = 8 offset = 8 rev.rename_all_lists() self.assertEqual(rev.lists[size_records][offset][0], expected) # rename all lists for size, offset_lists in rev.lists.items(): for offset, multiple_lists in offset_lists.items(): for members_list in multiple_lists: nb = len(members_list) rt = rev.rename_record_type(members_list, offset) log.debug('%d members for : %s', nb, rt.to_string()) pass
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_reverse_heap(self): #ctx = reversers.reverse_heap(self.memory_handler, zeus_856_svchost_exe.known_heaps[0][0]) struct_d = self._context.get_record_for_address(self.offset) struct_d.reset() sig_1 = struct_d.get_signature_text() # print '1.', self._v(struct_d) #self.assertEqual(sig_1, 'P4P4P4P4P4P4P4i4z4i4i4z8P4P4z8P4i4u16z4i4z4P4P4P4P4z64P4P4P4P4P4P4P4i4z4i4i4z8P4P4z8P4i4u16z4i4z4P4P4P4P4z64P4u4z176P4u4z176P4u4z176P4u4z176P4u4z176P4u4z176P4u4z176P4u4z176P4u4z176P4u4z176P4u4z176P4u4z176P4u4z176P4u4z176P4u4z176P4u4z176P4u4z8272P4u4z176P4u4z176P4u4z176P4u4z176P4u4z176P4u4z176P4u4z176P4u4z176P4u4z176P4u4z176P4u4z176P4u4z176P4u4z176P4u4z176P4u4z176P4u4z180u4z176') # decode bytes contents to find basic types. fr = dsa.FieldReverser(self.memory_handler) fr.reverse() sig_2 = struct_d.get_signature_text() # print '2.', self._v(struct_d) # no double linked list in here #self.assertEqual(sig_2, 'P4P4P4P4P4P4P4i4z4i4i4z8P4P4z8P4i4u16z4i4z4P4P4P4P4z64P4P4P4P4P4P4P4i4z4i4i4z8P4P4z8P4i4u16z4i4z4P4P4P4P4z64P4u4z176P4u4z176P4u4z176P4u4z176P4u4z176P4u4z176P4u4z176P4u4z176P4u4z176P4u4z176P4u4z176P4u4z176P4u4z176P4u4z176P4u4z176P4u4z176P4u4z8272P4u4z176P4u4z176P4u4z176P4u4z176P4u4z176P4u4z176P4u4z176P4u4z176P4u4z176P4u4z176P4u4z176P4u4z176P4u4z176P4u4z176P4u4z176P4u4z180u4z176') # print struct_d.to_string() #import code #code.interact(local=locals()) # try to find some logical constructs. doublelink = reversers.DoubleLinkedListReverser(self.memory_handler) doublelink.reverse() #self.assertEqual(doublelink.found, 12) sig_3 = struct_d.get_signature_text() # print '3.', self._v(struct_d) #self.assertEqual(sig_3, 'P4P4P4P4P4P4P4i4z4i4i4z8P4P4z8P4i4u16z4i4z4P4P4P4P4z64P4P4P4P4P4P4P4i4z4i4i4z8P4P4z8P4i4u16z4i4z4P4P4P4P4z64P4u4z176P4u4z176P4u4z176P4u4z176P4u4z176P4u4z176P4u4z176P4u4z176P4u4z176P4u4z176P4u4z176P4u4z176P4u4z176P4u4z176P4u4z176P4u4z176P4u4z8272P4u4z176P4u4z176P4u4z176P4u4z176P4u4z176P4u4z176P4u4z176P4u4z176P4u4z176P4u4z176P4u4z176P4u4z176P4u4z176P4u4z176P4u4z176P4u4z180u4z176') # print struct_d.to_string() #import code #code.interact(local=locals()) # identify pointer relation between allocators pfr = pointertypes.PointerFieldReverser(self.memory_handler) pfr.reverse() sig_4 = struct_d.get_signature_text() # print '4.', self._v(struct_d) # print struct_d.to_string() #import code #code.interact(local=locals()) # aggregate field of same type in an array #afr = reversers.ArrayFieldsReverser(self._context) #afr.reverse() #sig_5 = struct_d.get_signature_text() # print '5.', self._v(struct_d) # print struct_d.to_string() #import code #code.interact(local=locals()) tr = signature.TypeReverser(self.memory_handler) tr.reverse() sig_6 = struct_d.get_signature_text() # print '6.', self._v(struct_d) # print "tr._similarities", tr._similarities for a, b in tr._similarities: # print self._context.get_record_for_address(a).to_string() # print self._context.get_record_for_address(b).to_string() #import code #code.interact(local=locals()) pass