Source code for vtrace.tools.iathook
'''
Code for hooking import address tables by making them invalid
pointers and catching the exceptions...
'''
import PE
import vtrace
import vtrace.watchpoints as vt_watchpoints
[docs]class IatHook(vt_watchpoints.Watchpoint):
'''
Abuse the PageWatch subsystem to allow function pointers to be
frob'd to create breakpoint like behavior.
'''
newptr = 0xfbfbf000
def __init__(self, ptraddr, iatname):
fakeptr = IatHook.newptr
IatHook.newptr += 4096 # FIXME race... sigh...
vt_watchpoints.Watchpoint.__init__(self, fakeptr)
self.ptraddr = ptraddr
self.fakeptr = fakeptr
self.iatname = iatname
self.origptr = None
[docs] def getName(self):
#bname = Breakpoint.getName(self)
return self.iatname
[docs] def resolveAddr(self, trace, addr):
pass
[docs] def activate(self, trace):
if self.origptr == None:
self.origptr = trace.readMemoryFormat(self.ptraddr, '<P')[0]
trace.writeMemoryFormat(self.ptraddr, '<P', self.fakeptr)
[docs] def deactivate(self, trace):
if self.origptr != None:
trace.writeMemoryFormat(self.ptraddr, '<P', self.origptr)
[docs] def notify(self, event, trace):
# We have to fake out the program counter...
trace.setProgramCounter(self.origptr)
trace.setCurrentSignal(None)
return vt_watchpoints.Watchpoint.notify(self, event, trace)
[docs]def hookIat(trace, libname, implib='*', impfunc='*', fast=False):
'''
Hook the IAT with special "breakpoint" like objects which
handle the memory access errors and document the calls...
Set fast=True for them to be "Fastbreak" breakpoints.
This returns a list of (name, bpid) tuples...
Example:
for impname, bpid in hookIat(t, 'ws2_32')
t.setBreakpointCode(bpid, codestr)
...
'''
ret = []
baseaddr = trace.parseExpression(libname)
pe = PE.peFromMemoryObject(trace, baseaddr)
origs = {}
implib = implib.lower()
impfunc = impfunc.lower()
for rva, ilib, ifunc in pe.getImports():
ilib = ilib.lower().replace('.dll', '')
if ilib != implib and implib != '*':
continue
if ifunc.lower() != impfunc and impfunc!='*':
continue
iatname = '%s.%s.%s' % (libname, ilib, ifunc)
wp = IatHook(baseaddr + rva, iatname)
wp.fastbreak = fast
bpid = trace.addBreakpoint(wp)
ret.append( (iatname, bpid) )
return ret