def scan_functions(self): from mybase import function self.logger.info("For function %s:" % idc.GetFunctionName(self.ea)) for ea in function.iterate(self.ea): for xref in idautils.XrefsFrom(ea, 0): if idautils.XrefTypeName(xref.type) == 'Code_Near_Call' or\ idautils.XrefTypeName(xref.type) == 'Code_Far_Call': self.logger.info("found call at %s --> %s" % (hex(ea), idc.GetFunctionName(xref.to))) #skip constructors fn = FunctionName(idc.GetFunctionName(xref.to)) if fn.namespace == fn.basename: continue tif = idaapi.tinfo_t() if idaapi.get_tinfo2(xref.to, tif): funcdata = idaapi.func_type_data_t() tif.get_func_details(funcdata) #funcdata.get_call_method() if funcdata.size() >= 1 and funcdata[0].name == "this": self.funcs.add( FunctionName(idc.GetFunctionName(xref.to))) self.logger.info("Call to %s found" % idc.GetFunctionName(xref.to)) else: self.logger.info("idaapi.get_tinfo2 failed") self.logger.info("%d subcalls found" % len(self.funcs))
def get_func_details(func_ea): xfunc = ida_hexrays.decompile(func_ea) if xfunc is None: return None func_details = idaapi.func_type_data_t() xfunc.type.get_func_details(func_details) return func_details
def get_func_arg_name(func_tinfo, arg_idx): # type: (idaapi.tinfo_t, int) -> str func_data = idaapi.func_type_data_t() func_tinfo.get_func_details(func_data) if arg_idx < func_tinfo.get_nargs(): return func_data[arg_idx].name
def set_func_arg_name(func_tinfo, arg_idx, name): # type: (idaapi.tinfo_t, int, str) -> None func_data = idaapi.func_type_data_t() func_tinfo.get_func_details(func_data) func_data[arg_idx].name = name func_tinfo.create_func(func_data)
def init(): """ All tinfo should be reinitialized between session. Otherwise they could have wrong type """ global VOID_TINFO, PVOID_TINFO, CONST_PVOID_TINFO, BYTE_TINFO, PBYTE_TINFO, LEGAL_TYPES, X_WORD_TINFO, \ PX_WORD_TINFO, DUMMY_FUNC, CONST_PCHAR_TINFO, CHAR_TINFO, PCHAR_TINFO, CONST_VOID_TINFO, \ WORD_TINFO, PWORD_TINFO, EA64, EA_SIZE EA64 = idaapi.get_inf_structure().is_64bit() EA_SIZE = 8 if EA64 else 4 VOID_TINFO = idaapi.tinfo_t(idaapi.BT_VOID) PVOID_TINFO.create_ptr(VOID_TINFO) CONST_VOID_TINFO = idaapi.tinfo_t(idaapi.BT_VOID | idaapi.BTM_CONST) CONST_PVOID_TINFO.create_ptr( idaapi.tinfo_t(idaapi.BT_VOID | idaapi.BTM_CONST)) CONST_PCHAR_TINFO.create_ptr( idaapi.tinfo_t(idaapi.BTF_CHAR | idaapi.BTM_CONST)) CHAR_TINFO = idaapi.tinfo_t(idaapi.BTF_CHAR) PCHAR_TINFO.create_ptr(idaapi.tinfo_t(idaapi.BTF_CHAR)) BYTE_TINFO = idaapi.tinfo_t(idaapi.BTF_BYTE) PBYTE_TINFO = idaapi.dummy_ptrtype(1, False) X_WORD_TINFO = idaapi.get_unk_type(EA_SIZE) PX_WORD_TINFO = idaapi.dummy_ptrtype(EA_SIZE, False) WORD_TINFO = idaapi.tinfo_t(idaapi.BT_UNK_WORD) PWORD_TINFO.create_ptr(idaapi.tinfo_t(idaapi.BT_UNK_WORD)) func_data = idaapi.func_type_data_t() func_data.rettype = PVOID_TINFO func_data.cc = idaapi.CM_CC_UNKNOWN DUMMY_FUNC = idaapi.tinfo_t() DUMMY_FUNC.create_func(func_data, idaapi.BT_FUNC) LEGAL_TYPES = [ PVOID_TINFO, PX_WORD_TINFO, PWORD_TINFO, PBYTE_TINFO, X_WORD_TINFO ]
def ParseAMXNativeInfo(): ida_string = idautils.Strings() last_native = "" for string in ida_string: for native in natives: if (str(string) == native and last_native != native): last_native = native for xref in XrefsTo(string.ea): offset = xref.frm + 4 for native_addr in XrefsFrom(offset): # Rename native handler function n_NativeName idc.MakeNameEx(native_addr.to, "n_" + native, idc.SN_NOWARN) # Setup function prototype & automate setting the native's tinfo = idaapi.tinfo_t() ida_typeinf.guess_tinfo(native_addr.to, tinfo) funcdata = idaapi.func_type_data_t() tinfo.get_func_details(funcdata) tinfo2 = idaapi.tinfo_t() tinfo2.get_named_type(idaapi.get_idati(), "Native" + native + "Params") tinfo3 = idaapi.tinfo_t() tinfo3.create_ptr(tinfo2) if ( len(funcdata) ): # For some reason this is 0 for some natives with params? Not sure why... funcdata[len(funcdata) - 1].type = tinfo3 function_tinfo = idaapi.tinfo_t() function_tinfo.create_func(funcdata) idaapi.apply_tinfo2(native_addr.to, function_tinfo, idaapi.TINFO_DEFINITE)
def init(): VOID_TINFO = idaapi.tinfo_t( idaapi.BTF_VOID) # make no sense lol `BT_VOID | 0` PVOID_TINFO.create_ptr(VOID_TINFO) CHAR_TINFO = idaapi.tinfo_t(idaapi.BTF_CHAR) PCHAR_TINFO.create_ptr(idaapi.tinfo_t(CHAR_TINFO)) BYTE_TINFO = idaapi.tinfo_t(idaapi.BTF_BYTE) PBYTE_TINFO.create_ptr(BYTE_TINFO) WORD_TINFO = idaapi.get_unk_type(2) PWORD_TINFO.create_ptr(WORD_TINFO) DWORD_TINFO = idaapi.get_unk_type(4) PDWORD_TINFO.create_ptr(DWORD_TINFO) QWORD_TINFO = idaapi.get_unk_type(8) PQWORD_TINFO.create_ptr(QWORD_TINFO) XWORD_TINFO = idaapi.get_unk_type(util.get_bitness() >> 3) PXWORD_TINFO.create_ptr(XWORD_TINFO) func_data = idaapi.func_type_data_t() func_data.rettype = PVOID_TINFO func_data.cc = idaapi.CM_CC_UNKNOWN DUMMY_FUNC.create_func(func_data, idaapi.BT_FUNC) assert PVOID_TINFO.get_pointed_object() == VOID_TINFO assert PCHAR_TINFO.get_pointed_object() == CHAR_TINFO assert PBYTE_TINFO.get_pointed_object() == BYTE_TINFO assert PWORD_TINFO.get_pointed_object() == WORD_TINFO assert PDWORD_TINFO.get_pointed_object() == DWORD_TINFO assert PQWORD_TINFO.get_pointed_object() == QWORD_TINFO assert PXWORD_TINFO.get_pointed_object() == XWORD_TINFO
def process_funcs(all_funcs): for func in all_funcs: # rename idc.set_name(func.start_ea, f"string_{func.start_ea:X}") # set type struc_id = idaapi.get_struc_id("std::string") # print(f"{struc_id:x}") if struc_id == idaapi.BADADDR: idc.set_local_type(-1, "struct std::string {char *ptr; size_t length; char buf[0x10];};", idaapi.PT_TYP) print("create std::string") func_tinfo = idaapi.tinfo_t() cfunc = idaapi.decompile(func.start_ea) cfunc.get_func_type(func_tinfo) func_details = idaapi.func_type_data_t() func_tinfo.get_func_details(func_details) std_string_tinfo = idaapi.tinfo_t() std_string_tinfo.get_named_type(idaapi.get_idati(), "std::string") std_string_ptr_tinfo = idaapi.tinfo_t() std_string_ptr_tinfo.create_ptr(std_string_tinfo) func_details[0].type = std_string_ptr_tinfo func_tinfo.create_func(func_details) idaapi.apply_tinfo(func.start_ea, func_tinfo, idaapi.TINFO_DEFINITE)
def get_func_type(f_start): tif = ida_typeinf.tinfo_t() idaapi.get_tinfo2(f_start, tif) funcdata = idaapi.func_type_data_t() got_data = tif.get_func_details(funcdata) if got_data: return funcdata else: return None
def get_func_details(funcea): """@return: func_type_data_t""" func_tif = deserialize_tinfo(get_func_type(funcea)) if func_tif is None: log.warning("%08X Couldn't get func type", funcea) return None func_details = idaapi.func_type_data_t() if not func_tif.get_func_details(func_details): log.warning("%08X Couldn't get func type details", funcea) return None return func_details
def get_type(addr): tif = idaapi.tinfo_t() idaapi.get_tinfo2(addr, tif) funcdata = idaapi.func_type_data_t() tif.get_func_details(funcdata) func_type = idaapi.print_tinfo("", 0, 0, PRTYPE_1LINE, tif, "", "") ret_type = idaapi.print_tinfo("", 0, 0, PRTYPE_1LINE, funcdata.rettype, "", "") args = [] for i in xrange(funcdata.size()): arg_type = idaapi.print_tinfo("", 0, 0, PRTYPE_1LINE, funcdata[i].type, "", "") args.append([i, funcdata[i].name, arg_type, funcdata[i].argloc.atype()]) return [func_type, ret_type, args]
def serialize(tif: idaapi.tinfo_t) -> typing.Union[dict, None]: fi = idaapi.func_type_data_t() if not tif.get_func_details(fi): return None args = [{"type": str(arg.type), "name": arg.name} for arg in fi] return ({ 'args': args, 'ret_type': str(fi.rettype), 'cc': '__stdcall' if fi.cc == idaapi.CM_CC_STDCALL else '__cdecl' })
def remove_rettype(vu): if vu.item.citype == idaapi.VDI_FUNC: # current function ea = vu.cfunc.entry_ea old_func_type = idaapi.tinfo_t() if not vu.cfunc.get_func_type(old_func_type): return False elif vu.item.citype == idaapi.VDI_EXPR and vu.item.e.is_expr( ) and vu.item.e.type.is_funcptr(): # call xxx ea = vu.item.get_ea() old_func_type = idaapi.tinfo_t() func = idaapi.get_func(ea) if func: try: cfunc = idaapi.decompile(func) except idaapi.DecompilationFailure: return False if not cfunc.get_func_type(old_func_type): return False else: return False else: return False fi = idaapi.func_type_data_t() if ea != idaapi.BADADDR and old_func_type.get_func_details(fi): # Return type is already void if fi.rettype.is_decl_void(): # Restore ret type if ea not in ret_type: return True ret = ret_type[ea] else: # Save ret type and change it to void ret_type[ea] = fi.rettype ret = idaapi.BT_VOID # Create new function info with new rettype fi.rettype = idaapi.tinfo_t(ret) # Create new function type with function info new_func_type = idaapi.tinfo_t() new_func_type.create_func(fi) # Apply new function type if idaapi.apply_tinfo2(ea, new_func_type, idaapi.TINFO_DEFINITE): return vu.refresh_view(True) return False
def activate(self, ctx): hx_view = idaapi.get_tform_vdui(ctx.form) result = self.check(hx_view.cfunc, hx_view.item) if result: func_tinfo, address, arg_index, name = result func_data = idaapi.func_type_data_t() func_tinfo.get_func_details(func_data) func_data[arg_index].name = name new_func_tinfo = idaapi.tinfo_t() new_func_tinfo.create_func(func_data) idaapi.apply_tinfo2(address, new_func_tinfo, idaapi.TINFO_DEFINITE)
def remove_rettype(self, vu): if vu.item.citype == idaapi.VDI_FUNC: # current function ea = vu.cfunc.entry_ea old_func_type = idaapi.tinfo_t() if not vu.cfunc.get_func_type(old_func_type): return False elif vu.item.citype == idaapi.VDI_EXPR and vu.item.e.is_expr() and vu.item.e.type.is_funcptr(): # call xxx ea = vu.item.get_ea() old_func_type = idaapi.tinfo_t() func = idaapi.get_func(ea) if func: try: cfunc = idaapi.decompile(func) except idaapi.DecompilationFailure: return False if not cfunc.get_func_type(old_func_type): return False else: return False else: return False fi = idaapi.func_type_data_t() if ea != idaapi.BADADDR and old_func_type.get_func_details(fi): # Return type is already void if fi.rettype.is_decl_void(): # Restore ret type if ea not in self.ret_type: return True ret = self.ret_type[ea] else: # Save ret type and change it to void self.ret_type[ea] = fi.rettype ret = idaapi.BT_VOID # Create new function info with new rettype fi.rettype = idaapi.tinfo_t(ret) # Create new function type with function info new_func_type = idaapi.tinfo_t() new_func_type.create_func(fi) # Apply new function type if idaapi.apply_tinfo2(ea, new_func_type, idaapi.TINFO_DEFINITE): return vu.refresh_view(True) return False
def __init__(self, ti): self.ti = ti self.extra = None if self.ti.is_func(): self.extra = idaapi.func_type_data_t() if not self.ti.get_func_details(self.extra): print "[-] can't get function's type details" return elif self.ti.is_struct(): self.extra = idaapi.udt_type_data_t() if not self.ti.get_udt_details(self.extra): print "[-] can't get struct's type details" return
def activate(self, ctx): vu = idaapi.get_tform_vdui(ctx.form) function_tinfo = idaapi.tinfo_t() if not vu.cfunc.get_func_type(function_tinfo): return function_details = idaapi.func_type_data_t() function_tinfo.get_func_details(function_details) del_arg = vu.item.get_lvar() # lvar_t function_details.erase(filter(lambda x: x.name == del_arg.name, function_details)[0]) function_tinfo.create_func(function_details) idaapi.apply_tinfo2(vu.cfunc.entry_ea, function_tinfo, idaapi.TINFO_DEFINITE) vu.refresh_view(True)
def activate(self, ctx): vu = idaapi.get_widget_vdui(ctx.widget) function_tinfo = idaapi.tinfo_t() if not vu.cfunc.get_func_type(function_tinfo): return function_details = idaapi.func_type_data_t() function_tinfo.get_func_details(function_details) if function_details.rettype.equals_to(const.VOID_TINFO): function_details.rettype = idaapi.tinfo_t(const.PVOID_TINFO) else: function_details.rettype = idaapi.tinfo_t(idaapi.BT_VOID) function_tinfo.create_func(function_details) idaapi.apply_tinfo(vu.cfunc.entry_ea, function_tinfo, idaapi.TINFO_DEFINITE) vu.refresh_view(True)
def activate(self, ctx): # ctx - action_activation_ctx_t vu = idaapi.get_tform_vdui(ctx.form) function_tinfo = idaapi.tinfo_t() if not vu.cfunc.get_func_type(function_tinfo): return function_details = idaapi.func_type_data_t() function_tinfo.get_func_details(function_details) if function_details.rettype.equals_to(Const.VOID_TINFO): function_details.rettype = idaapi.tinfo_t(Const.PVOID_TINFO) else: function_details.rettype = idaapi.tinfo_t(idaapi.BT_VOID) function_tinfo.create_func(function_details) idaapi.set_tinfo2(vu.cfunc.entry_ea, function_tinfo) vu.refresh_view(True)
def activate(self, ctx): vu = idaapi.get_widget_vdui(ctx.widget) function_tinfo = idaapi.tinfo_t() if not vu.cfunc.get_func_type(function_tinfo): return function_details = idaapi.func_type_data_t() function_tinfo.get_func_details(function_details) del_arg = vu.item.get_lvar() function_details.erase( [x for x in function_details if x.name == del_arg.name][0]) function_tinfo.create_func(function_details) idaapi.apply_tinfo(vu.cfunc.entry_ea, function_tinfo, idaapi.TINFO_DEFINITE) vu.refresh_view(True)
def resolve_objc_self_to_class(self, ea): ''' Get the objective c class for the current function RDI value based on the class of the first argument to the current function ''' f_start = idc.get_func_attr(ea, idc.FUNCATTR_START) tif = ida_typeinf.tinfo_t() idaapi.get_tinfo2(f_start, tif) funcdata = idaapi.func_type_data_t() tif.get_func_details(funcdata) # not happy about casting to a string and then regex replacing... but that's the best I could come up with replace_reg = re.compile(' \*', re.IGNORECASE) objc_self_type = funcdata[0].type return objc_self_type
def fixFuncType(ea): funcEa = GetFunctionAttr(ea, FUNCATTR_START) cfunc = idaapi.decompile(funcEa) old_func_type = idaapi.tinfo_t() cfunc.get_func_type(old_func_type) fi = idaapi.func_type_data_t() if old_func_type.get_func_details(fi): if (fi.cc == idaapi.CM_CC_SPECIAL) or ( fi.cc == idaapi.CM_CC_SPECIALE) or (fi.cc == idaapi.CM_CC_SPECIALP): fi.cc = idaapi.CM_CC_FASTCALL new_func_type = idaapi.tinfo_t() new_func_type.create_func(fi) idaapi.apply_tinfo2(funcEa, new_func_type, idaapi.TINFO_DEFINITE)
def check(cfunc, ctree_item): if ctree_item.citype != idaapi.VDI_EXPR: return False expression = ctree_item.it.to_specific_type if expression.op == idaapi.cot_var: lvar = ctree_item.get_lvar() # Check if it's either variable with user name or argument with not standard `aX` name if lvar.has_user_name or lvar.is_arg_var and re.search("a\d*$", lvar.name) is None: parent = cfunc.body.find_parent_of(expression).to_specific_type if parent.op == idaapi.cot_call: arg_index, _ = Helper.get_func_argument_info(parent, expression) func_tinfo = parent.x.type.get_pointed_object() func_data = idaapi.func_type_data_t() func_tinfo.get_func_details(func_data) if arg_index < func_tinfo.get_nargs() and lvar.name.lstrip('_') != func_data[arg_index].name: return func_tinfo, parent.x.obj_ea, arg_index, lvar.name.lstrip('_')
def init(): global VOID_TINFO, PVOID_TINFO, CONST_PVOID_TINFO, BYTE_TINFO, PBYTE_TINFO, LEGAL_TYPES, X_WORD_TINFO, \ PX_WORD_TINFO, DUMMY_FUNC VOID_TINFO = idaapi.tinfo_t(idaapi.BT_VOID) PVOID_TINFO.create_ptr(VOID_TINFO) CONST_PVOID_TINFO.create_ptr(idaapi.tinfo_t(idaapi.BT_VOID | idaapi.BTM_CONST)) BYTE_TINFO = idaapi.tinfo_t(idaapi.BTF_BYTE) PBYTE_TINFO = idaapi.dummy_ptrtype(1, False) X_WORD_TINFO = idaapi.get_unk_type(EA_SIZE) PX_WORD_TINFO = idaapi.dummy_ptrtype(EA_SIZE, False) func_data = idaapi.func_type_data_t() func_data.rettype = PVOID_TINFO func_data.cc = idaapi.CM_CC_UNKNOWN DUMMY_FUNC = idaapi.tinfo_t() DUMMY_FUNC.create_func(func_data, idaapi.BT_FUNC) LEGAL_TYPES = [PVOID_TINFO, PX_WORD_TINFO, X_WORD_TINFO, PBYTE_TINFO]
def check(cfunc, ctree_item): if ctree_item.citype != idaapi.VDI_EXPR: return False expression = ctree_item.it.to_specific_type if expression.op == idaapi.cot_var: lvar = ctree_item.get_lvar() parent = cfunc.body.find_parent_of(expression).to_specific_type if parent.op == idaapi.cot_call: arg_index, _ = Helper.get_func_argument_info(parent, expression) func_tinfo = parent.x.type.get_pointed_object() if func_tinfo.get_nargs() < arg_index: return func_data = idaapi.func_type_data_t() func_tinfo.get_func_details(func_data) name = func_data[arg_index].name if name and re.search("a\d*$", name) is None and name != 'this' and name != lvar.name: return name, lvar
def __init__(self, ea, iatEA=None, library_name=None): """ Ctor """ self.logger = logging.getLogger(__name__) self.ea = ea # Effective Address of the function self.iatEA = iatEA # If imported function, the address in the IAT try: function = sark.Function(ea) except sark.exceptions.SarkNoFunction: raise DIE.Lib.DIE_Exceptions.DieNoFunction( "No Function at 0x%08X" % (ea, )) self.funcName = get_function_name(function.ea) self.func_start = function.startEA self.func_end = function.endEA self.proto_ea = self.getFuncProtoAdr() # Address of function prototype self.typeInfo = idaapi.tinfo_t() # Function type info self.funcInfo = idaapi.func_type_data_t() # Function info self.argNum = 0 # Number of input arguments self.args = [] # Function argument list self.retArg = None # Return argument self.library_name = library_name # If library function, name of containing library self.isLibFunc = False if self.iatEA: self.isLibFunc = True # Is this a library function elif sark.Function(ea).flags & (idaapi.FUNC_LIB | idaapi.FUNC_THUNK): self.isLibFunc = True try: self.getArguments() except Exception as ex: self.logger.error( "Failed to get function arguments for function %s: %s", self.funcName, ex)
def activate(self, ctx): # ctx - action_activation_ctx_t vu = idaapi.get_tform_vdui(ctx.form) function_tinfo = idaapi.tinfo_t() if not vu.cfunc.get_func_type(function_tinfo): return function_details = idaapi.func_type_data_t() function_tinfo.get_func_details(function_details) convention = idaapi.CM_CC_MASK & function_details.cc if convention == idaapi.CM_CC_CDECL: function_details.cc = idaapi.CM_CC_SPECIAL elif convention in (idaapi.CM_CC_STDCALL, idaapi.CM_CC_FASTCALL, idaapi.CM_CC_PASCAL, idaapi.CM_CC_THISCALL): function_details.cc = idaapi.CM_CC_SPECIALP elif convention == idaapi.CM_CC_ELLIPSIS: function_details.cc = idaapi.CM_CC_SPECIALE else: return function_tinfo.create_func(function_details) idaapi.apply_tinfo2(vu.cfunc.entry_ea, function_tinfo, idaapi.TINFO_DEFINITE) vu.refresh_view(True)
def _rename_function(self, function_ea, class_name, instance_ptr_ea): # type: (int, str, int) -> None i = 0 function_name = "%s::__auto%d" % (class_name, i) while not idc.MakeNameEx(function_ea, function_name, idaapi.SN_NOWARN): i += 1 function_name = "%s::__auto%d" % (class_name, i) func_tinfo = idaapi.tinfo_t() if not idaapi.get_tinfo2(function_ea, func_tinfo): return arg_tinfo = idaapi.tinfo_t() idaapi.get_tinfo2(instance_ptr_ea, arg_tinfo) func_data = idaapi.func_type_data_t() func_tinfo.get_func_details(func_data) func_data[0].type = arg_tinfo new_func_tinfo = idaapi.tinfo_t() new_func_tinfo.create_func(func_data) idaapi.apply_tinfo2(function_ea, new_func_tinfo, idaapi.TINFO_DEFINITE)
def set_first_argument_type(self, name): func_data = idaapi.func_type_data_t() func_tinfo = self.tinfo.get_pointed_object() class_tinfo = idaapi.tinfo_t() if func_tinfo.get_func_details(func_data) and func_tinfo.get_nargs() and \ class_tinfo.get_named_type(idaapi.cvar.idati, name): class_tinfo.create_ptr(class_tinfo) first_arg_tinfo = func_data[0].type if (first_arg_tinfo.is_ptr() and first_arg_tinfo.get_pointed_object().is_udt()) or \ helper.is_legal_type(func_data[0].type): func_data[0].type = class_tinfo func_data[0].name = "this" func_tinfo.create_func(func_data) func_tinfo.create_ptr(func_tinfo) if func_tinfo.dstr() != self.tinfo.dstr(): self.tinfo = func_tinfo self.tinfo_modified = True for parent in self.parents: parent.modified = True else: print("[Warning] function {0} probably have wrong type".format(self.name))
def __init__(self, ea, iatEA=None, library_name=None): """ Ctor """ self.logger = logging.getLogger(__name__) self.ea = ea # Effective Address of the function self.iatEA = iatEA # If imported function, the address in the IAT try: function = sark.Function(ea) except sark.exceptions.SarkNoFunction: raise DIE.Lib.DIE_Exceptions.DieNoFunction("No Function at 0x%08X" % (ea, )) self.funcName = get_function_name(function.ea) self.func_start = function.startEA self.func_end = function.endEA self.proto_ea = self.getFuncProtoAdr() # Address of function prototype self.typeInfo = idaapi.tinfo_t() # Function type info self.funcInfo = idaapi.func_type_data_t() # Function info self.argNum = 0 # Number of input arguments self.args = [] # Function argument list self.retArg = None # Return argument self.library_name = library_name # If library function, name of containing library self.isLibFunc = False if self.iatEA: self.isLibFunc = True # Is this a library function elif sark.Function(ea).flags & (idaapi.FUNC_LIB | idaapi.FUNC_THUNK): self.isLibFunc = True try: self.getArguments() except Exception as ex: self.logger.error("Failed to get function arguments for function %s: %s", self.funcName, ex)
def set_func_argument(func_tinfo, index, arg_tinfo): func_data = idaapi.func_type_data_t() func_tinfo.get_func_details(func_data) func_data[index].type = arg_tinfo func_tinfo.create_func(func_data)
def activate(self, ctx): hx_view = idaapi.get_tform_vdui(ctx.form) result = self.check(hx_view.cfunc, hx_view.item) if result: if result[0] == RECAST_LOCAL_VARIABLE: tinfo, lvar = result[1:] if hx_view.set_lvar_type(lvar, tinfo): hx_view.refresh_view(True) elif result[0] == RECAST_GLOBAL_VARIABLE: tinfo, address = result[1:] if idaapi.apply_tinfo2(address, tinfo, idaapi.TINFO_DEFINITE): hx_view.refresh_view(True) elif result[0] == RECAST_ARGUMENT: arg_index, func_tinfo, arg_tinfo, address = result[1:] func_data = idaapi.func_type_data_t() func_tinfo.get_func_details(func_data) func_data[arg_index].type = arg_tinfo new_func_tinfo = idaapi.tinfo_t() new_func_tinfo.create_func(func_data) if idaapi.apply_tinfo2(address, new_func_tinfo, idaapi.TINFO_DEFINITE): hx_view.refresh_view(True) elif result[0] == RECAST_RETURN: return_type, func_address = result[1:] try: cfunc = idaapi.decompile( func_address) if func_address else hx_view.cfunc except idaapi.DecompilationFailure: print "[ERROR] Ida failed to decompile function" return function_tinfo = idaapi.tinfo_t() cfunc.get_func_type(function_tinfo) func_data = idaapi.func_type_data_t() function_tinfo.get_func_details(func_data) func_data.rettype = return_type function_tinfo.create_func(func_data) if idaapi.apply_tinfo2(cfunc.entry_ea, function_tinfo, idaapi.TINFO_DEFINITE): hx_view.refresh_view(True) elif result[0] == RECAST_STRUCTURE: structure_name, field_offset, new_type = result[1:] tinfo = idaapi.tinfo_t() tinfo.get_named_type(idaapi.cvar.idati, structure_name) ordinal = idaapi.get_type_ordinal(idaapi.cvar.idati, structure_name) if ordinal: udt_member = idaapi.udt_member_t() udt_member.offset = field_offset * 8 idx = tinfo.find_udt_member(idaapi.STRMEM_OFFSET, udt_member) if udt_member.offset != field_offset * 8: print "[Info] Can't handle with arrays yet" elif udt_member.type.get_size() != new_type.get_size(): print "[Info] Can't recast different sizes yet" else: udt_data = idaapi.udt_type_data_t() tinfo.get_udt_details(udt_data) udt_data[idx].type = new_type tinfo.create_udt(udt_data, idaapi.BTF_STRUCT) tinfo.set_numbered_type(idaapi.cvar.idati, ordinal, idaapi.NTF_REPLACE, structure_name) hx_view.refresh_view(True)