Skip to content

Commit fe032a9

Browse files
committed
doesn't work for stacked IMemoryMapping. more work to do for rebase
1 parent a1368ea commit fe032a9

File tree

6 files changed

+36
-22
lines changed

6 files changed

+36
-22
lines changed

haystack/allocators/win32/win7heapwalker.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ def _make_dual_arch_ctypes(self):
6363
_constraints_64 = parser.read(constraint_filename)
6464

6565
# KERNEL AS
66-
kas32 = (0xFFFF080000000000, 0xFFFFFFFFFFFFFFFF)
66+
kas32 = (0x8000000, 0xFFFFFFFF)
6767
kas64 = (0xFFFF080000000000, 0xFFFFFFFFFFFFFFFF)
6868

6969
_cpu = dict()

haystack/allocators/win32/winheapwalker.py

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,7 @@ def _find_heap(self, mapping):
284284
Funny enough, a X64 process could have 32 bits and 64 bits heaps.
285285
"""
286286
for addr in range(mapping.start, mapping.end, 0x1000):
287+
map_start = mapping.start
287288
# offset of Signature in 32 and 64 bits
288289
for bits in [32, 64]:
289290
offset = self._cpu[bits]['signature_offset']
@@ -299,14 +300,14 @@ def _find_heap(self, mapping):
299300
self._cpu[bits]['constraints'],
300301
addr)
301302
elif self.__is_kernel_heap(mapping, addr, bits):
302-
# FIXME
303-
addr = mapping.start
303+
_heap_offset = addr - map_start
304+
heap_addr = mapping.start + _heap_offset
304305
return self._walker_type()(self._memory_handler,
305306
self._cpu[bits]['target'],
306307
self._cpu[bits]['module'],
307308
mapping,
308309
self._cpu[bits]['constraints'],
309-
addr)
310+
heap_addr)
310311
# otherwise try another combination
311312
return None
312313

@@ -337,6 +338,7 @@ def __is_kernel_heap(self, mapping, address, bits):
337338
"""
338339
if not isinstance(mapping, interfaces.IMemoryMapping):
339340
raise TypeError('Feed me a IMemoryMapping object')
341+
offset = self._cpu[bits]['signature_offset']
340342
# switch to the right target
341343
heap_module = self._cpu[bits]['module']
342344
target_platform = self._cpu[bits]['target']
@@ -352,17 +354,24 @@ def __is_kernel_heap(self, mapping, address, bits):
352354
old_start = mapping.start
353355
# start = kernel_ptr & 0xFFFFFFFFFFFF0000
354356
start = kernel_ptr & ((1 << bits) - 0x10000)
355-
print '[!] KERNEL SPACE HEAP FOUND ! USER:0x%x => KERNEL:0x%x' % (address, start)
357+
#print '[!] POSSIBLE KERNEL SPACE HEAP FOUND ! USER:0x%x => KERNEL:0x%x' % (address, start)
358+
## print hex(struct.unpack('I', mapping.read_bytes(address+offset, 4))[0])
359+
# FIXME: rebase must be recursive on mappings
360+
#import pdb
361+
#pdb.set_trace()
356362
self._memory_handler.rebase_mapping(mapping, start)
357-
self._memory_handler.reset_mappings()
363+
## print hex(struct.unpack('I', mapping.read_bytes(start+offset, 4))[0])
358364
heap = mapping.read_struct(start, heap_module.HEAP)
359365
# validator is (should be) then target-bound
360366
validator = self._validator_type()(self._memory_handler, constraints, target_platform, heap_module)
361367
load = validator.load_members(heap, 3)
362368
log.debug('HeapFinder._is_heap %s %s', mapping, load)
363369
if not load:
370+
#import code
371+
#code.interact(local=locals())
364372
self._memory_handler.rebase_mapping(mapping, old_start)
365-
self._memory_handler.reset_mappings()
373+
else:
374+
print '[!] KERNEL SPACE HEAP FOUND ! USER:0x%x => KERNEL:0x%x' % (address, start)
366375
return load
367376

368377
def _get_heap_possible_kernel_pointer_from_heap(self, target_platform, heap):

haystack/allocators/win32/winxpheapwalker.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ def _make_dual_arch_ctypes(self):
6262
_constraints_64 = parser.read(constraint_filename)
6363

6464
# KERNEL AS
65-
kas32 = (0xFFFF080000000000, 0xFFFFFFFFFFFFFFFF)
65+
kas32 = (0x8000000, 0xFFFFFFFF)
6666
kas64 = (0xFFFF080000000000, 0xFFFFFFFFFFFFFFFF)
6767

6868
_cpu = dict()

haystack/dump_loader.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -175,9 +175,7 @@ def _load_memory_mappings(self):
175175
log.warning(
176176
'Using a local memory mapping . Zipfile sux. thx ruby.')
177177
mmap = AMemoryMapping(start, end, permissions, offset, major_device, minor_device, inode, pathname=pathname)
178-
mmap = LocalMemoryMapping.fromBytebuffer(
179-
mmap,
180-
mmap_content_file.read())
178+
mmap = LocalMemoryMapping.fromBytebuffer(mmap, mmap_content_file.read())
181179
# use file mmap when file is too big
182180
elif end - start > haystack.MAX_MAPPING_SIZE_FOR_MMAP:
183181
log.warning('Using a file backed memory mapping. no mmap in memory for this memorymap (%s).' % (pathname) +

haystack/mappings/base.py

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,11 @@ def read_struct(self, address, struct):
189189
def read_array(self, address, basetype, count):
190190
raise NotImplementedError(self)
191191

192+
def rebase(self, new_start_address):
193+
end = new_start_address + len(self)
194+
self.start = new_start_address
195+
self.end = end
196+
192197

193198
class MemoryHandler(interfaces.IMemoryHandler, interfaces.IMemoryCache):
194199
"""
@@ -268,8 +273,6 @@ def reset_mappings(self):
268273
# reset the mappings
269274
for m in self.get_mappings():
270275
m.reset()
271-
# reset the caches too
272-
self.__optim_get_mapping_for_address()
273276

274277
def __optim_get_mapping_for_address(self):
275278
self.__optim_get_mapping_for_address_cache = dict()
@@ -431,10 +434,13 @@ def rebase_mapping(self, user_mapping, new_start_address):
431434
if user_mapping not in self._mappings:
432435
raise ValueError("User mapping not found")
433436
user_mapping = self._mappings[self._mappings.index(user_mapping)]
434-
end = new_start_address + len(user_mapping)
435-
user_mapping.start = new_start_address
436-
user_mapping.end = end
437+
user_mapping.rebase(new_start_address)
438+
# end = new_start_address + len(user_mapping)
439+
# user_mapping.start = new_start_address
440+
# user_mapping.end = end
437441
self._mappings.sort()
442+
# reset the caches too
443+
self.__optim_get_mapping_for_address()
438444
return user_mapping
439445

440446

haystack/mappings/file.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -78,9 +78,7 @@ def __init__(self, address, start, end, permissions, offset,
7878
def _vtop(self, vaddr):
7979
ret = vaddr - self.start + self._address
8080
if ret < self._address or ret > (self._address + len(self)):
81-
raise ValueError(
82-
'0x%0.8x/0x%0.8x is not a valid vaddr for me' %
83-
(vaddr, ret))
81+
raise ValueError('0x%0.8x/0x%0.8x is not a valid vaddr for me' % (vaddr, ret))
8482
return ret
8583

8684
def mmap(self):
@@ -202,6 +200,11 @@ def mmap(self):
202200
def unmmap(self):
203201
raise NotImplementedError
204202

203+
def rebase(self, new_start_address):
204+
super(MemoryDumpMemoryMapping, self).rebase(new_start_address)
205+
if self.is_mmaped():
206+
self._base.rebase(new_start_address)
207+
205208
def _mmap(self):
206209
""" protected api """
207210
# mmap.mmap has a full bytebuffer API, so we can use it as is for bytebuffer.
@@ -245,9 +248,7 @@ def _mmap(self):
245248
self._memdump.close()
246249
log.warning('MemoryHandler Mapping content copied to ctypes array : %s', self)
247250
# make that _base
248-
self._base = LocalMemoryMapping.fromAddress(
249-
self, ctypes.addressof(
250-
self._local_mmap_content))
251+
self._base = LocalMemoryMapping.fromAddress(self, ctypes.addressof(self._local_mmap_content))
251252
log.debug('%s done.' % self.__class__)
252253
# redirect function calls
253254
self.read_word = self._base.read_word

0 commit comments

Comments
 (0)