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', [])