def resolveStackAddress(self, address, symbol):
if symbol[0] == "0x0":
return None
info = {}
info['module'] = str(symbol[1])
segm = get_segm_by_name(info['module'])
if segm is not None:
locEA = segm.startEA
delta = address - int(symbol[0], 16) + locEA
func = get_func(delta)
if func is not None:
info['symbol'] = str(get_func_name(delta))
else:
info['symbol'] = str(GetDisasm(delta))
elif symbol[2] != '':
if symbol[2] == '<redacted>':
info['symbol'] = "+0x%X" % (address - int(symbol[0], 16))
else:
info['symbol'] = str(symbol[2])
else:
info['symbol'] = ''
return info
python类get_func_name()的实例源码
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_all_funcs():
"""
Enumerate all function names defined in the IDB.
"""
return set(idaapi.get_func_name(ea) for ea in idautils.Functions())
def get_name(func):
'''Return the name of the function ``func``.'''
rt,ea = __addressOfRtOrSt(func)
if rt:
res = idaapi.get_name(-1, ea)
return internal.declaration.demangle(res) if internal.declaration.mangled(res) else res
#return internal.declaration.extract.fullname(internal.declaration.demangle(res)) if internal.declaration.mangled(res) else res
res = idaapi.get_func_name(ea)
if not res: res = idaapi.get_name(-1, ea)
if not res: res = idaapi.get_true_name(ea, ea)
return res
#return internal.declaration.extract.fullname(internal.declaration.demangle(res)) if internal.declaration.mangled(res) else res
#return internal.declaration.extract.name(internal.declaration.demangle(res)) if internal.declaration.mangled(res) else res
def get_name(func):
'''Return the name of the function ``func``.'''
rt,ea = __addressOfRtOrSt(func)
if rt:
res = idaapi.get_name(-1, ea)
return internal.declaration.demangle(res) if internal.declaration.mangled(res) else res
#return internal.declaration.extract.fullname(internal.declaration.demangle(res)) if internal.declaration.mangled(res) else res
res = idaapi.get_func_name(ea)
if not res: res = idaapi.get_name(-1, ea)
if not res: res = idaapi.get_true_name(ea, ea)
return res
#return internal.declaration.extract.fullname(internal.declaration.demangle(res)) if internal.declaration.mangled(res) else res
#return internal.declaration.extract.name(internal.declaration.demangle(res)) if internal.declaration.mangled(res) else res
def get_name(func):
'''Return the name of the function ``func``.'''
rt,ea = __addressOfRtOrSt(func)
if rt:
res = idaapi.get_name(-1, ea)
return internal.declaration.demangle(res) if internal.declaration.mangled(res) else res
#return internal.declaration.extract.fullname(internal.declaration.demangle(res)) if internal.declaration.mangled(res) else res
res = idaapi.get_func_name(ea)
if not res: res = idaapi.get_name(-1, ea)
if not res: res = idaapi.get_true_name(ea, ea)
return res
#return internal.declaration.extract.fullname(internal.declaration.demangle(res)) if internal.declaration.mangled(res) else res
#return internal.declaration.extract.name(internal.declaration.demangle(res)) if internal.declaration.mangled(res) else res
def get_name(func):
'''Return the name of the function ``func``.'''
rt,ea = __addressOfRtOrSt(func)
if rt:
res = idaapi.get_name(-1, ea)
return internal.declaration.demangle(res) if internal.declaration.mangled(res) else res
#return internal.declaration.extract.fullname(internal.declaration.demangle(res)) if internal.declaration.mangled(res) else res
res = idaapi.get_func_name(ea)
if not res: res = idaapi.get_name(-1, ea)
if not res: res = idaapi.get_true_name(ea, ea)
return res
#return internal.declaration.extract.fullname(internal.declaration.demangle(res)) if internal.declaration.mangled(res) else res
#return internal.declaration.extract.name(internal.declaration.demangle(res)) if internal.declaration.mangled(res) else res
def get_name(func):
'''Return the name of the function ``func``.'''
rt,ea = __addressOfRtOrSt(func)
if rt:
res = idaapi.get_name(-1, ea)
return internal.declaration.demangle(res) if internal.declaration.mangled(res) else res
#return internal.declaration.extract.fullname(internal.declaration.demangle(res)) if internal.declaration.mangled(res) else res
res = idaapi.get_func_name(ea)
if not res: res = idaapi.get_name(-1, ea)
if not res: res = idaapi.get_true_name(ea, ea)
return res
#return internal.declaration.extract.fullname(internal.declaration.demangle(res)) if internal.declaration.mangled(res) else res
#return internal.declaration.extract.name(internal.declaration.demangle(res)) if internal.declaration.mangled(res) else res
def get_name(func):
'''Return the name of the function ``func``.'''
rt,ea = __addressOfRtOrSt(func)
if rt:
res = idaapi.get_name(-1, ea)
return internal.declaration.demangle(res) if internal.declaration.mangled(res) else res
#return internal.declaration.extract.fullname(internal.declaration.demangle(res)) if internal.declaration.mangled(res) else res
res = idaapi.get_func_name(ea)
if not res: res = idaapi.get_name(-1, ea)
if not res: res = idaapi.get_true_name(ea, ea)
return res
#return internal.declaration.extract.fullname(internal.declaration.demangle(res)) if internal.declaration.mangled(res) else res
#return internal.declaration.extract.name(internal.declaration.demangle(res)) if internal.declaration.mangled(res) else res
def GetFunctionName(ea):
"""
Retrieve function name
@param ea: any address belonging to the function
@return: null string - function doesn't exist
otherwise returns function name
"""
name = idaapi.get_func_name(ea)
if not name:
return ""
else:
return name
def traverse_xrefs(func):
func_created = 0
if func is None:
return func_created
# First
func_xref = idaapi.get_first_cref_to(func.startEA)
# Attempt to go through crefs
while func_xref != BADADDR:
# See if there is a function already here
if idaapi.get_func(func_xref) is None:
# Ensure instruction bit looks like a jump
func_end = FindCode(func_xref, SEARCH_DOWN)
if GetMnem(func_end) == "jmp":
# Ensure we're jumping back "up"
func_start = GetOperandValue(func_end, 0)
if func_start < func_xref:
if idc.MakeFunction(func_start, func_end):
func_created += 1
else:
# If this fails, we should add it to a list of failed functions
# Then create small "wrapper" functions and backtrack through the xrefs of this
error('Error trying to create a function @ 0x%x - 0x%x' %(func_start, func_end))
else:
xref_func = idaapi.get_func(func_xref)
# Simple wrapper is often runtime_morestack_noctxt, sometimes it isn't though...
if is_simple_wrapper(xref_func.startEA):
debug('Stepping into a simple wrapper')
func_created += traverse_xrefs(xref_func)
if idaapi.get_func_name(xref_func.startEA) is not None and 'sub_' not in idaapi.get_func_name(xref_func.startEA):
debug('Function @0x%x already has a name of %s; skipping...' % (func_xref, idaapi.get_func_name(xref_func.startEA)))
else:
debug('Function @ 0x%x already has a name %s' % (xref_func.startEA, idaapi.get_func_name(xref_func.startEA)))
func_xref = idaapi.get_next_cref_to(func.startEA, func_xref)
return func_created
def find_func_by_name(name):
text_seg = get_text_seg()
if text_seg is None:
return None
for addr in Functions(text_seg.startEA, text_seg.endEA):
if name == idaapi.get_func_name(addr):
return idaapi.get_func(addr)
return None
def renamer_init():
renamed = 0
gopclntab = get_gopclntab_seg()
if gopclntab is not None:
# Skip unimportant header and goto section size
addr = gopclntab.startEA + 8
size, addr_size = create_pointer(addr)
addr += addr_size
# Unsure if this end is correct
early_end = addr + (size * addr_size * 2)
while addr < early_end:
func_offset, addr_size = create_pointer(addr)
name_offset, addr_size = create_pointer(addr + addr_size)
addr += addr_size * 2
func_name_addr = Dword(name_offset + gopclntab.startEA + addr_size) + gopclntab.startEA
func_name = GetString(func_name_addr)
MakeStr(func_name_addr, func_name_addr + len(func_name))
appended = clean_func_name = clean_function_name(func_name)
debug('Going to remap function at 0x%x with %s - cleaned up as %s' % (func_offset, func_name, clean_func_name))
if idaapi.get_func_name(func_offset) is not None:
if MakeName(func_offset, clean_func_name):
renamed += 1
else:
error('clean_func_name error %s' % clean_func_name)
return renamed
# Function pointers are often used instead of passing a direct address to the
# function -- this function names them based off what they're currently named
# to ease reading
#
# lea rax, main_GetExternIP_ptr <-- pointer to actual function
# mov [rsp+1C0h+var_1B8], rax <-- loaded as arg for next function
# call runtime_newproc <-- function is used inside a new process
def handleQuickFuncHook(self, address, once):
# safety checks, can be start of the function
if address in self.idbHookMap and self.idbHookMap[address].hook.type == "inst":
dlg = AskYN(0, "Address contains instruction hook!\nDo you want to remove it?")
if dlg != 1:
return
# remove instruction hook
self.handleUnhookInst(address)
offset, moduleName = self.getAddressDetails(address)
hook = FuncHook()
hook.id = address
hook.symbol = get_func_name(address)
hook.address = offset
hook.module = moduleName
hook.once = once
entry = HookEntry(hook)
outJSON = json.dumps({
"req_id": kFridaLink_SetHookRequest,
"data": entry.genSetRequest()
})
SetColor(address, CIC_FUNC, kIDAViewColor_HookedFunc)
refresh_idaview_anyway()
self.clientSocket.sendto(outJSON, self.clientAddress)
self.idbHookMap[address] = entry
self.idbHooksView.setContent(self.idbHookMap)
def _feature_name(self,f_ea):
return idaapi.get_func_name(f_ea)
def _feature_ClsorInstMethod(self,f_ea):
'''
prior feature: Null
'''
func_name = idaapi.get_func_name(f_ea)
disable_mask = idc.GetLongPrm(idc.INF_LONG_DN)
prototype = idaapi.demangle_name(func_name, disable_mask)
if not prototype:
return 0
elif '__thiscall' in prototype:
return 1
else:
return 0
def copy_function(addr):
func_addr = idc.LocByName(idaapi.get_func_name(addr))
if func_addr == idaapi.BADADDR:
idaapi.msg("0x%08X does not belong to a defined function\n" % addr)
return
callTypes = ["__cdecl", "__fastcall", "__stdcall", "__thiscall", "__usercall"]
funcDef = str(idaapi.decompile(func_addr)).split('\n', 1)[0]
hasCallType = any(call_type in funcDef for call_type in callTypes)
parenthesesStart = funcDef.find('(')
parenthesesEnd = funcDef.rfind(')')
funcNameStart = funcDef[0 : parenthesesStart].rfind(' ')
funcNameEnd = parenthesesStart
returnTypeStart = 0
returnTypeEnd = funcNameStart
callType = ""
if hasCallType:
callTypeStart = funcDef[0 : funcNameStart].rfind(' ')
callType = funcDef[callTypeStart + 1 : funcNameStart]
returnTypeEnd = callTypeStart
if callType == "__cdecl":
callType = ""
returnType = funcDef[returnTypeStart : returnTypeEnd]
funcName = funcDef[funcNameStart + 1 : parenthesesStart]
args = funcDef[parenthesesStart + 1 : parenthesesEnd]
finalString = "{0} ({1}* {2})({3}) = ({0}({1}*)({3}))({4});".format(
returnType, callType, funcName, args, "0x%08X" % func_addr
)
return finalString
def get_all_funcs():
return set(idaapi.get_func_name(ea) for ea in idautils.Functions())
def apply_labels(fun_names):
new_sub = 0
new_som = 0
new_oth = 0
named_overwrittens = []
for f_ea, name in fun_names.iteritems():
name = re.sub('[^a-zA-Z0-9_]+', '', name)
curr_name = idaapi.get_func_name(f_ea)
if curr_name.startswith("sub_"):
new_sub += 1
elif "_something" in curr_name:
new_som += 1
else:
new_oth += 1
named_overwrittens.append(curr_name)
#so we don't overwrite these
continue
# stats counting aside, make sure we don't overwrite non-sub
# functions from e.g. our IDC assignments
if not curr_name.startswith("sub_") and not "_something" in curr_name:
continue
ret = idc.LocByName(name)
count = 1
while (ret != 0xffffffff):
count += 1
ret = idc.LocByName(name + "__" + "%d" % count)
idc.MakeName(f_ea, name + ("__%d" % count)*(count > 1))
def recursive_prefix(addr):
"""
Recursively prefix a function tree with a user defined string.
"""
func_addr = idaapi.get_name_ea(idaapi.BADADDR, idaapi.get_func_name(addr))
if func_addr == idaapi.BADADDR:
idaapi.msg("Prefix: 0x%08X does not belong to a defined function\n" % addr)
return
# NOTE / COMPAT:
# prompt the user for a prefix to apply to the selected functions
if using_ida7api:
tag = idaapi.ask_str(PREFIX_DEFAULT, 0, "Function Tag")
else:
tag = idaapi.askstr(0, PREFIX_DEFAULT, "Function Tag")
# the user closed the window... ignore
if tag == None:
return
# the user put a blank string and hit 'okay'... notify & ignore
elif tag == '':
idaapi.warning("[ERROR] Tag cannot be empty [ERROR]")
return
# recursively collect all the functions called by this function
nodes_xref_down = graph_down(func_addr, path=set([]))
# graph_down returns the int address needs to be converted
tmp = []
tmp1 = ''
for func_addr in nodes_xref_down:
tmp1 = idaapi.get_func_name(func_addr)
if tmp1:
tmp.append(tmp1)
nodes_xref_down = tmp
# prefix the tree of functions
for rename in nodes_xref_down:
func_addr = idaapi.get_name_ea(idaapi.BADADDR, rename)
if tag not in rename:
idaapi.set_name(func_addr,'%s%s%s' % (str(tag), PREFIX_SEPARATOR, rename), idaapi.SN_NOWARN)
# refresh the IDA views
refresh_views()
def handleHookFuncCust(self, screenEA = None):
if screenEA is not None:
func = get_func(screenEA)
else:
func = get_func(ScreenEA())
if func is None:
return
address = func.startEA;
# safety checks, can be start of the function
if address in self.idbHookMap and self.idbHookMap[address].hook.type == "inst":
dlg = AskYN(0, "Address contains instruction hook!\nDo you want to remove it?")
if dlg != 1:
return
# remove instruction hook
self.handleUnhookInst(address)
offset, moduleName = self.getAddressDetails(address)
hookDlg = FunctionHookDialog(moduleName, "%X" % address, get_func_name(address), None, None)
hookDlg.Compile()
hookDlg.script_enter.value = ""
hookDlg.script_leave.value = ""
ok = hookDlg.Execute()
if ok != 1:
return
hook = FuncHook()
hook.id = address
hook.symbol = get_func_name(address)
hook.address = offset
hook.module = moduleName
hook.once = True if hookDlg.trigger.value == 0 else False
hook.enterRecentSrcFile = hookDlg.recentScriptFileEnter
hook.enterScript = hookDlg.script_enter.value
hook.leaveRecentSrcFile = hookDlg.recentScriptFileLeave
hook.leaveScript = hookDlg.script_leave.value
entry = HookEntry(hook)
outJSON = json.dumps({
"req_id": kFridaLink_SetHookRequest,
"data": entry.genSetRequest()
})
SetColor(address, CIC_FUNC, kIDAViewColor_HookedFunc)
refresh_idaview_anyway()
self.clientSocket.sendto(outJSON, self.clientAddress)
self.idbHookMap[address] = entry
self.idbHooksView.setContent(self.idbHookMap)
def handleHookFuncEdit(self, screenEA = None):
if self.hookedFunction() == False:
return
if screenEA is not None:
func = get_func(screenEA)
else:
func = get_func(ScreenEA())
if func is None:
return
address = func.startEA;
entry = self.idbHookMap[address]
entry.hook.symbol = get_func_name(address)
hookDlg = FunctionHookDialog(entry.hook.module, "%X" % entry.hook.id, entry.hook.symbol, entry.hook.enterRecentSrcFile, entry.hook.leaveRecentSrcFile)
hookDlg.Compile()
hookDlg.script_enter.value = entry.hook.enterScript
hookDlg.script_leave.value = entry.hook.leaveScript
hookDlg.trigger.value = 0 if entry.hook.once == True else 1
ok = hookDlg.Execute()
if ok != 1:
return
flags = HookEntry.UDP_NONE
once = True if hookDlg.trigger.value == 0 else False
if entry.hook.once != once:
entry.hook.once = once
flags |= HookEntry.UPD_TRIGGER
entry.hook.enterRecentSrcFile = hookDlg.recentScriptFileEnter
if entry.hook.enterScript != hookDlg.script_enter.value:
entry.hook.enterScript = hookDlg.script_enter.value
flags |= HookEntry.UPD_SCRIPT
entry.hook.leaveRecentSrcFile = hookDlg.recentScriptFileLeave
if entry.hook.leaveScript != hookDlg.script_leave.value:
entry.hook.leaveScript = hookDlg.script_leave.value
flags |= HookEntry.UPD_SCRIPT
outJSON = json.dumps({
"req_id": kFridaLink_UpdHookRequest,
"data": entry.genUpdRequest(flags)
})
self.clientSocket.sendto(outJSON, self.clientAddress)
def handleReplaceFunc(self, screenEA = None):
if screenEA is not None:
func = get_func(screenEA)
else:
func = get_func(ScreenEA())
if func is None:
return
address = func.startEA;
offset, moduleName = self.getAddressDetails(address)
replaceDlg = FunctionReplaceDialog(moduleName, "%X" % address, get_func_name(address), None)
replaceDlg.Compile()
replaceDlg.script.value = ""
ok = replaceDlg.Execute()
if ok != 1:
return
replace = FuncReplace()
replace.id = address
replace.symbol = get_func_name(address)
replace.address = offset
replace.module = moduleName
replace.moduleImport = False
replace.ret_type = "\'" + replaceDlg.ret_type.value + "\'"
replace.recentSrcFile = replaceDlg.recentScriptFile
replace.script = replaceDlg.script.value
replace.args_str = replaceDlg.args.value
replace.arg_types = ""
replace.arg_names = ""
if replace.args_str != "":
args_list = replace.args_str.split(",")
for arg in args_list:
arg_list = arg.split()
replace.arg_types += "\'" + arg_list[0] + "\', "
replace.arg_names += arg_list[1] + ", "
replace.arg_types = replace.arg_types[:-2]
replace.arg_names = replace.arg_names[:-2]
outJSON = json.dumps({
"req_id": kFridaLink_SetReplaceRequest,
"data": replace.genSetRequest()
})
SetColor(address, CIC_FUNC, kIDAViewColor_ReplacedFunc)
refresh_idaview_anyway()
self.clientSocket.sendto(outJSON, self.clientAddress)
self.funcReplaceMap[address] = replace
self.funcReplaceView.setContent(self.funcReplaceMap)