def activate(self, ctx): hx_view = idaapi.get_widget_vdui(ctx.widget) if not self.check(hx_view): return data = [] offset = hx_view.item.e.m struct_type = idaapi.remove_pointer(hx_view.item.e.x.type) ordinal = helper.get_ordinal(struct_type) result = struct_xrefs.XrefStorage().get_structure_info(ordinal, offset) for xref_info in result: data.append([ idaapi.get_short_name(xref_info.func_ea) + "+" + hex(int(xref_info.offset)), xref_info.type, xref_info.line ]) field_name = helper.get_member_name(struct_type, offset) chooser = forms.MyChoose( data, "Cross-references to {0}::{1}".format(struct_type.dstr(), field_name), [["Function", 20 | idaapi.CHCOL_PLAIN], ["Type", 2 | idaapi.CHCOL_PLAIN], ["Line", 40 | idaapi.CHCOL_PLAIN]] ) idx = chooser.Show(True) if idx == -1: return xref = result[idx] idaapi.open_pseudocode(xref.func_ea + xref.offset, False)
def create(cfunc, arg): # Creates object suitable for scaning either from cexpr_t or ctree_item_t if isinstance(arg, idaapi.ctree_item_t): lvar = arg.get_lvar() if lvar: index = list(cfunc.get_lvars()).index(lvar) result = VariableObject(lvar, index) if arg.e: result.ea = ScanObject.get_expression_address(cfunc, arg.e) return result cexpr = arg.e else: cexpr = arg if cexpr.op == idaapi.cot_var: lvar = cfunc.get_lvars()[cexpr.v.idx] result = VariableObject(lvar, cexpr.v.idx) result.ea = ScanObject.get_expression_address(cfunc, cexpr) return result elif cexpr.op == idaapi.cot_memptr: t = cexpr.x.type.get_pointed_object() result = StructPtrObject(t.dstr(), cexpr.m) result.name = get_member_name(t, cexpr.m) elif cexpr.op == idaapi.cot_memref: t = cexpr.x.type result = StructRefObject(t.dstr(), cexpr.m) result.name = get_member_name(t, cexpr.m) elif cexpr.op == idaapi.cot_obj: result = GlobalVariableObject(cexpr.obj_ea) result.name = idaapi.get_short_name(cexpr.obj_ea) else: return result.tinfo = cexpr.type result.ea = ScanObject.get_expression_address(cfunc, cexpr) return result
def _name_changed(self, address, new_name, local_name): """ Handler for rename event in IDA. """ # we should never care about local renames (eg, loc_40804b), ignore if local_name or new_name.startswith("loc_"): return 0 # get the function that this address falls within function = self.get_function(address) # if the address does not fall within a function (might happen?), ignore if not function: return 0 # # ensure the renamed address matches the function start before # renaming the function in our metadata cache. # # I am not sure when this would not be the case (globals? maybe) # but I'd rather not find out. # if address == function.address: logger.debug("Name changing @ 0x%X" % address) logger.debug(" Old name: %s" % function.name) function.name = idaapi.get_short_name(address) logger.debug(" New name: %s" % function.name) # notify any listeners that a function rename occurred self._notify_function_renamed() # necessary for IDP/IDB_Hooks return 0
def parse_vtable_name(address): name = idaapi.get_short_name(address) if idaapi.is_valid_typename(name): if name[0:3] == 'off': # off_XXXXXXXX case return "Vtable" + name[3:], False else: # Attempt to make nice and valid name from demangled RTTI name try: name = re.sub("^const ", "", name) sliced_names = name.split("::") name, for_part = "_for_".join(sliced_names[:-1]), sliced_names[-1] print name, for_part templates = re.search("<(.*)>", name) if templates: templates = templates.group(1) name = re.sub("<.*>", "", name) templates = re.sub("[^a-zA-Z0-9_*]", "_", templates) templates = re.sub("\*", "PTR", templates) name += '_' + templates for_part = re.search("\{for `(.*)'\}", for_part) if for_part: for_part = for_part.group(1) name += '_' + for_part return 'Vtable_' + name, True except (AttributeError, IndexError): print "[Warning] Unable to parse virtual table name - " return "Vtable_{0:X}".format(address), False
def add_item(self, function_match): imagebase = idaapi.get_imagebase() self_address = imagebase + function_match[self.self_name] counts = self.count_blocks(function_match) root = self.model.invisibleRootItem() columns = [ QtGui.QStandardItem(idaapi.get_short_name(self_address)), QtGui.QStandardItem('%.8x' % self_address), QtGui.QStandardItem(function_match[self.peer_name + '_name']), QtGui.QStandardItem('%.8x' % function_match[self.peer_name]), QtGui.QStandardItem('%d' % counts['matched_block_counts']), QtGui.QStandardItem('%d' % counts['self_unidentified_block_counts']), QtGui.QStandardItem('%d' % counts['peer_unidentified_block_counts']) ] root.appendRow(columns) class Item: def __init__(self, **kwargs): self.__dict__.update(kwargs) item_data = Item(function_match=function_match, self_name=self.self_name, peer_name=self.peer_name, peer_md5=self.peer_md5, queue=self.queue) for column_item in columns: column_item.setData(item_data, QtCore.Qt.UserRole)
def __init__(self, offset, address, scanned_variable=None, origin=0): AbstractMember.__init__(self, offset + origin, scanned_variable, origin) self.address = address self.virtual_functions = [] self.name = "vtable" + ("_{0:X}".format(self.offset) if self.offset else '') self.vtable_name, self.have_nice_name = parse_vtable_name( idaapi.get_short_name(address)) self.populate()
def name(self): name = idaapi.get_short_name(self.address) name = name.split('(')[0] result = re.search(r"(\[thunk\]:)?([^`]*)(.*\{(\d+)}.*)?", name) name, adjuster = result.group(2), result.group(4) if adjuster: name += "_adj_" + adjuster name = name.translate(None, "`'").replace(' ', '_') name = re.sub(r'[<>]', '_t_', name) return name
def renamed(self, address, new_name, local_name): """ Capture all IDA rename events. """ # we should never care about local renames (eg, loc_40804b), ignore if local_name or new_name.startswith("loc_"): return 0 rendered_name = idaapi.get_short_name(address) # call the 'renamed' callback, that will get hooked by a listener self.name_changed(address, rendered_name) # must return 0 to keep IDA happy... return 0
def apply_type(self, tinfo): """ Finally apply Class'es tinfo to this variable """ if self.applicable: hx_view = idaapi.open_pseudocode(self.function.entry_ea, -1) if hx_view: print "[Info] Applying tinfo to variable {0} in function {1}".format( self.lvar.name, idaapi.get_short_name(self.function.entry_ea)) # Finding lvar of new window that have the same name that saved one and applying tinfo_t lvar = filter(lambda x: x == self.lvar, hx_view.cfunc.get_lvars()) if lvar: print "+++++++++++" hx_view.set_lvar_type(lvar[0], tinfo) else: print "-----------"
def scan_function(self, ea, offset, arg_index): # Function for recursive search structure's members if (ea, arg_index, self.origin + offset) in scanned_functions: return try: scanned_functions.add((ea, arg_index, self.origin + offset)) new_function = idaapi.decompile(ea) if new_function: print "[Info] Scanning function {name} at 0x{ea:08X}, origin: 0x{origin:04X}".format( name=idaapi.get_short_name(ea), ea=ea, origin=self.origin + offset ) scanner = DeepSearchVisitor(new_function, self.origin + offset, arg_index) scanner.apply_to(new_function.body, None) self.candidates.extend(scanner.candidates) except idaapi.DecompilationFailure: print "[ERROR] Ida failed to decompile function"
def create(cfunc, cexpr): if cexpr.op == idaapi.cot_call: e = cexpr elif cexpr.op == idaapi.cot_cast and cexpr.x.op == idaapi.cot_call: e = cexpr.x else: return func_name = idaapi.get_short_name(e.x.obj_ea) if "malloc" in func_name or "operator new" in func_name: carg = e.a[0] if carg.op == idaapi.cot_num: size = carg.numval() else: size = 0 result = MemoryAllocationObject(func_name, size) result.ea = ScanObject.get_expression_address(cfunc, e) return result
def _manipulate(self, cexpr, obj): if self.crippled: logger.debug("Skipping crippled function at {}".format( helper.to_hex(self._cfunc.entry_ea))) return if obj.id == api.SO_GLOBAL_OBJECT: old_name = idaapi.get_short_name(cexpr.obj_ea) if settings.PROPAGATE_THROUGH_ALL_NAMES or _is_default_name( old_name): new_name = self.__rename_with_prefix( lambda x: idaapi.set_name(cexpr.obj_ea, x), self.__propagated_name) logger.debug("Renamed global variable from {} to {}".format( old_name, new_name)) elif obj.id == api.SO_LOCAL_VARIABLE: lvar = self._cfunc.get_lvars()[cexpr.v.idx] old_name = lvar.name if settings.PROPAGATE_THROUGH_ALL_NAMES or _is_default_name( old_name): new_name = self.__rename_with_prefix( lambda x: self.__hx_view.rename_lvar(lvar, x, True), self.__propagated_name) logger.debug("Renamed local variable from {} to {}".format( old_name, new_name)) elif obj.id in (api.SO_STRUCT_POINTER, api.SO_STRUCT_REFERENCE): struct_tinfo = cexpr.x.type offset = cexpr.m struct_tinfo.remove_ptr_or_array() old_name = helper.get_member_name(struct_tinfo, offset) if settings.PROPAGATE_THROUGH_ALL_NAMES or _is_default_name( old_name): new_name = self.__rename_with_prefix( lambda x: helper.change_member_name( struct_tinfo.dstr(), offset, x), self.__propagated_name) logger.debug("Renamed struct member from {} to {}".format( old_name, new_name))
def function_name(self): return idaapi.get_short_name(self.func_ea)
def name(self): name = idaapi.get_short_name(self.address) name = name.split('(')[0] name = name.replace("`", '').replace(" ", '_').replace("'", '') return name
def get_function_name_at(self, address): return idaapi.get_short_name(address)
def _refresh_name(self): """ Refresh the function name against the open database. """ self.name = idaapi.get_short_name(self.address)