mirror of
https://github.com/vivisect/vivisect
synced 2026-06-08 18:04:23 +00:00
e42e6de568
* initial emulation commit: bugfix: BSF bugfix: ROR (emu doesn't set OF when processor does, in the "undefined behavior" realm) add: e_bits.msb_minus_one() and unittest * a few bugs * psize should be imem_psize * PE use archcalls instead of defcalls... * more updates - emu-bugfixes and lockstep updates * amd64-emu-bugfixes and lockstep work. * bugfix for call [esp + FOO] bugfix for pushfd * new memory allocator (been long in coming). hey, it said "fixme!" * more efficient findFreeMemoryBlock() algorithm * lots of emulation and symbol bugfixes * enhancement: REP i386reponce enhancement: i386 LEA analyzed for accessing local vars * tweak for Function Header bugfix: VWGUI envi nav sendto (actually check and limit which funcgraphs are sent) * bugfix: REP/REPZ/REPNZ handlers * Safeguard codeblocks.py as it counts mnemonics (#408) * Safeguard codeblocks.py as it counts mnemonics * Add logging for error * break instead of pass Co-authored-by: todd-plantenga <todd.plantenga@mandiant.com> Co-authored-by: James Gross <45212823+rakuy0@users.noreply.github.com> * Yet Another Grabbag Bugfix PR (#404) * Get vtrace and other unittests working on windows * tests for vivisect.reports * PE.carve bytes/string IO fix * lots of fixes to the intel emulators per the lockstepper test which only runs on windows. * utilitize some common hex functionality * bugfix and implement BOUND emulation * reponce bugfix cleanup * mods and bugfixes per @rakuy0 * updates from merge-fail * bugfix: envitools->util * more tweaks for unittests and @rakuy0 * replacing delMemoryMap() in envi.memory! * fix unittest that doesn't want to work correctly. * modified rep prefix handler to handle repz as well. unittests * updated BSR tests (and emu flags work) * changes per @rakuy0 * bugfix: IMUL now does signed math * fixed unittest * mods per @rakuy0 * unduplicate the rep_handler list for Amd64Emulator (since it's defined in IntelEmulator's __init__) * updated MM_* constants from envi.const * more e_mem -> e_const for MM_READ/WRITE/etc.. * updates per @rakuy0 * touchups before the purge... about to kill off the LockStep stuff from this branch (will continue in Vtrace conversions PR#406) * RESET LockStepper code and tests. look to Vtrace PR#406 for these changes * test allocateMemory() "insufficient contiguous memory" exception case. Co-authored-by: upside2 <todd.plantenga@fireeye.com> Co-authored-by: todd-plantenga <todd.plantenga@mandiant.com> Co-authored-by: James Gross <45212823+rakuy0@users.noreply.github.com>
92 lines
2.9 KiB
Python
92 lines
2.9 KiB
Python
"""
|
|
Watchpoint Objects
|
|
"""
|
|
# Copyright (C) 2007 Invisigoth - See LICENSE file for details
|
|
import envi.const as e_const
|
|
|
|
from vtrace import *
|
|
from vtrace.breakpoints import *
|
|
|
|
class Watchpoint(Breakpoint):
|
|
"""
|
|
The basic "break on access" watchpoint. Extended from
|
|
Breakpoints and handled almost exactly the same way...
|
|
"""
|
|
def __init__(self, addr, expression=None, size=4, perms="rw"):
|
|
Breakpoint.__init__(self, addr, expression=expression)
|
|
self.wpsize = size
|
|
self.wpperms = perms
|
|
|
|
def inittrace(self, trace):
|
|
# No need to get a breakinstr
|
|
pass
|
|
|
|
def resolvedaddr(self, trace, addr):
|
|
# We needn't save the memory at our addr...
|
|
pass
|
|
|
|
def getName(self):
|
|
bname = Breakpoint.getName(self)
|
|
return "%s (%s %d bytes)" % (bname, self.wpperms, self.wpsize)
|
|
|
|
def activate(self, trace):
|
|
trace.requireAttached()
|
|
if not self.active:
|
|
if self.address is not None:
|
|
trace.archAddWatchpoint(self.address, size=self.wpsize, perms=self.wpperms)
|
|
self.active = True
|
|
return self.active
|
|
|
|
def deactivate(self, trace):
|
|
trace.requireAttached()
|
|
if self.active:
|
|
trace.archRemWatchpoint(self.address)
|
|
self.active = False
|
|
return self.active
|
|
|
|
class PageWatchpoint(Watchpoint):
|
|
"""
|
|
A special "watchpoint" that uses memory permissions to
|
|
watch for accesses to whole memory maps. This *requires* OS
|
|
help and only works on platforms which support:
|
|
* platformProtectMemory()
|
|
* signal/exceptions which denote the fault address on SEGV
|
|
|
|
NOTE: These *must* be added page aligned
|
|
"""
|
|
def __init__(self, addr, expression=None, size=4, watchread=False):
|
|
Watchpoint.__init__(self, addr, expression=expression, size=size, perms='rw')
|
|
self._orig_perms = None
|
|
self._new_perms = e_const.MM_READ
|
|
if watchread:
|
|
self._new_perms = e_const.MM_NONE
|
|
|
|
def resolvedaddr(self, trace, addr):
|
|
self._orig_perms = trace.getMemoryMap(addr)[2]
|
|
|
|
def notify(self, event, trace):
|
|
pw = trace.getMeta('pagewatch')
|
|
pc = trace.getProgramCounter()
|
|
vaddr,vperm = trace.platformGetMemFault()
|
|
pw.append((pc, vaddr, vperm))
|
|
# Change to/from fastbreak on pagerun...
|
|
self.fastbreak = trace.getMeta('pagerun')
|
|
|
|
def getName(self):
|
|
bname = Breakpoint.getName(self)
|
|
return "%s (%s %d bytes)" % (bname, e_mem.reprPerms(self._new_perms), self.wpsize)
|
|
|
|
def activate(self, trace):
|
|
#trace.requireNotRunning()
|
|
if not self.active:
|
|
trace.protectMemory(self.address, self.wpsize, self._new_perms)
|
|
self.active = True
|
|
return self.active
|
|
|
|
def deactivate(self, trace):
|
|
#trace.requireNotRunning()
|
|
if self.active:
|
|
trace.protectMemory(self.address, self.wpsize, self._orig_perms)
|
|
self.active = False
|
|
return self.active
|