def postprocess(self):
try:
if self.cmdname == "MakeFunction":
if idc.GetFunctionAttr(self.addr, 0) is not None:
# Push "MakeFunction" change
pass
elif self.cmdname == "DeclareStructVar":
g_logger.error("Fixme : declare Struct variable")
elif self.cmdname == "SetType":
newtype = idc.GetType(self.addr)
if newtype is None:
newtype = ""
else:
newtype = SkelUtils.prepare_parse_type(
newtype, self.addr)
self.skel_conn.push_type(int(self.addr), newtype)
elif self.cmdname == "OpStructOffset":
g_logger.debug("A struct member is typed to struct offset")
except KeyError:
g_logger.debug("Got unimplemented ops %s", self.cmdname)
return 0
python类GetFunctionAttr()的实例源码
def __init__(self):
self.addr = None
self.flags = None
self.names = [
'Function name', 'Address', 'Segment', 'Length', 'Locals',
'Arguments', 'R', 'F', 'L', 'S', 'B', 'T', '='
]
self.handlers = {
0: lambda: None,
1: lambda: self.ptr().format(self.addr),
2: lambda: '{}'.format(idc.SegName(self.addr)),
3: lambda: self.halfptr().format(idc.GetFunctionAttr(
self.addr, idc.FUNCATTR_END) - self.addr),
4: lambda: self.set_if_true(idc.GetFunctionAttr(
self.addr, idc.FUNCATTR_FRSIZE)),
5: lambda: self.set_if_true(idc.GetFunctionAttr(
self.addr, idc.FUNCATTR_ARGSIZE)),
6: lambda: self.is_true(not self.flags & idc.FUNC_NORET, 'R'),
7: lambda: self.is_true(self.flags & idc.FUNC_FAR, 'F'),
8: lambda: self.is_true(self.flags & idc.FUNC_LIB, 'L'),
9: lambda: self.is_true(self.flags & idc.FUNC_STATIC, 'S'),
10: lambda: self.is_true(self.flags & idc.FUNC_FRAME, 'B'),
11: lambda: self.is_true(idc.GetType(self.addr), 'T'),
12: lambda: self.is_true(self.flags & idc.FUNC_BOTTOMBP, '=')
}
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 output_symbols(out):
"""Dump symbols."""
try:
from idaapi import get_func_name2 as get_func_name
# Since get_func_name is deprecated (at least from IDA 6.9)
except ImportError:
from idaapi import get_func_name
# Older versions of IDA don't have get_func_name2
# so we just use the older name get_func_name
def func_name_propagate_thunk(ea):
current_name = get_func_name(ea)
if current_name[0].isalpha():
return current_name
func = idaapi.get_func(ea)
temp_ptr = idaapi.ea_pointer()
ea_new = idaapi.BADADDR
if func.flags & idaapi.FUNC_THUNK == idaapi.FUNC_THUNK:
ea_new = idaapi.calc_thunk_func_target(func, temp_ptr.cast())
if ea_new != idaapi.BADADDR:
ea = ea_new
propagated_name = get_func_name(ea) or '' # Ensure it is not `None`
if len(current_name) > len(propagated_name) > 0:
return propagated_name
else:
return current_name
# Fallback to non-propagated name for weird times that IDA gives
# a 0 length name, or finds a longer import name
for ea in idautils.Segments():
fs = idautils.Functions(idc.SegStart(ea), idc.SegEnd(ea))
for f in fs:
out.write('("%s" 0x%x 0x%x)\n' % (
func_name_propagate_thunk(f),
idc.GetFunctionAttr(f, idc.FUNCATTR_START),
idc.GetFunctionAttr(f, idc.FUNCATTR_END)))
def get_user_functions():
user_functions = []
for fva in idautils.Functions():
f_attr = idc.GetFunctionAttr(fva, idc.FUNCATTR_FLAGS)
if not f_attr & idc.FUNC_LIB and not f_attr & idc.FUNC_THUNK:
user_functions.append(fva)
return user_functions
def getMinorDispatchTableAddress(ea):
"""find address of last lea in function"""
start = idc.GetFunctionAttr(ea, idc.FUNCATTR_START)
end = idc.PrevHead( idc.GetFunctionAttr(ea, idc.FUNCATTR_END), start)
res = prevMnemonic(end, 'lea', start)
assert res != idc.BADADDR
return idc.GetOperandValue(res, 1)
def getMajorDispatchTableAddress():
"""find quicktime major dispatch table"""
res = idc.LocByName('theQuickTimeDispatcher')
res = nextMnemonic(res, 'lea', idc.GetFunctionAttr(res, idc.FUNCATTR_END))
assert res != idc.BADADDR
return idc.GetOperandValue(res, 1)
def activate(self, ctx):
hx_view = idaapi.get_tform_vdui(ctx.form)
address = hx_view.cfunc.entry_ea
xref_ea = idaapi.get_first_cref_to(address)
xrefs = set()
while xref_ea != idaapi.BADADDR:
xref_func_ea = idc.GetFunctionAttr(xref_ea, idc.FUNCATTR_START)
if xref_func_ea != idaapi.BADADDR:
xrefs.add(xref_func_ea)
else:
print "[Warning] Function not found at 0x{0:08X}".format(xref_ea)
xref_ea = idaapi.get_next_cref_to(address, xref_ea)
for func_ea in xrefs:
visitor = VariableLookupVisitor(address)
try:
cfunc = idaapi.decompile(func_ea)
if cfunc:
FunctionTouchVisitor(cfunc).process()
visitor.apply_to(cfunc.body, None)
for idx in visitor.result:
scanner = DeepSearchVisitor(cfunc, 0, idx)
scanner.process()
for field in scanner.candidates:
self.temporary_structure.add_row(field)
except idaapi.DecompilationFailure:
print "[Warning] Failed to decompile function at 0x{0:08X}".format(xref_ea)
DeepSearchVisitor.clear()