Python源码示例:idaapi.get_func()
示例1
def find_dispatch_by_struct_index():
"""Attempts to locate the dispatch function based off it being loaded in a structure
at offset 70h, based off of https://github.com/kbandla/ImmunityDebugger/blob/master/1.73/Libs/driverlib.py """
out = set()
for function_ea in idautils.Functions():
flags = idc.get_func_flags(function_ea)
# skip library functions
if flags & idc.FUNC_LIB:
continue
func = idaapi.get_func(function_ea)
addr = func.startEA
while addr < func.endEA:
if idc.GetMnem(addr) == 'mov':
if '+70h' in idc.GetOpnd(addr, 0) and idc.GetOpType(addr, 1) == 5:
out.add(idc.GetOpnd(addr, 1))
addr = idc.NextHead(addr)
return out
示例2
def find_all_ioctls():
"""
From the currently selected address attempts to traverse all blocks inside the current function to find all immediate values which
are used for a comparison/sub immediately before a jz. Returns a list of address, second operand pairs.
"""
ioctls = []
# Find the currently selected function and get a list of all of it's basic blocks
addr = idc.ScreenEA()
f = idaapi.get_func(addr)
fc = idaapi.FlowChart(f, flags=idaapi.FC_PREDS)
for block in fc:
# grab the last two instructions in the block
last_inst = idc.PrevHead(block.endEA)
penultimate_inst = idc.PrevHead(last_inst)
# If the penultimate instruction is cmp or sub against an immediate value immediately preceding a 'jz'
# then it's a decent guess that it's an IOCTL code (if this is a dispatch function)
if idc.GetMnem(penultimate_inst) in ['cmp', 'sub'] and idc.GetOpType(penultimate_inst, 1) == 5:
if idc.GetMnem(last_inst) == 'jz':
value = get_operand_value(penultimate_inst)
ioctls.append((penultimate_inst, value))
ioctl_tracker.add_ioctl(penultimate_inst, value)
return ioctls
示例3
def funcAt(self, ea):
"""Return the function that includes the given address.
Args:
ea (int): effective address of the wanted function
Return Value:
A function instance, or None if no such function
"""
func = idaapi.get_func(ea)
if func is None:
return None
# can now use sark more freely
try:
return sark.Function(ea)
except sark.exceptions.SarkNoFunction:
# just to be sure
return None
# Overridden base function
示例4
def enum_function_addrs(fva):
'''
yield the effective addresses of each instruction in the given function.
these addresses are not guaranteed to be in any order.
Args:
fva (int): the starting address of a function
Returns:
sequence[int]: the addresses of each instruction
'''
f = idaapi.get_func(fva)
if not f:
raise ValueError('not a function')
for block in idaapi.FlowChart(f):
ea = block.startEA
while ea <= block.endEA:
yield ea
ea = idc.NextHead(ea)
示例5
def FuncItems(start):
"""
Get a list of function items
@param start: address of the function
@return: ea of each item in the function
"""
func = idaapi.get_func(start)
if not func:
return
fii = idaapi.func_item_iterator_t()
ok = fii.set(func)
while ok:
yield fii.current()
ok = fii.next_code()
示例6
def get_libc_version_disasm():
fnc_addr = get_name_ea_simple("gnu_get_libc_version")
if fnc_addr == BADADDR:
return None
add_func(fnc_addr)
fnc = get_func(fnc_addr)
if fnc is None:
return None
for head in Heads(fnc.start_ea, fnc.end_ea):
disas = GetDisasm(head)
if disas.startswith("lea"):
m = re.search(";\s\"(.*)\"$", disas)
if m:
return m.groups()[0]
return None
# --------------------------------------------------------------------------
示例7
def OnDblClick(self, node_id):
eas = self.nodes_ea[node_id]
if len(eas) == 1:
jumpto(list(eas)[0])
else:
items = []
for ea in eas:
func = idaapi.get_func(ea)
if func is None:
s = get_strlit_contents(ea)
s = s.decode("utf-8")
if s is not None and s.find(str(self[node_id])) == -1:
s = get_strlit_contents(ea, strtype=1)
else:
s = GetDisasm(ea)
else:
s = get_func_name(func.start_ea)
items.append(["0x%08x" % ea, repr(s)])
chooser = CClassXRefsChooser("XRefs to %s" % str(self[node_id]), items)
idx = chooser.Show(1)
if idx > -1:
jumpto(list(eas)[idx])
示例8
def get_func(func_ea):
"""get_func(func_t or ea) -> func_t
Take an IDA function (``idaapi.func_t``) or an address (EA) and return
an IDA function object.
Use this when APIs can take either a function or an address.
Args:
func_ea: ``idaapi.func_t`` or ea of the function.
Returns:
An ``idaapi.func_t`` object for the given address. If a ``func_t`` is
provided, it is returned.
"""
if isinstance(func_ea, idaapi.func_t):
return func_ea
func = idaapi.get_func(func_ea)
if func is None:
raise exceptions.SarkNoFunction("No function at 0x{:08X}".format(func_ea))
return func
示例9
def get_nx_graph(ea, ignore_external=False):
"""Convert an IDA flowchart to a NetworkX graph."""
nx_graph = networkx.DiGraph()
func = idaapi.get_func(ea)
flowchart = FlowChart(func, ignore_external=ignore_external)
for block in flowchart:
# Make sure all nodes are added (including edge-less nodes)
nx_graph.add_node(block.start_ea)
for pred in block.preds():
nx_graph.add_edge(pred.start_ea, block.start_ea)
for succ in block.succs():
nx_graph.add_edge(block.start_ea, succ.start_ea)
return nx_graph
示例10
def find_interesting_xors(self):
next_xor = idc.FindText(idc.MinEA(), idc.SEARCH_DOWN|idc.SEARCH_NEXT, 0, 0, "xor")
while next_xor != idc.BADADDR:
if idc.GetOpnd(next_xor, 0) != idc.GetOpnd(next_xor, 1):
entry = {"func":"", "addr": next_xor, "loop":False, "disasm": idc.GetDisasm(next_xor)}
func = idaapi.get_func(next_xor)
if func:
entry["func"] = idaapi.get_name(idc.BADADDR, func.startEA)
heads = idautils.Heads(next_xor, func.endEA)
lxors = []
for head in heads:
if idc.GetMnem(head).startswith('j'):
jmp_addr = idc.GetOperandValue(head,0)
if jmp_addr < next_xor and jmp_addr > func.startEA:
entry["loop"] = True
break
self._interesting_xors.append(entry)
next_xor = idc.FindText(idc.NextHead(next_xor), idc.SEARCH_DOWN|idc.SEARCH_NEXT, 0, 0, "xor")
示例11
def search_function_with_wildcards():
addr_current = idc.get_screen_ea()
addr_func = idaapi.get_func(addr_current)
if not addr_func:
logging.error('[VT Plugin] Current address doesn\'t belong to a function')
ida_kernwin.warning('Point the cursor in an area beneath a function.')
else:
search_vt = vtgrep.VTGrepSearch(
addr_start=addr_func.start_ea,
addr_end=addr_func.end_ea
)
search_vt.search(True, False)
示例12
def __init__(self, fun_addr):
super(MyFlowGraph, self).__init__()
self.fun = idaapi.get_func(fun_addr)
self.startEA = self.fun.startEA
self.endEA = self.fun.endEA
for bb in idaapi.FlowChart(self.fun):
self.__setitem__(bb.id, MyBasicBlock(bb))
self._compute_links()
self.edge_map = self.make_graph()
self.shortest_path_map = self.dijkstra(self.edge_map)
self.size = sum([x.size() for x in self.values()])
self.viewer = MyFlowGraphViewer(self, "Extract(%s)" % idc.GetFunctionName(self.startEA))
示例13
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
示例14
def run(self):
# -- GUI stuff
self.result_widget.set_actions_visible_and_enabled(False)
self.set_progress_visible(True)
# -----------
# Refill the configuration file
if self.configuration.ksteps != 0 and self.config_widget.radio_path_routine.isChecked():
self.k = self.configuration.ksteps # Use the ksteps given if making the path on the whole routine
self.result_widget.webview.append("### Opaque predicates Detection ###\n")
self.configuration.analysis_name = "static opaque"
self.configuration.additional_parameters.typeid = self.configuration.additional_parameters.STANDARD
target_val = str(self.config_widget.target_field.text())
start_tps = time.time()
if self.config_widget.radio_addr.isChecked():
addr = utils.to_addr(target_val)
self.process_routine(idaapi.get_func(addr).startEA, pred_addr=addr)
elif self.config_widget.radio_routine.isChecked():
addr = idc.LocByName(target_val)
if addr == idc.BADADDR:
addr = utils.to_addr(target_val)
self.process_routine(addr)
elif self.config_widget.radio_program.isChecked():
self.process_program()
else:
pass
self.exec_time_total = time.time() - start_tps - self.exec_time_dep
self.analyse_finished = True
self.broker.terminate()
# -- GUI stuff
self.result_widget.set_actions_visible_and_enabled(True)
self.set_progress_visible(False)
# ------------
self.analysis_terminated()
示例15
def highlight_dead_code(self, enabled):
curr_fun = idaapi.get_func(idc.here()).startEA
cfg = self.functions_cfg[curr_fun]
# for cfg in self.functions_cfg.values():
for bb in cfg.values():
color = {Status.DEAD: 0x5754ff, Status.ALIVE: 0x98FF98, Status.UNKNOWN: 0xaa0071}[bb.status]
color = 0xFFFFFF if enabled else color
for i in bb:
idc.SetColor(i, idc.CIC_ITEM, color)
self.actions[HIGHLIGHT_DEAD_CODE] = (self.highlight_dead_code, not enabled)
self.result_widget.action_selector_changed(HIGHLIGHT_DEAD_CODE)
示例16
def highlight_spurious(self, enabled):
print "Highlight spurious clicked !"
curr_fun = idaapi.get_func(idc.here()).startEA
cfg = self.functions_cfg[curr_fun]
color = 0xFFFFFF if enabled else 0x507cff
for bb in [x for x in cfg.values() if x.is_alive()]: # Iterate only alive basic blocks
for i, st in bb.instrs_status.items():
if st == Status.DEAD: # Instructions dead in alive basic blocks are spurious
idc.SetColor(i, idc.CIC_ITEM, color)
self.actions[HIGHLIGHT_SPURIOUS_CALCULUS] = (self.highlight_spurious, not enabled)
self.result_widget.action_selector_changed(HIGHLIGHT_SPURIOUS_CALCULUS)
示例17
def update_mapping(self):
pass
self.fun_mapping = {idc.GetFunctionName(x): (idaapi.get_func(x).startEA, idaapi.get_func(x).endEA-1) for x in
idautils.Functions()}
self.seg_mapping = {idc.SegName(x): (idc.SegStart(x), idc.SegEnd(x)) for x in idautils.Segments()}
示例18
def __init__(self):
addr = idc.ScreenEA()
func = idaapi.get_func(addr)
tests_choice = "\n".join(map(lambda x: "<%s:{r%s}>" % (x, x), AVAILABLE_TESTS))
ida_kernwin.Form.__init__(self,
r"""BUTTON YES* Launch
BUTTON CANCEL NONE
Sibyl Settings
{FormChangeCb}
Apply on:
<One function:{rOneFunc}>
<All functions:{rAllFunc}>{cMode}>
<Targeted function:{cbFunc}>
Testsets to use:
%s{cTest}>
""" % tests_choice, {
'FormChangeCb': ida_kernwin.Form.FormChangeCb(self.OnFormChange),
'cMode': ida_kernwin.Form.RadGroupControl(("rOneFunc", "rAllFunc")),
'cTest': ida_kernwin.Form.ChkGroupControl(map(lambda x: "r%s" % x,
AVAILABLE_TESTS),
value=(1 << len(AVAILABLE_TESTS)) - 1),
'cbFunc': ida_kernwin.Form.DropdownListControl(
items=self.available_funcs,
readonly=False,
selval="0x%x" % func.startEA),
}
)
self.Compile()
示例19
def Texts(*args):
"""
Enumerate text search matches
@param <range>: see getrange
@param searchstr: string or regex
@param flags: for instance SEARCH_REGEX
@return: list of addresses matching searchstr
Example::
for ea in Texts((FirstSeg(), BADADDR), "LDR *PC, =", SEARCH_REGEX):
f = idaapi.get_func(ea)
if f and f.start_ea==ea:
n= idaapi.get_name(BADADDR, ea)
if not n.startswith("sub_"):
MakeName(ea, "j_%s" %n)
Will search for functions containing only "LDR PC, =xxxxx",
and rename them as j_XXXXX.
"""
(first, last)= getrange(args)
i= getstringpos(args)
if i<0:
raise Exception("missing searchstring")
searchstr= args[i]
flags = args[i+1] if i+1<len(args) else 0
ea= idaapi.find_text(first, idaapi.SEARCH_DOWN|flags, 0, 0, searchstr)
while ea!=idaapi.BADADDR and ea<last:
yield ea
ea= idaapi.find_text(idaapi.next_head(ea, last), idaapi.SEARCH_DOWN|flags, 0, 0, searchstr)
示例20
def get_basic_blocks(fva):
'''
return sequence of `BasicBlock` instances for given function.
'''
ret = []
func = idaapi.get_func(fva)
if func is None:
return ret
for bb in idaapi.FlowChart(func):
ret.append(BasicBlock(va=bb.start_ea,
size=bb.end_ea - bb.start_ea))
return ret
示例21
def get_function(va):
'''
return va for first instruction in function that contains given va.
'''
return idaapi.get_func(va).start_ea
示例22
def get_custom_viewer_hint(self, view, place):
try:
tform = idaapi.get_current_tform()
if idaapi.get_tform_type(tform) != idaapi.BWN_DISASM:
return None
curline = idaapi.get_custom_viewer_curline(view, True)
# sometimes get_custom_viewer_place() returns [x, y] and sometimes [place_t, x, y].
# we want the place_t.
viewer_place = idaapi.get_custom_viewer_place(view, True)
if len(viewer_place) != 3:
return None
_, x, y = viewer_place
ea = place.toea()
# "color" is a bit of misnomer: its the type of the symbol currently hinted
color = get_color_at_char(curline, x)
if color != idaapi.COLOR_ADDR:
return None
# grab the FAR references to code (not necessarilty a branch/call/jump by itself)
far_code_references = [xref.to for xref in idautils.XrefsFrom(ea, ida_xref.XREF_FAR)
if idc.isCode(idc.GetFlags(xref.to))]
if len(far_code_references) != 1:
return None
fva = far_code_references[0]
# ensure its actually a function
if not idaapi.get_func(fva):
return None
# this magic constant is the number of "important lines" to display by default.
# the remaining lines get shown if you scroll down while the hint is displayed, revealing more lines.
return render_function_hint(fva), DEFAULT_IMPORTANT_LINES_NUM
except Exception as e:
logger.warning('unexpected exception: %s. Get in touch with @williballenthin.', e, exc_info=True)
return None
示例23
def Chunks(start):
"""
Get a list of function chunks
@param start: address of the function
@return: list of funcion chunks (tuples of the form (start_ea, end_ea))
belonging to the function
"""
func_iter = idaapi.func_tail_iterator_t( idaapi.get_func( start ) )
status = func_iter.main()
while status:
chunk = func_iter.chunk()
yield (chunk.startEA, chunk.endEA)
status = func_iter.next()
示例24
def get_current_address():
"""
Get the hex address of the function.
"""
ca = idc.here()
func = idaapi.get_func(ca)
if not func:
print("GhIDA:: [!] Error: function not found.")
return None
# Get function start address
ea = func.start_ea
ea = hex(ea).strip("0x").strip("L")
return ea
示例25
def convert_address(ca):
"""
Convert a decimal address into the hex address
of the corresponding function.
"""
func = idaapi.get_func(ca)
if not func:
print("GhIDA:: [!] Error: function not found.")
return None
# Get function start address
ea = func.start_ea
ea = hex(ea).strip("0x").strip("L")
return ea
示例26
def get_basic_blocks(fva):
'''
return sequence of `BasicBlock` instances for given function.
'''
ret = []
func = idaapi.get_func(fva)
if func is None:
return ret
for bb in idaapi.FlowChart(func):
ret.append(BasicBlock(va=bb.start_ea,
size=bb.end_ea - bb.start_ea))
return ret
示例27
def get_function(va):
'''
return va for first instruction in function that contains given va.
'''
return idaapi.get_func(va).start_ea
示例28
def get_func_name_offset(ea):
func = idaapi.get_func(ea)
if func:
offset = ea - func.start_ea
return "%s+%#x" % (get_func_name(ea), offset)
return "%#x" % ea
# --------------------------------------------------------------------------
示例29
def rename_items(self, items):
for i in items:
item = self.items[i]
ea = int(item[3], 16)
candidate, _ = os.path.splitext(item[2])
name = "%s_%08x" % (candidate, ea)
func = idaapi.get_func(ea)
if func is not None:
ea = func.start_ea
set_name(ea, name, SN_CHECK)
else:
line = "WARNING: Cannot rename 0x%08x to %s because there is no function associated."
print(line % (ea, name))
示例30
def __init__(self, title, classes, final_list):
idaapi.GraphViewer.__init__(self, title)
self.selected = None
self.classes = classes
self.final_list = final_list
self.nodes = {}
self.nodes_ea = {}
self.graph = {}
self.last_cmd = 0
dones = set()
for ea, tokens in self.classes:
refs = DataRefsTo(ea)
refs_funcs = set()
for ref in refs:
func = idaapi.get_func(ref)
if func is not None:
refs_funcs.add(func.start_ea)
if len(refs_funcs) == 1:
func_ea = list(refs_funcs)[0]
if func_ea in dones:
continue
dones.add(func_ea)
func_name = get_func_name(func_ea)
tmp = demangle_name(func_name, INF_SHORT_DN)
if tmp is not None:
func_name = tmp
element = [func_ea, func_name, "::".join(tokens), [get_string(ea)]]
self.final_list.append(element)