From 1a775f7d5a1b931be5e72da9fce1f6bd4cf47b86 Mon Sep 17 00:00:00 2001 From: Loic Jaquemet Date: Fri, 14 Aug 2015 17:17:54 -0600 Subject: [PATCH] embeded list structure are hard to work with --- haystack/listmodel.py | 12 +++++++----- haystack/structures/win32/winheap.py | 7 ++++++- haystack/structures/win32/winxpheap.py | 11 +++++++++-- test/haystack/structures/win32/test_winxpwalker.py | 6 +++--- 4 files changed, 25 insertions(+), 11 deletions(-) diff --git a/haystack/listmodel.py b/haystack/listmodel.py index 66a0a608..c7fb7e1e 100644 --- a/haystack/listmodel.py +++ b/haystack/listmodel.py @@ -140,8 +140,8 @@ def register_single_linked_list_record_type(self, record_type, forward, sentinel :param forward: the list pointer fieldname :return: None """ - if not issubclass(record_type, ctypes.Structure): - raise TypeError('Feed me a ctypes.Structure') + if not issubclass(record_type, ctypes.Structure) and not issubclass(record_type, ctypes.Union): + raise TypeError('Feed me a ctypes record rype') # test field existences in instance flink_type = getattr(record_type, forward) # test field existences in type @@ -189,8 +189,8 @@ def register_double_linked_list_record_type(self, record_type, forward, backward :param backward: the backward pointer :return: None """ - if not issubclass(record_type, ctypes.Structure): - raise TypeError('Feed me a ctypes.Structure') + if not issubclass(record_type, ctypes.Structure) and not issubclass(record_type, ctypes.Union): + raise TypeError('Feed me a ctypes record rype') # test field existences in instance flink_type = getattr(record_type, forward) blink_type = getattr(record_type, backward) @@ -320,12 +320,14 @@ def _iterate_list_from_field_with_link_info(self, record, link_info): head = getattr(record, fieldname) # and its record_type field_record_type = type(head) + ## DEBUG use registration instead + ##field_record_type = pointee_record_type # check that forward and backwards link field name were registered iterator_fn = None if self.is_single_linked_list_type(field_record_type): iterator_fn = self._iterate_single_linked_list # stop at the first sign of a previously found list entry - _, _, sentinels = self.get_single_linked_list_type(type(head)) + _,sentinels = self.get_single_linked_list_type(type(head)) elif self.is_double_linked_list_type(field_record_type): iterator_fn = self._iterate_double_linked_list # stop at the first sign of a previously found list entry diff --git a/haystack/structures/win32/winheap.py b/haystack/structures/win32/winheap.py index ec77df96..72f99588 100644 --- a/haystack/structures/win32/winheap.py +++ b/haystack/structures/win32/winheap.py @@ -172,8 +172,13 @@ def HEAP_get_frontend_chunks(self, record): st = m.read_struct(addr, self.win_heap.HEAP_LOOKASIDE) # load members on self.FrontEndHeap car c'est un void * #for free in st.iterateList('ListHead'): # single link list. - for free in self.iterate_list_from_field(st, 'ListHead'): + #for free in self.iterate_list_from_field(st, 'ListHead'): + listHead = st.ListHead._1 + listHead._orig_address_ = addr + for free in self.iterate_list_from_field(listHead, 'Next'): # TODO delete this free from the heap-segment entries chunks + # is that supposed to be a FREE_ENTRY ? + # or a struct__HEAP_LOOKASIDE ? log.debug('free') res.append(free) # ??? pass diff --git a/haystack/structures/win32/winxpheap.py b/haystack/structures/win32/winxpheap.py index 573a8790..f7533afb 100644 --- a/haystack/structures/win32/winxpheap.py +++ b/haystack/structures/win32/winxpheap.py @@ -60,7 +60,7 @@ def __init__(self, memory_handler, my_constraints, winxpheap_module): sentinels.append(0xffffffff) self.register_double_linked_list_record_type(self.win_heap.struct__LIST_ENTRY, 'Flink', 'Blink', sentinels) # - self.register_linked_list_field_and_type(self.win_heap.HEAP, 'VirtualAllocdBlocks', self.win_heap.HEAP_VIRTUAL_ALLOC_ENTRY, 'Entry') # offset = -8 + self.register_linked_list_field_and_type(self.win_heap.HEAP, 'VirtualAllocdBlocks', self.win_heap.struct__HEAP_VIRTUAL_ALLOC_ENTRY, 'Entry') # offset = -8 # we need a single linked pointer list management @@ -76,7 +76,14 @@ def __init__(self, memory_handler, my_constraints, winxpheap_module): #class struct__SLIST_HEADER_0(ctypes.Structure): # ('Next', SINGLE_LIST_ENTRY), self.register_single_linked_list_record_type(self.win_heap.struct__SINGLE_LIST_ENTRY, 'Next') - self.register_linked_list_field_and_type(self.win_heap.struct__HEAP_LOOKASIDE, 'ListHead', self.win_heap.struct__SINGLE_LIST_ENTRY, 'Next') + #self.register_linked_list_field_and_type(self.win_heap.struct__HEAP_LOOKASIDE, 'ListHead', self.win_heap.struct__SINGLE_LIST_ENTRY, 'Next') + #self.register_single_linked_list_record_type(self.win_heap.union__SLIST_HEADER, '_1') + #self.register_single_linked_list_record_type(self.win_heap.struct__SLIST_HEADER_0, 'Next') + #self.register_linked_list_field_and_type(self.win_heap.struct__HEAP_LOOKASIDE, 'ListHead', self.win_heap.union__SLIST_HEADER, '_1') + #self.register_linked_list_field_and_type(self.win_heap.union__SLIST_HEADER, '_1', self.win_heap.struct__SLIST_HEADER_0, 'Next') + self.register_linked_list_field_and_type(self.win_heap.struct__SLIST_HEADER_0, 'Next', self.win_heap.struct__HEAP_LOOKASIDE, 'ListHead') + # what the fuck is pointed record type of listHead ? + #self.register_linked_list_field_and_type(self.win_heap.struct__SINGLE_LIST_ENTRY, 'Next', self.win_heap.struct__SINGLE_LIST_ENTRY, 'Next') return diff --git a/test/haystack/structures/win32/test_winxpwalker.py b/test/haystack/structures/win32/test_winxpwalker.py index 2abfa6b0..0691e50e 100644 --- a/test/haystack/structures/win32/test_winxpwalker.py +++ b/test/haystack/structures/win32/test_winxpwalker.py @@ -263,7 +263,7 @@ def test_totalsize(self): #self.skipTest('overallocation clearly not working') - self.assertEquals(self._memory_handler.get_target_platform(), 'win32') + self.assertEquals(self._memory_handler.get_target_platform().get_os_name(), 'winxp') full = list() for heap in self._memory_handler.get_heaps(): @@ -464,8 +464,8 @@ def test_is_heap(self): self.assertTrue(self._heap_finder._is_heap(m)) if __name__ == '__main__': - # logging.basicConfig(stream=sys.stderr, level=logging.INFO) - logging.basicConfig(stream=sys.stderr, level=logging.DEBUG) + logging.basicConfig(stream=sys.stderr, level=logging.INFO) + # logging.basicConfig(stream=sys.stderr, level=logging.DEBUG) # logging.getLogger('testwalker').setLevel(level=logging.DEBUG) # logging.getLogger('winxpheapwalker').setLevel(level=logging.DEBUG) # logging.getLogger('win7heap').setLevel(level=logging.DEBUG)