Log in

View Full Version : ImmDbg getXrefTo API call


RalenBek
July 19th, 2009, 12:40
Hey guys,

I'm working on a script for Immunity Debugger at the moment, the aim of which is just to automate some repeated breakpointing I seem to do all the time. Anyways, the following script illustrates a problem I'm having finding, and setting breakpoints on, the callsites of a given function.

Everything appears to work fine until about 8 lines from the end, where getXrefTo() is called. This consistently returns no xrefs for functions I have verified are called. The functions are found at the same addresses that are used if I just right click on the function name and set a breakpoint on all call sites, but passing that value to getXrefTo returns an empty list.

Any help is appeciated. Cheers.

Code:

"""
callsitebp.py - Set breakpoints at the callsites of a given function
"""

__VERSION__ = '0.1'

import getopt
import immlib


DESC = "Set breakpoints at the callsites of a given function"
HEAD = "### PyCommand CallsiteBP ###"
USAGE = "!callsitebp [-m module] -f function"

def usage(imm):
imm.Log(USAGE)
return "For usage information see Log Window"

def findFunction(imm, mod, funcName, foundFuncs):
modAddr = mod.getBaseAddress()

imm.Log("Getting functions from %s" % mod.getName())

for funcAddr in imm.getAllFunctions(modAddr):
func = imm.getFunction(funcAddr)
foundName = func.getName().split('.')[-1]
if foundName == funcName:
imm.Log("Found %s in %s at 0x%x" % (funcName, mod.getName(),
func.getStart()))
foundFuncs.append((func, mod))

def main(args):
if not args:
return USAGE

imm = immlib.Debugger()
funcName = None
numBps = 0
foundFuncs = []
modName = None

imm.Log(HEAD)

try:
opts, extra = getopt.getopt(args, "m:f:"
except getopt.GetoptError:
imm.setStatusBar("Bad argument %s" % str(args))
usage(imm)
return 0

for flag, val in opts:
if flag == "-m":
modName = val
elif flag == "-f":
funcName = val

imm.Log("Setting breakpoints on callsites of %s" % funcName)

if funcName is None:
imm.Log(USAGE)
return "No function specified. Check log for usage details"

if modName is None:
for mod in imm.getAllModules():
if not mod.isAnalysed():
imm.Log("Analysing %s" % mod.getName())
imm.analyseCode(mod.getCodebase())

findFunction(imm, mod, funcName, foundFuncs)
else:
mod = imm.getModule(modName)
if mod is None:
return "Module %s not found" % modName

if not mod.isAnalysed():
imm.Log("Analysing %s" % mod.getName())
imm.analyseCode(mod.getCodebase())

findFunction(imm, mod, funcName, foundFuncs)

if len(foundFuncs) == 0:
imm.Log("%s not found in any loaded modules! Check spelling and case." %
funcName)
return "Function not found. Check log"

imm.Log("Found %d functions matching that description" % len(foundFuncs))
for func, mod in foundFuncs:
funcAddr = func.getStart()
imm.Log("Looking for XREFs to 0x%x" % funcAddr)
xrefs = imm.getXrefTo(funcAddr)
imm.Log("Found %d XREFs to %s" % (len(xrefs), funcName))

for xref in xrefs:
imm.Log("Setting breakpoint at 0x%x" % xref.getStart())
imm.setBreakpoint(xref.getStart())
numBps += 1

return "Breakpoints set on %d callsites" % numBps


And some sample output....

Code:

0BADF00D ### PyCommand CallsiteBP ###
0BADF00D Setting breakpoints on callsites of VirtualAlloc
0BADF00D Getting functions from kernel32.dll
0BADF00D Found VirtualAlloc in kernel32.dll at 0x7c809a61
0BADF00D Found 1 functions matching that description
0BADF00D Looking for XREFs to 0x7c809a61
0BADF00D Found 0 XREFs to VirtualAlloc


UPDATE: It does appear the following two lines don't actually get passed every function defined in the module either. For example, in the debugger I can set see the function msvcrt.free is imported, and set breakpoints on all its call sites, but the only 'free' function that imm.getAllFunctions() returns is msvcrt._aligned_free.

Code:

for funcAddr in imm.getAllFunctions(modAddr):
func = imm.getFunction(funcAddr)