def find_xrefs_from( self, func_ea ):
xrefs = []
for item in idautils.FuncItems( func_ea ):
ALL_XREFS = 0
for ref in idautils.XrefsFrom( item, ALL_XREFS ):
if ref.type not in XrefsFromFinder.XREF_TYPE2STR:
continue
if ref.to in idautils.FuncItems( func_ea ):
continue
disas = idc.GetDisasm( item )
curr_xref = XrefFrom( item, ref.to, ref.type, disas )
xrefs.append( curr_xref )
return xrefs
python类FuncItems()的实例源码
def detect_start_and_stop(self): # FIXME:Duplicate code with core (or something similar)
start, stop = 0, 0
if self.core.ftype == "PE":
start, stop = self.core.fun_mapping["start"]
else:
if "main" in self.core.fun_mapping:
start, stop = self.core.fun_mapping["main"]
elif "start" in self.core.fun_mapping:
if "__libc_start_main" in self.core.fun_mapping:
instrs = list(idautils.FuncItems(self.core.fun_mapping["start"][0]))
instrs.reverse()
for inst in instrs:
arg1 = idc.GetOperandValue(inst, 0)
if idc.GetMnem(inst) == "push":
start, stop = arg1, self.core.fun_mapping["start"][1]
break
else:
start, stop = self.core.fun_mapping["start"]
else:
start, stop = idc.BeginEA(), 0
self.start, self.stop = start, stop
def traverseCalls(adr):
print 'entering into %s' % GetFunctionName(adr)
print 'searching for heap_alloc calls inside'
flags=GetFunctionFlags(adr)
start=GetFunctionAttr(adr,FUNCATTR_START)
end=GetFunctionAttr(adr,FUNCATTR_END)
call_list=[]
heap_found=False
#ignore library functions
if flags & idaapi.FUNC_THUNK or flags & idaapi.FUNC_LIB:
return
#get list all ea's of current function routine
disasm_addr = list(idautils.FuncItems(adr))
for ea in disasm_addr:
if idaapi.is_call_insn(ea):
op_addr = GetOperandValue(ea,0)
op_type = GetOpType(ea,0)
name=GetFunctionName(op_addr)
op_flags = GetFunctionFlags(op_addr)
if op_flags & idaapi.FUNC_LIB:
name = Name(op_addr)
if name in ('GetProcessHeap','HeapAlloc','LocalHeap'):
print 'Heap allocation routine found at %s' % GetFunctionName(ea)
heap_found=True
call_list.append(name)
break
call_list.append(name)
return call_list, heap_found
def process_routine(self, rtn_addr, pred_addr=None, rtn_i=1, total_rtn=1):
if rtn_addr not in self.functions_cfg:
self.functions_cfg[rtn_addr] = MyFlowGraph(rtn_addr)
cfg = self.functions_cfg[rtn_addr]
path_to = self.config_to_path_function(cfg)
if pred_addr is None:
candidates = {x for x in idautils.FuncItems(rtn_addr) if idc.GetMnem(x) in cond_jump}
else:
candidates = {pred_addr}
nb_candidates = len(candidates)
self.functions_candidates[rtn_addr] = set()
self.functions_spurious_instrs[rtn_addr] = set()
self.progressbar_loading.reset()
self.progressbar_loading.setMaximum(len(candidates))
name = idc.GetFunctionName(rtn_addr)
self.result_widget.webview.append("\n=> Function:%s\n" % name)
self.log("[result]", "Start processing function: 0x%x" % rtn_addr)
for i, addr in zip(xrange(len(candidates)), candidates):
path = path_to(addr)
res = self.process_addr(rtn_addr, addr, path)
if self.STOP:
return
elif res is None:
continue
dead_br = "/" if res.dead_branch is None else "%x" % res.dead_branch
self.result_widget.webview.append("%x:\t%s\t\tK:%d\tDead:%s" % (addr, to_status_name(res.status), res.k, dead_br))
self.result_widget.webview.verticalScrollBar().setValue(self.result_widget.webview.verticalScrollBar().maximum())
self.loading_stat.setText("Fun: %d/%d Addr: %d/%d" % (rtn_i, total_rtn, i+1, nb_candidates))
self.progressbar_loading.setValue(self.progressbar_loading.value()+1)
self.functions_candidates[rtn_addr].add(addr)
def set_start_stop(self, ftype):
assert_ida_available()
import idc
import idaapi
import idautils
fun_mapping = {idc.GetFunctionName(x): (idaapi.get_func(x).startEA, idaapi.get_func(x).endEA-1)
for x in idautils.Functions()}
start = idc.BeginEA()
stop = 0
if ftype == PE:
start, stop = fun_mapping["start"]
else:
if not idc.isCode(idc.GetFlags(start)):
if idc.MakeCode(start) == 0:
print "Fail to decode instr !"
idaapi.autoWait()
if idc.GetFunctionName(start) == "":
if idc.MakeFunction(start) == 0:
print "Fail to create function !"
idaapi.autoWait()
fun_mapping = {idc.GetFunctionName(x): (idaapi.get_func(x).startEA, idaapi.get_func(x).endEA-1)
for x in idautils.Functions()}
if "main" in fun_mapping:
start, stop = fun_mapping["main"]
elif "start" in fun_mapping:
if "__libc_start_main" in fun_mapping:
instrs = list(idautils.FuncItems(fun_mapping["start"][0]))
instrs.reverse()
for inst in instrs:
arg1 = idc.GetOperandValue(inst, 0)
if idc.GetMnem(inst) == "push":
start, stop = arg1, fun_mapping["start"][1]
break
else:
start, stop = fun_mapping["start"]
self.config.start, self.config.stop = start, stop
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 graph_down(ea, path=set()):
"""
Recursively collect all function calls.
Copied with minor modifications from
http://hooked-on-mnemonics.blogspot.com/2012/07/renaming-subroutine-blocks-and.html
"""
path.add(ea)
#
# iterate through all the instructions in the target function (ea) and
# inspect all the call instructions
#
for x in [x for x in idautils.FuncItems(ea) if idaapi.is_call_insn(x)]:
# TODO
for r in idautils.XrefsFrom(x, idaapi.XREF_FAR):
#print "0x%08X" % h, "--calls-->", "0x%08X" % r.to
if not r.iscode:
continue
# get the function pointed at by this call
func = idaapi.get_func(r.to)
if not func:
continue
# ignore calls to imports / library calls / thunks
if (func.flags & (idaapi.FUNC_THUNK | idaapi.FUNC_LIB)) != 0:
continue
#
# if we have not traversed to the destination function that this
# call references, recurse down to it to continue our traversal
#
if r.to not in path:
graph_down(r.to, path)
return path