Source code for vdb.recon

'''
The recon subsystem for monitoring well known library
calls and identifying dangerous calling mechanisms.

NOTE: This subsystem pretty much assumes some intel-like
conventions...

Recon Format Chars:
    A - A NULL terminated ascii string
    W - A NULL terminated utf-16le string
    P - A platform width pointer
    I - An integer (32 bits for now...)
'''

import vtrace.breakpoints as vt_breakpoints

[docs]def reprargs(trace, fmt, args): r = [] for i in xrange(len(fmt)): fchr = fmt[i] arg = args[i] if fchr == 'P': sym = trace.getSymByAddr(arg) if sym != None: rstr = repr(sym) else: rstr = '0x%.8x' elif fchr == 'I': rstr = repr(arg) elif fchr == 'U': if arg == 0: rstr = 'NULL' elif not trace.isValidPointer(arg): rstr = '0x%.8x' % arg else: buf = trace.readMemory(arg, 260*2) ubuf = buf.decode('utf-16le','ignore') rstr = repr(ubuf.split('\x00')[0]) elif fchr == 'S': if arg == 0: rstr = 'NULL' elif not trace.isValidPointer(arg): rstr = '0x%.8x' % arg else: buf = trace.readMemory(arg, 260) rstr = repr(buf.split('\x00')[0]) elif fchr == 'C': rstr = repr(chr( arg & 0xff )) elif fchr == 'X': rstr = '0x%.8x' % arg else: raise Exception('Unknown Recon Format: %s' % fchr) r.append(rstr) return r
[docs]class ReconBreak(vt_breakpoints.Breakpoint): ''' ''' def __init__(self, symname, reconfmt): vt_breakpoints.Breakpoint.__init__(self, None, expression=symname) self.fastbreak = True # We are a fast-break, don't notify the trace self._symname = symname self._reconfmt = reconfmt
[docs] def getName(self): return '%s(%s)' % (self._symname, self._reconfmt)
[docs] def notify(self, event, trace): thid = trace.getMeta('ThreadId') stackptr = trace.getStackCounter() rawargs = trace.readMemoryFormat(stackptr, '<%dP' % (len(self._reconfmt) + 1)) savedeip = rawargs[0] args = rawargs[1:] recon_hits = trace.getMeta('recon_hits') argrep = reprargs(trace, self._reconfmt, args) recon_hits.append((thid, savedeip, self._symname, args, argrep)) if not trace.getMeta('recon_quiet'): argstr = '(%s)' % ', '.join(argrep) print 'RECON: %.4d 0x%.8x %s%s' % (thid, savedeip, self._symname, argstr)
[docs]def addReconBreak(trace, symname, reconfmt): if trace.getMeta('recon_hits') == None: trace.setMeta('recon_hits', []) bp = ReconBreak(symname, reconfmt) bpid = trace.addBreakpoint(bp) return bpid
[docs]def clearReconHits(trace): ''' Clear the current list of recon hits. ''' trace.setMeta('recon_hits', [])
[docs]def getReconHits(trace): ''' Get the list of recon "hits" entries. Each hit entry is a tuple of (threadid, savedeip, symname, argtup, argreprtup). ''' return trace.getMeta('recon_hits', [])