def get_import_thunk(import_addr):
'''
find import thunk for the given import pointer.
this is a function that simply jumps to the external implementation of the routine.
Args:
import_addr (int): address of import table pointer.
Returns:
int: address of function thunk.
Raises:
ValueError: when the thunk does not exist.
'''
for xref in idautils.XrefsTo(import_addr):
if xref.type != 3: # XrefTypeName(3) == 'Data_Read'
continue
if idc.GetMnem(xref.frm) != 'jmp':
continue
return xref.frm
raise ValueError('thunk does not exist')
python类XrefsTo()的实例源码
def _refs_to_tablegroup(self):
from itertools import chain
if self.tablegroup is None:
return []
candidates = []
# For now just use the first table array
primary_table = self.tablegroup.primary_table()
# When debug symbols are present, the decompile will usually
# refer to the function table as an offset from the start
# of the vtable, so also allow references to that.
references = chain(idautils.XrefsTo(primary_table.address_point),
idautils.XrefsTo(self.tablegroup.ea))
for ref in references:
start = as_signed(idc.GetFunctionAttr(ref.frm, idc.FUNCATTR_START),
TARGET_ADDRESS_SIZE)
if start == -1:
continue
candidates.append(start)
return candidates
def get_xrefs_to(functions):
candidate_functions = {}
for fva in functions:
candidate_functions[fva] = len(list(idautils.XrefsTo(fva)))
return candidate_functions
def make_islands_xrefs_force_bl_call(ea, verbose=True):
""" makes all BL references to a branch islands as call """
segname = idc.SegName(ea)
if verbose:
print "[+] forcing bl call on: %s [0x%X]" % (segname, ea)
if "branch_islands" in segname:
idc.SetFunctionFlags(ea, idc.GetFunctionFlags(ea) & (0xffffffff - 1))
for x in idautils.XrefsTo(ea):
make_islands_xrefs_force_bl_call(x.frm)
return
idc.ArmForceBLCall(ea)
def get_xrefs(self):
return (IdaLocation(x.frm) for x in idautils.XrefsTo(self.at))
def get_callers(ea,maxlen=None):
'''
Walk through the callers recursively starting at address ea.
maxlen is the maximum number of node the graph can contain.
Return a dictionary of list of caller addresses.
Return empty dictionary when number of node > maxlen.
'''
xtree = {}
visited = []
towalk = [ea]
while towalk:
curr = towalk.pop()
if curr not in xtree: # the start point also will record in the tree
xtree[curr] = []
if curr not in visited:
visited.append(curr)
for x in idautils.XrefsTo(curr):
caller = idaapi.get_func(x.frm)
if caller:
caller = caller.startEA
if caller not in visited:
towalk.append(caller)
# else: #not very clear, if this is not a function, still record it??
# caller = x.frm
# xtree[caller] = []
xtree[curr].append(caller)
if maxlen and len(tree) > maxlen:
return {}
return xtree
def eFunc(self, address=None, retAddr=None, args=[]):
if address == None: address = here()
func = get_func(address)
if retAddr == None:
refs = [ref.frm for ref in XrefsTo(func.startEA, 0)]
if len(refs) != 0:
retAddr = refs[0] + ItemSize(refs[0])
else:
print("Please offer the return address.")
return
self._emulate(func.startEA, retAddr, args)
res = self.curUC.reg_read(self.REG_RES)
return res
def _feature_returnpoints(self, f_ea):
'''
Number of 'ret' within the function
rets = [addr1, addr2. ...]
prior feature: Null
'''
# rets = []
# for ea in idautils.FuncItems(f_ea):
# if idaapi.is_ret_insn(ea):
# rets.append(ea)
# self.ftable["returnpoints"] = rets
DEBUG_PRINT("in returnpoints")
fun = idaapi.get_func(f_ea)
visited = []
retVal = []
for ret in self.ftable["returnpoints"]:
towalk = [ret]
# print 'towalk',towalk
while towalk:
curr = towalk.pop()
# print 'curr',curr
if curr not in range(fun.startEA,fun.endEA+2): # the start point also will record int the tree
# print 'not in range'
continue
# print '1', hex(curr)
if curr not in visited:
visited.append(curr)
inst = GetInstruction(curr)
# print '2', inst
if inst is None:
continue
elif 'eax' in inst:
# print ret, curr, inst
retVal.append((ret,curr,inst))
continue
for xto in idautils.XrefsTo(curr, 0):
DEBUG_PRINT('xto')
if xto.frm not in visited:
DEBUG_PRINT(xto.frm)
towalk.append(xto.frm)
DEBUG_PRINT(retVal)
return len(self.ftable["returnpoints"]), retVal
def __init__(self, ea):
#: The address of the start of this vtable
self.ea = ea
ea, offset_to_top = get_address(ea)
#: The offset to the top of the object for a subobject with this vtable
self.offset_to_top = as_signed(offset_to_top, TARGET_ADDRESS_SIZE)
# Arbitrary bounds for offset size
if self.offset_to_top < -0xFFFFFF or self.offset_to_top > 0xFFFFFF:
raise ValueError("Invalid table address `0x{:02x}`".format(self.ea))
ea, typeinfo = get_address(ea)
#: Handle to the RTTI object associated with this vtable (if any)
self.typeinfo = None
if typeinfo != 0:
if not in_same_segment(typeinfo, self.ea):
raise ValueError("Invalid table address `0x{:02x}`".format(self.ea))
else:
self.typeinfo = ItaniumTypeInfo(typeinfo)
#: A list of function addresses in this vtable (some may be NULL)
self.functions = []
#: The address of the start of the function array
self.address_point = ea
try:
next(idautils.XrefsTo(self.address_point))
except StopIteration:
raise ValueError("Invalid table address `0x{:02x}`".format(self.ea))
while True:
ea, func = get_address(ea)
# The first few function pointers can be 0
if not is_in_executable_segment(func):
if func == 0 and all([f == 0 for f in self.functions]):
pass
else:
break
self.functions.append(func)
# Because the first two functions can be zero, and the RTTI
# pointer and base offset can also be zero, require at least
# one function to not be zero (so blocks of zero don't match).
if all([f == 0 for f in self.functions]):
raise ValueError("Invalid table address `0x{:02x}`".format(self.ea))
#: The size in bytes of this vtable
self.size = TARGET_ADDRESS_SIZE*(len(self.functions) + 2)