Skip to content

Commit

Permalink
nto working for winxp. UCRList not present
Browse files Browse the repository at this point in the history
  • Loading branch information
trolldbois committed Dec 31, 2015
1 parent 468070e commit e5356e1
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 157 deletions.
2 changes: 2 additions & 0 deletions haystack/allocators/heapwalker.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,8 @@ def _search_heap(self, mapping):
# on ly return first results in each mapping
log.debug("_search_heap in %s", mapping)
res = my_searcher._search_in(mapping, self._heap_type, nb=1, align=0x1000)
# DEBUG PEB search
#res = my_searcher._search_in(mapping, peb.struct__PEB, nb=1, align=0x1000)
if len(res) > 0:
instance, address = res[0]
mapping.mark_as_heap(address)
Expand Down
175 changes: 18 additions & 157 deletions scripts/haystack-find-heap.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,14 @@
# -*- coding: utf-8 -*-

import logging
import os
import sys
import argparse

from functools import partial

import haystack
from haystack import dump_loader
from haystack import constraints
from haystack import argparse_utils
from haystack.search import searcher
from haystack.outputters import text
#from haystack.outputters import python

# from haystack.outputters import python

"""
Search for HEAP.
Expand All @@ -23,138 +18,6 @@
log = logging.getLogger('haytack-find-heap')


class HeapFinder(object):
""" THIS IS DUPLICATE CODE WITH THE REAL HEAP FINDER.
"""

def __init__(self, memory_handler):
print 'Using %s' % self.__class__.__name__
self.memory_handler = memory_handler
pass

def _init_module_name(self, memory_handler):
raise NotImplementedError('_init_module_name')

def _init_constraints_filename(self, heap_module):
raise NotImplementedError('_init_constraints_filename')

def _init_heap_record_name(self):
raise NotImplementedError('_init_heap_record_name')

def search_heap(self):
my_model = self.memory_handler.get_model()
module_name = self._init_module_name(self.memory_handler)
# import the module with the right arch
heap_module = my_model.import_module(module_name)
log.debug('the heap module loaded is %s', module_name)
# load the constraints
constraint_filename = self._init_constraints_filename(heap_module)
parser = constraints.ConstraintsConfigHandler()
my_constraints = parser.read(constraint_filename)
my_searcher = searcher.AnyOffsetRecordSearcher(self.memory_handler,
my_constraints,
#update_cb=partial(self.print_cb, self.memory_handler)
)
## DEBUG
# DEBUG PEB search
#peb = my_model.import_module('haystack.allocators.win32.winxp_32_peb')
##DEBUG
heap_record_name = self._init_heap_record_name()
heap_struct = getattr(heap_module, heap_record_name)
# on ly return first results in each mapping
results = []
for mapping in self.memory_handler.get_mappings():
log.debug("looking at %s", mapping)
res = my_searcher._search_in(mapping, heap_struct, nb=1, align=0x1000)
# DEBUG PEB search
#res = my_searcher._search_in(mapping, peb.struct__PEB, nb=1, align=0x1000)
if res:
# FIXME output_to are stupid
#print haystack.output_to_string(memory_handler, res)
results.extend(res)

return results

def search_heap_direct(self, start_address_mapping):
my_model = self.memory_handler.get_model()
module_name = self._init_module_name(self.memory_handler)
# import the module with the right arch
heap_module = my_model.import_module(module_name)
log.debug('the heap module loaded is %s', module_name)
# load the constraints
constraint_filename = self._init_constraints_filename(heap_module)
parser = constraints.ConstraintsConfigHandler()
my_constraints = parser.read(constraint_filename)
m = self.memory_handler.get_mapping_for_address(start_address_mapping)
my_searcher = searcher.AnyOffsetRecordSearcher(self.memory_handler,
my_constraints,
[m],
#update_cb=partial(self.print_cb, self.memory_handler)
)
heap_record_name = self._init_heap_record_name()
heap_struct = getattr(heap_module, heap_record_name)
results = my_searcher._load_at(m, start_address_mapping, heap_struct, depth=5)
#print haystack.output_to_python(memory_handler, [results])[0][0].toString()
return results

def print_cb(self, memory_handler, instance, address):
"""
Callback function called by AnyOffsetRecordSearcher when an instance is found
:param memory_handler:
:param instance:
:param address:
:return:
"""
py_results = haystack.output_to_python(memory_handler, [(instance, address)])
for x, addr in py_results:
heap_not_at_start = ' '
m = memory_handler.get_mapping_for_address(addr)
if addr != m.start:
heap_not_at_start = ' (!)'
print '[+] %s' % heap_not_at_start, m
#print x
# print children
# Mark as heap for later use
m.mark_as_heap(address)
#
finder = memory_handler.get_heap_finder()
walker = finder.get_heap_walker(m)
children = walker.get_heap_children_mmaps()
if len(children) > 0:
for child in children:
print '\t[-] ', child


class Win7HeapFinder(HeapFinder):
def _init_module_name(self, memory_handler):
if 64 == memory_handler.get_target_platform().get_cpu_bits():
module_name = 'haystack.allocators.win32.win7_64'
else:
module_name = 'haystack.allocators.win32.win7_32'
return module_name

def _init_constraints_filename(self, heap_module):
return os.path.join(os.path.dirname(heap_module.__file__), 'win7heap.constraints')

def _init_heap_record_name(self):
return 'HEAP'


class WinXPHeapFinder(HeapFinder):
def _init_module_name(self, memory_handler):
if 64 == memory_handler.get_target_platform().get_cpu_bits():
module_name = 'haystack.allocators.win32.winxp_64'
else:
module_name = 'haystack.allocators.win32.winxp_32'
return module_name

def _init_constraints_filename(self, heap_module):
return os.path.join(os.path.dirname(heap_module.__file__), 'winxpheap.constraints')

def _init_heap_record_name(self):
return 'HEAP'


def count_by_mapping(memory_handler, chunksize_tuple, overhead_size):
res = {}
Expand Down Expand Up @@ -192,7 +55,7 @@ def main(argv):
parser = argparse.ArgumentParser(prog='haystack-find-heap',
description="Find heaps in a dumpfile")
parser.add_argument('--host', action='store', default='winxp', help='winxp,win7')
parser.add_argument('--verbose', '-v', action='store', help='Verbose')
parser.add_argument('--verbose', '-v', action='store_true', help='Verbose')
parser.add_argument('dumpname', type=argparse_utils.readable, help='process memory dump name')
parser.add_argument('address', nargs='?', type=argparse_utils.int16, default=None, help='Load Heap from address (hex)')

Expand All @@ -205,13 +68,6 @@ def main(argv):
from haystack.allocators.win32 import winheap
output = text.RecursiveTextOutputter(memory_handler)

if 'winxp' == opts.host:
my_finder = WinXPHeapFinder(memory_handler)
elif 'win7' == opts.host:
my_finder = Win7HeapFinder(memory_handler)
else:
raise ValueError('not such heap finder for %s' % opts.host)

my_finder = memory_handler.get_heap_finder()

# Show Target information
Expand All @@ -224,23 +80,28 @@ def main(argv):
for m in memory_handler.get_mappings():
print m

print 'Probable Process HEAPS:'
#for m in memory_handler.get_mappings():
# heap = m.my_finder._read_heap(m, m.start)
# if heap.Signature == 0xffeeffee:
# print m
print 'Probable Process HEAPS:'
for m in memory_handler.get_mappings():
for addr in range(m.start, m.end, 0x1000):
heap_not_at_start = ''
heap = my_finder._read_heap(m, addr)
# print hex(heap.Signature)
if heap.Signature == 0xeeffeeff:
if addr != m.start:
heap_not_at_start = ' (!) '
print '[+] %s@0x%0.8x' % (heap_not_at_start, addr), m

# Then show heaps
print 'Heaps and their children mapping:'
# Then show heaps
print 'Found Heaps:'

results = my_finder.search_heap()
for ctypes_heap, addr in results:
heap_not_at_start = ' '
heap_not_at_start = ''
m = memory_handler.get_mapping_for_address(addr)
if addr != m.start:
heap_not_at_start = ' (!)'
heap_not_at_start = ' (!) '

print '[+] %s HEAP @0x%0.8x' % (heap_not_at_start, addr)
print '[+] %s@0x%0.8x' % (heap_not_at_start, addr), m
if not opts.verbose:
continue
#print x
Expand Down

0 comments on commit e5356e1

Please sign in to comment.