def similar_names_list(nm): l = [] if nm: for ea, name in idautils.Names(): dn = idc.Demangle(name, 0) if idc.Demangle(name, 0) else name if re.search(r"\b" + nm + r"\b", dn): l.append((ea, name)) return l
def launch(self, names): texts = [i[1] for i in names] self.jump_list = [i[0] for i in names] for i in range(len(texts)): if idc.Demangle(texts[i], 0): texts[i] = idc.Demangle(texts[i], 0) self.goto_list.insertItems(0, texts) if not texts: self.goto_btn.setEnabled(False) self.d.exec_()
def kernelcache_find_virtual_method_overrides(classname=None, method=None): import idc import idaapi import ida_kernelcache as kc # Define the form to ask for the arguments. class MyForm(idaapi.Form): def __init__(self): swidth = 40 idaapi.Form.__init__( self, r"""STARTITEM 0 Find virtual method overrides <#The class#Class :{classname}> <#The virtual method#Method:{method}>""", { 'classname': idaapi.Form.StringInput(tp=idaapi.Form.FT_IDENT, swidth=swidth), 'method': idaapi.Form.StringInput(tp=idaapi.Form.FT_IDENT, swidth=swidth), }) def OnFormChange(self, fid): return 1 kc.collect_class_info() if any(arg is None for arg in (classname, method)): f = MyForm() f.Compile() f.classname.value = classname or '' f.method.value = method or '' ok = f.Execute() if ok != 1: print 'Cancelled' return False classname = f.classname.value method = f.method.value f.Free() if classname not in kc.class_info: print 'Not a valid class: {}'.format(classname) return False print 'Subclasses of {} that override {}:'.format(classname, method) baseinfo = kc.class_info[classname] found = False for classinfo in baseinfo.descendants(): for _, override, _ in kc.vtable.class_vtable_overrides( classinfo, superinfo=baseinfo, methods=True): name = idc.NameEx(idc.BADADDR, override) demangled = idc.Demangle(name, idc.GetLongPrm(idc.INF_SHORT_DN)) name = demangled if demangled else name if method in name: print '{:#x} {}'.format(override, classinfo.classname) found = True if not found: print 'No subclass of {} overrides {}'.format(classname, method) return found
def get_new_operators(): newoperators = set() for i, func_addr in enumerate(idautils.Functions(plt_start, plt_end)): demangled_name = idc.Demangle(idc.Name(func_addr), 0) if demangled_name is not None and "operator new" in demangled_name: newoperators.add(func_addr) return newoperators
def kernelcache_find_virtual_method_overrides(classname=None, method=None): import idc import ida_kernelcache as kc kc.collect_class_info() if not classname: classname = idc.AskStr('IOUserClient', 'Enter class name') if classname not in kc.class_info: print 'Not a valid class: {}'.format(classname) return False if not method: method = idc.AskStr('externalMethod', 'Enter method name') print 'Subclasses of {} that override {}:'.format(classname, method) baseinfo = kc.class_info[classname] found = False for classinfo in baseinfo.descendants(): for _, override, _ in kc.vtable.class_vtable_overrides( classinfo, superinfo=baseinfo, methods=True): name = idc.NameEx(idc.BADADDR, override) demangled = idc.Demangle(name, idc.GetLongPrm(idc.INF_SHORT_DN)) name = demangled if demangled else name if method in name: print '{:#x} {}'.format(override, classinfo.classname) found = True if not found: print 'No subclass of {} overrides {}'.format(classname, method) return found
def demangle(self, name): mask = idc.GetLongPrm(idc.INF_SHORT_DN) demangled = idc.Demangle(name, mask) if demangled is None: return name else: return demangled
def _split_basic_block(start_ea, end_ea): """ IDA Pro's ``idaapi.Flowchart`` does not consider function calls as basic block boundaries. This function takes an address range and splits the basic blocks found within that range so that function calls are considered basic block boundaries. """ split_bbs = [] func_name = idc.GetFunctionName(start_ea) demangled_name = idc.Demangle(func_name, idc.GetLongPrm(idc.INF_SHORT_DN)) if demangled_name: func_name = demangled_name bb_start_addr = start_ea block = idautils.Heads(start_ea, end_ea) for inst in block: mnem = idc.GetMnem(inst) if mnem == 'call' and inst != end_ea: split_bbs.append( dict(start_addr=bb_start_addr, end_addr=idc.NextHead(inst, end_ea + 1) - 1, function=func_name)) bb_start_addr = idc.NextHead(inst, end_ea + 1) if bb_start_addr < end_ea: split_bbs.append( dict(start_addr=bb_start_addr, end_addr=end_ea - 1, function=func_name)) return split_bbs
def __get_functions(self): functions = list(idautils.Functions()) for start_function in functions: tinfo = idc.GetTinfo(start_function) if tinfo is None: continue mangled_name = idc.GetFunctionName(start_function) demangled = {idc.INF_SHORT_DN: '', idc.INF_LONG_DN: ''} for record in demangled.iteritems(): (type, value) = record demangled[type] = idc.Demangle(mangled_name, idc.GetLongPrm(type)) ida_type, ida_fields = tinfo yield models_ida.IdaRawFunctions( start=start_function, end=idc.GetFunctionAttr(start_function, idc.FUNCATTR_END), ida_type=ida_type, ida_fields=ida_fields, mangled_name=mangled_name, short_name=demangled[idc.INF_SHORT_DN], long_name=demangled[idc.INF_LONG_DN])
def load_crash_report(self, log_file): with open(log_file, 'r') as f: log = f.read() traceback = process_stack_trace(log) self.log_txt.setText(log) self.stack_trace_table.clear() self.stack_trace_table.setHorizontalHeaderLabels( ["Address", "Function"]) self.stack_trace_table.setRowCount(len(traceback)) for i, addr in enumerate(traceback): func_name = idc.GetFunctionName(addr) func_name_demangled = idc.Demangle( func_name, idc.GetLongPrm(idc.INF_SHORT_DN)) if func_name_demangled is not None: func_name = func_name_demangled self.stack_trace_table.setRowHeight(i, 20) self.stack_trace_table.setItem( i, 0, QtWidgets.QTableWidgetItem("0x{:016x}".format(addr))) self.stack_trace_table.setItem( i, 1, QtWidgets.QTableWidgetItem(func_name)) self.log_txt.setEnabled(True) self.stack_trace_table.setEnabled(True)
def getFunctionName(self, ea): """Returns the name of the function to which ea belongs""" demangled_name = idc.Demangle(idc.GetFunctionName(ea), idc.GetLongPrm(idc.INF_SHORT_DN)) if not demangled_name: return idc.GetFunctionName(ea) else: return demangled_name
def GetFuncName(self, ea, demangle=True): name = get_func_name(ea) demangled_name = idc.Demangle(name, idc.GetLongPrm(idc.INF_SHORT_DN)) if demangled_name == None: return name else: return demangled_name
def __init__(self, addr, deepness=0): super(RTTITypeDescriptor, self).__init__(addr, deepness) nameAddr = addr + RTTITypeDescriptor.Offset.mangledName.value + RTTITypeDescriptor.NameOffset.classPrefix.value self.mangledName = idc.GetString(nameAddr) demangledName = idc.Demangle('??_7' + self.mangledName + '6B@', 8) if demangledName != None: demangledName = demangledName[0:len(demangledName) - 11] self.name = demangledName
def demangle(name, strip_arg_types=False): def strip_args(name): if strip_arg_types is True: return name.split("(", 1)[0] else: return name demangled = idc.Demangle(name, idc.GetLongPrm(idc.INF_LONG_DN)) if demangled is not None: return strip_args(demangled) # The names in RTTI are not mangled normally, so try prepending # the '_Z' demangled = idc.Demangle("_Z" + name, idc.GetLongPrm(idc.INF_LONG_DN)) if demangled is not None: return strip_args(demangled) return strip_args(name)
def demangle_name(cls, name): '''Demangle name.''' tmp = idc.Demangle(name, idc.GetLongPrm(idc.INF_SHORT_DN)) if tmp: name = tmp matches = re.match(r'^(.*?)\(.*?\)', name) if matches: name = matches.group(1) return name
def vtable_symbol_get_class(symbol): """Get the class name for a vtable symbol.""" try: demangled = idc.Demangle(symbol, idc.GetLongPrm(idc.INF_SHORT_DN)) pre, post = demangled.split("`vtable for'", 1) assert pre == '' return post except: return None
def _demangle(name, short=True): dtype = idc.INF_LONG_DN if short: dtype = idc.INF_SHORT_DN tmp = idc.Demangle(name, idc.GetLongPrm(dtype)) if tmp: name = tmp name = name.replace('__', '::') return name
def _get_imported_names(self): '''Create and return a list of imported function names.''' tmp = [] for _, imp_entries in self._build_imports().items(): for imp_name in imp_entries: tmp_name = idc.Demangle(imp_name, idc.GetLongPrm(idc.INF_SHORT_DN)) if tmp_name: imp_name = tmp_name tmp.append(imp_name) return tmp
def get_func_name(self, address): name = idc.Demangle(idaapi.get_func_name(address), idc.GetLongPrm(idc.INF_LONG_DN)) if name != None: name = re.sub(r'[A-Za-z0-9_]+::', r'', name) name = re.sub(r'^public: ', r'', name) name = re.sub(r'unsigned short const \*', r'const wchar_t *', name) name = re.sub(r'unsigned short \*', r'wchar_t *', name) return name else: return idaapi.get_func_name(address)
def similar_func_list(nm): l = [] if nm: def eee(x): return '\\%s' % x if re.match('\W', x) else x nm = "".join([eee(s) for s in nm]) print nm m = {} for ea, name in idautils.Names(): m[ea] = name for ea in idautils.Functions(): fn = m.get(ea, "sub_" + hex(ea)[2:].replace("L", "")) fn = idc.Demangle(fn, 0) if idc.Demangle(fn, 0) else fn if re.search(r"\W" + nm + r"\W", fn): l.append((ea, fn)) return l
def _init_demangled_names(): """ Creates dictionary of demangled names => set of address, that will be used further when user makes double click on methods in Decompiler output. """ demangled_names.clear() for address, name in idautils.Names(): short_name = idc.Demangle(name, idc.INF_SHORT_DN) if short_name: short_name = common.demangled_name_to_c_str(short_name) demangled_names[short_name].add(address - idaapi.get_imagebase()) print("[DEBUG] Demangled names have been initialized")
def block_split(output_file, startEA, endEA): curName = GetFunctionName(startEA); dem = idc.Demangle(curName, idc.GetLongPrm(INF_SHORT_DN)); if dem != None: curName = dem; first=startEA h = idautils.Heads(startEA, endEA) for i in h: mnem = idc.GetMnem(i) if mnem == "call" and i != endEA: first=idc.NextHead(i, endEA+1)
def method_name(symbol): """Get the name of the C++ method from its symbol. If the symbol demangles to 'Class::method(args)', this function returns 'method'. """ try: demangled = idc.Demangle(symbol, idc.GetLongPrm(idc.INF_SHORT_DN)) func = demangled.split('::', 1)[1] base = func.split('(', 1)[0] return base or None except: return None
def class_from_vtable_method_symbol(method_symbol): """Get the base class in a vtable method symbol. Extract the name of the base class from a canonical method symbol. """ demangled = idc.Demangle(method_symbol, idc.GetLongPrm(idc.INF_SHORT_DN)) if not demangled: return None classname = demangled.split('::', 1)[0] if classname == demangled: return None return classname
def init_demangled_names(*args): """ Creates dictionary of demangled names => address, that will be used further at double click on methods got from symbols. """ demangled_names.clear() for address, name in idautils.Names(): short_name = idc.Demangle(name, idc.INF_SHORT_DN) if short_name: short_name = common.demangled_name_to_c_str(short_name) demangled_names[short_name].add(address - idaapi.get_imagebase()) print "[DEBUG] Demangled names have been initialized"
def init_demangled_names(*args): """ Creates dictionary of demangled names => address, that will be used further at double click on methods got from symbols. """ demangled_names.clear() for address, name in idautils.Names(): short_name = idc.Demangle(name, idc.GetLongPrm(idc.INF_SHORT_DN)) if short_name: demangled_names[short_name.split('(') [0]] = address - idaapi.get_imagebase() print "[DEBUG] Demangled names have been initialized"
def imp_cb(self, ea, name, ord1): """Callback passed to idaapi.enum_import_name in buildImportDictionary(). Sets the name of the PE segment in which the import table resides, and inserts current import in dictionary of imported APIS""" if self.firstImport: self.imports_segment_name = idaapi.get_segm_name(ea) self.firstImport = False demangled_name = idc.Demangle(name, idc.GetLongPrm(idc.INF_SHORT_DN)) if not demangled_name: self.import_dict[ea] = (name, self.curr_mod_name) else: self.import_dict[ea] = (demangled_name, self.curr_mod_name) return True
def method_arguments_string(symbol): """Get the arguments string of the C++ method from its symbol. If the symbol demangles to 'Class::method(arg1, arg2)', this function returns 'arg1, arg2'. """ try: demangled = idc.Demangle(symbol, idc.GetLongPrm(idc.INF_LONG_DN)) func = demangled.split('::', 1)[1] args = func.split('(', 1)[1] args = args.rsplit(')', 1)[0].strip() return args except: return None
def launch(self): global last_typed_text global last_selected_row self.func_names = [] self.jump_list = {} self.filter_edit.setText(last_typed_text) self.filter_edit.selectAll() self.goto_list.setCurrentRow(last_selected_row) m = {} for ea, name in idautils.Names(): m[ea] = name for ea in idautils.Functions(): n = m.get(ea, "sub_" + hex(ea)[2:].replace("L", "")) n = idc.Demangle(n, 0) if idc.Demangle(n, 0) else n self.func_names.append(n) self.jump_list[n] = ea self.filter_edit_changed() self.filter_edit.setFocus() self.d.exec_()
def replace_func_names(from_str, to_str, mangled, unmangled): for ea in idautils.Functions(): name = idc.GetFunctionName(ea) if not name: continue dnm = idc.Demangle(name, 0) proceed = mangled if dnm else unmangled if proceed and from_str in name: new_name = name.replace(from_str, to_str) idc.MakeNameEx(ea, new_name, 0) print "FunctionName %s is replaced to %s" % (name, new_name)
def choose_virtual_func_address(name, tinfo=None, offset=None): addresses = get_virtual_func_addresses(name, tinfo, offset) if not addresses: return if len(addresses) == 1: return addresses[0] chooser = forms.MyChoose( [[to_hex(ea), idc.Demangle(idc.get_name(ea), idc.INF_LONG_DN)] for ea in addresses], "Select Function", [["Address", 10], ["Full name", 50]]) idx = chooser.Show(modal=True) if idx != -1: return addresses[idx]