def current_addr(): """ Return current screen address. :return: The current address selected. """ return ida_kernwin.get_screen_ea()
def from_addr(cls, ea=None): """ Class method which return a :class:`HxCFunc` object corresponding to the function at a particular address. This may raise a :class:`~bip.base.BipDecompileError` if the decompilation failed or if the address provided is not in a function. :param int ea: An address inside the function for which we want an :class:`HxCFunc`. If ``None`` the screen address will be used. :return: A :class:`HxCFunc` object. """ if ea is None: ea = ida_kernwin.get_screen_ea() try: idaobj = ida_hexrays.decompile(ea) except ida_hexrays.DecompilationFailure: # IDA could not decompile the function raise bbase.BipDecompileError( "Hexrays failed to decompile function at 0x{:X}".format(ea)) if idaobj is None: raise bbase.BipDecompileError( "Decompilation failed for {}: address was probably not in a function ?" .format(ea)) return cls(idaobj)
def copy_ea_to_clipboard(): """copy current effective address to clipboard""" fmt = "%x" % ida_kernwin.get_screen_ea() QApplication.clipboard().setText(fmt) print("[%s]: copied ea to clipboard: '%s'" % (SCRIPT_NAME, fmt)) return
def activate(self, ctx): """ :param ctx: idaapi.action_activation_ctx_t :return: None """ ea = get_screen_ea() if get_func(ea) is None: print("address = " + hex(ea)) data = get_bytes(ea, 16) guid = str(UUID(bytes_le=data)) else: name, data = extract_guid(ea) guid = str(UUID(bytes_le=data)) print("Local variable EFI_GUID extraction for " + name) print("data = " + " ".join("%02x" % x for x in bytes(data))) print("guid = " + guid) try: import clipboard clipboard.copy(guid) except ImportError: print("clipboard module is not available.")
def _hxe_callback(self, event, *_): if not self._installed: return 0 if event == ida_hexrays.hxe_func_printed: ea = ida_kernwin.get_screen_ea() func = ida_funcs.get_func(ea) if func is None: return if self._func_ea != func.start_ea: self._func_ea = func.start_ea self._labels = HexRaysHooks._get_user_labels(self._func_ea) self._cmts = HexRaysHooks._get_user_cmts(self._func_ea) self._iflags = HexRaysHooks._get_user_iflags(self._func_ea) self._lvar_settings = HexRaysHooks._get_user_lvar_settings( self._func_ea ) self._numforms = HexRaysHooks._get_user_numforms(self._func_ea) self._send_user_labels(func.start_ea) self._send_user_cmts(func.start_ea) self._send_user_iflags(func.start_ea) self._send_user_lvar_settings(func.start_ea) self._send_user_numforms(func.start_ea) return 0
def __init__(self, q, ea_list=None, no_cit=False, flags=ida_kernwin.CH_RESTORE | ida_kernwin.CH_QFLT, width=None, height=None, embedded=False, modal=False): ida_kernwin.Choose.__init__(self, "Hexrays Toolbox", [["Address", 10 | ida_kernwin.CHCOL_EA], ["Output", 80 | ida_kernwin.CHCOL_PLAIN]], flags=flags, width=width, height=height, embedded=embedded) if ea_list is None: ea_list = [ida_kernwin.get_screen_ea()] if callable(q): self.items = exec_query(q, ea_list, no_cit) elif isinstance(q, list): self.items = q else: self.items = list() self.Show()
def activate(self, ctx): f = search_strlit_form_t() f, args = f.Compile() ok = f.Execute() if ok: current_ea = ida_kernwin.get_screen_ea() patterns = ida_bytes.compiled_binpat_vec_t() encoding = ida_nalt.get_default_encoding_idx( ida_nalt.BPU_2B if f.Encoding.value else ida_nalt.BPU_1B) # string literals must be quoted. That's how parse_binpat_str # recognizes them (we want to be careful though: the user # might type in something like 'L"hello"', which should # decode to the IDB-specific wide-char set of bytes) text = f.Text.value if text.find('"') < 0: text = '"%s"' % text err = ida_bytes.parse_binpat_str( patterns, current_ea, text, 10, # radix (not that it matters though, since we're all about string literals) encoding) if not err: ea = ida_bytes.bin_search( current_ea, ida_ida.inf_get_max_ea(), patterns, ida_bytes.BIN_SEARCH_FORWARD | ida_bytes.BIN_SEARCH_NOBREAK | ida_bytes.BIN_SEARCH_NOSHOW) ok = ea != ida_idaapi.BADADDR if ok: ida_kernwin.jumpto(ea) else: print("Failed parsing binary pattern: \"%s\"" % err) return ok
def main(): # Get current ea ea = ida_kernwin.get_screen_ea() # Get segment class seg = ida_segment.getseg(ea) # Loop from segment start to end func_ea = seg.start_ea # Get a function at the start of the segment (if any) func = ida_funcs.get_func(func_ea) if func is None: # No function there, try to get the next one func = ida_funcs.get_next_func(func_ea) seg_end = seg.end_ea while func is not None and func.start_ea < seg_end: funcea = func.start_ea print("Function %s at 0x%x" % (ida_funcs.get_func_name(funcea), funcea)) ref = ida_xref.get_first_cref_to(funcea) while ref != ida_idaapi.BADADDR: print(" called from %s(0x%x)" % (ida_funcs.get_func_name(ref), ref)) ref = ida_xref.get_next_cref_to(funcea, ref) func = ida_funcs.get_next_func(funcea)
def activate(self, ctx): cur_ea = ida_kernwin.get_screen_ea() pfn = ida_funcs.get_func(cur_ea) if pfn: v = ida_kernwin.get_current_viewer() result = ida_kernwin.get_highlight(v) if result: stkvar_name, _ = result frame = ida_frame.get_frame(cur_ea) sptr = ida_struct.get_struc(frame.id) mptr = ida_struct.get_member_by_name(sptr, stkvar_name) if mptr: fii = ida_funcs.func_item_iterator_t() ok = fii.set(pfn) while ok: ea = fii.current() F = ida_bytes.get_flags(ea) for n in range(ida_ida.UA_MAXOP): if not ida_bytes.is_stkvar(F, n): continue insn = ida_ua.insn_t() if not ida_ua.decode_insn(insn, ea): continue v = ida_frame.calc_stkvar_struc_offset( pfn, insn, n) if v >= mptr.soff and v < mptr.eoff: print("Found xref at 0x%08x, operand #%d" % (ea, n)) ok = fii.next_code() else: print("No stack variable named \"%s\"" % stkvar_name) else: print("Please position the cursor within a function")
def query(q, ea_list=None, full=False, fmt=lambda x: "%x: %s" % (x.ea, ida_lines.tag_remove(x.print1(None)))): """run query on list of addresses, print results arguments: q: lambda/function: f(cfunc_t, citem_t) returning a bool ea_list: iterable of addresses/functions to process full: False -> find cexpr_t only (faster but doesn't find cinsn_t items) True -> find citem_t elements, which includes cexpr_t and cinsn_t fmt: lambda/callback-function to be called for formatting output """ if not ea_list: ea_list = [ida_kernwin.get_screen_ea()] r = exec_query(q, ea_list=ea_list, full=full) print("<query> done! %d unique hits." % len(r)) try: for e in r: print(fmt(e)) except: print("<query> error!") return
def __init__(self, val=None): """ Constructor for an :class:`BipBlock` object. This function may raise a ``TypeError`` if the argument is not of a type supported or a ``ValueError`` if the address pass in parameter is not inside a function. :param val: A value used for creating a basic block. This can be an address (int or long) or a ``ida_gdl.BasicBlock`` object. If ``None`` the screen address is used. """ if val is None: val = ida_kernwin.get_screen_ea() #: Internal ida_gdl.BasicBlock object representing this block in IDA self._bb = None if isinstance(val, ida_gdl.BasicBlock): # in this case no problem just put it in the internal value self._bb = val elif isinstance(val, (int, long)): # if val is an int we consider it to be an address # for getting the basic block we need to get the flowchart for the # function # this may raise a ValueError if val is not a function fc = bip.base.func.BipFunction(val)._flowchart for i in range(fc.size): if val >= fc[i].start_ea and val < fc[i].end_ea: # we found it self._bb = fc[i] break if self._bb is None: raise TypeError( "BipBlock expect a ida_gdl.BasicBlock or the address of an instruction inside a function in input." )
def GetElt(ea=None): """ Return an object inherithed from :class:`BipBaseElt` which correspond to the element at an id. Internally this function parcours subclasses of :class:`BipBaseElt` and call the :meth:`~BipBaseElt._is_this_elt` and return the one which match. .. warning:: There is a problem if two functions of a sublcass level can return True on the same element. :param int ea: An address at which to get an element. If ``None`` the screen address is used. :raise RuntimeError: If the address correspond to the error value. :return: An object (subclass of :class:`BipBaseElt`) representing the element. If the address is not mapped a :class:`BipElt` will be returned. """ if ea is None: ea = ida_kernwin.get_screen_ea() if ea == idc.BADADDR: raise RuntimeError("Trying to get element for error address") cls = BipBaseElt sbcls = cls.__subclasses__() while len(sbcls) != 0: cl = sbcls.pop() if cl._is_this_elt(ea): cls = cl sbcls = cl.__subclasses__() return cls(ea)
def _update(self, vu): if vu: focus = None if vu.get_current_item(ida_hexrays.USE_MOUSE): focus = vu.item.e if vu.item.is_citem() else None _ea = _exp = _type = _objid = "???" if vu.get_current_item(ida_hexrays.USE_MOUSE): item = vu.item.it isexpr = item.is_expr() item_type = ida_hexrays.get_ctype_name(item.op) if isexpr: _exp = item.cexpr.print1(None) _exp = ida_lines.tag_remove(_exp) _ea = "%x" % item.ea _type = "c%ct_%s" % ("o" if isexpr else "i", item_type) _objid = "%x" % item.obj_id self.SetControlValue(self.lbl_ea, _ea) self.SetControlValue(self.lbl_exp, _exp) self.SetControlValue(self.lbl_op, _type) self.SetControlValue(self.lbl_objid, _objid) gd = graph_dumper_t() gd.apply_to(vu.cfunc.body if not focus else focus, vu.cfunc.body) expr = "(%s)" % " and\n".join(gd.lines) tc = self.GetControlValue(self.mstr_pexp) tc.text = expr self.SetControlValue(self.mstr_pexp, tc) self.SetControlValue(self.lbl_sea, "%x" % ida_kernwin.get_screen_ea()) return
def invite_to(name): """ Send an invitation to the current location within the disassembler view to the specified user. """ loc = ida_kernwin.get_screen_ea() packet = InviteTo(name, loc) self._plugin.network.send_packet(packet)
def show(self, address=None): """ Show the microcode explorer. """ if address is None: address = ida_kernwin.get_screen_ea() self.select_function(address) self.view.show()
def OnCreate(self, form): self.form = form self.parent = self.FormToPyQtWidget(form) vl = QVBoxLayout() hl = QHBoxLayout() hl2 = QHBoxLayout() hl3 = QHBoxLayout() hl4 = QHBoxLayout() flt = QLabel() flt.setText('Filter:') hl.addWidget(flt) self.cb = QCheckBox('Sync') self.cb.setChecked(True) self.cb.stateChanged.connect(self._toggle_sync) hl2.addWidget(self.cb) self.status = QLabel() self.status.setText('Cyber, cyber!') hl4.addWidget(self.status) self.pw = PixelWidget(self.parent, IDACyberForm.idbh) self.pw.setFocusPolicy(Qt.StrongFocus | Qt.WheelFocus) self.pw.statechanged.connect(self._update_widget) self.pw.next_filter.connect(self._select_next_filter) self.pw.prev_filter.connect(self._select_prev_filter) self.filterlist = self._load_filters(self.pw) if not len(self.filterlist): ida_kernwin.warning( "IDACyber: no filters found within /plugins/cyber/") return self.pw.set_filter(self.filterlist[0][1], 0) self.pw.set_addr(ida_kernwin.get_screen_ea()) self.filterChoser = QComboBox() self.filterChoser.addItems( [obj.name for filter, obj in self.filterlist]) self.filterChoser.currentIndexChanged.connect(self._select_filter) hl.addWidget(self.filterChoser) hl.addStretch(1) vl.addWidget(self.pw) vl.addLayout(hl) vl.addLayout(hl2) vl.addLayout(hl3) vl.addLayout(hl4) self.parent.setLayout(vl) if IDACyberForm.hook is not None: IDACyberForm.hook.new_ea.connect(self._change_screen_ea) self.clean_init = True return
def activate(self, ctx): ea = ida_kernwin.get_screen_ea() index = self.anchor while True: cmt = ida_lines.get_extra_cmt(ea, index) if cmt is None: break print("Got: '%s'" % cmt) index += 1
def preprocess_action(self, name): ea = ida_kernwin.get_screen_ea() self._plugin.logger.debug("preprocess_action(name = %s). ea = 0x%X." % (name, ea)) if name == "MakeUnknown": self.actions.append((name, ea)) elif name == "MakeCode": self.actions.append((name, ea)) return 0
def restore_x(unique_name=None, start=None): ea = ida_kernwin.get_screen_ea() # signature if not unique_name: if not start: seg = ida_segment.getseg(ea) start = seg.start_ea sig_bytes = ida_bytes.get_bytes(start, SIGNATURE_SIZE) sig_hash = hashlib.md5(sig_bytes).hexdigest() unique_name = sig_hash if not start: seg = ida_segment.getseg(ea) start = seg.start_ea if MD5_hash_data_file and os.path.isfile(MD5_hash_data_file): with open(MD5_hash_data_file, "rb") as ifile: received_data = pickle.loads(ifile.read()) saved_data = received_data print("dumpDyn::restore\n\ Name: {}\n\ Restore address: {}\n".format(unique_name, hex(start))) # (start_addr, end_addr, names, comms, bpts, funcs) if unique_name in saved_data: current_data = saved_data[unique_name] # restore names names = current_data[2] for name in names: # names: (rel_addr, name, is_code) ida_name.set_name(start + name[0], name[1]) flags = ida_bytes.get_flags(start + name[0]) if name[2] and not ida_bytes.is_code(flags): ida_auto.auto_make_code(start + name[0]) # restore comments # comms: (rel_addr, TYPE, comment) comms = current_data[3] for comm in comms: # 0:MakeComm and 1:MakeRptCmt ida_bytes.set_cmt(start + comm[0], comm[2], comm[1]) # restore breakpoints # bpts: (rel_addr, size, type) bpts = current_data[4] for bpt in bpts: ida_dbg.add_bpt(start + bpt[0], bpt[1], bpt[2]) # restore functions funcs_addr = current_data[5] for addr in funcs_addr: ida_auto.auto_make_proc(start + addr) # make code & func
def del_at(ea): """ Function which delete the type set at a particular address. :param ea: The address at which to delete the type. If ``None`` the screen address will be used. """ if ea is None: ea = ida_kernwin.get_screen_ea() ida_nalt.del_tinfo(ea)
def main(): va = ida_kernwin.get_screen_ea() f = ida_funcs.get_func(va) if not f: logger.error("function not found: 0x%x", va) return path = find_function_dirtree_path(f.start_ea) if not path: logger.error("function directory entry not found: 0x%x", f.start_ea) return func_dir: dirtree_t = ida_dirtree.get_std_dirtree( ida_dirtree.DIRTREE_FUNCS) dirent = func_dir.resolve_path(path) name = func_dir.get_entry_name(dirent) existing_tag = path[:-(len("/") + len(name))].lstrip("/") # ask_str(defval, hist, prompt) -> PyObject * # I'm not sure what "history id" does. tag = ida_kernwin.ask_str(existing_tag, 69, "tag:") if not tag: return tag_path = f"/{tag}" if not func_dir.isdir(tag_path): logger.info("creating tag: %s", tag) e = dirtree_mkdirs(func_dir, tag_path) if e != ida_dirtree.DTE_OK: logger.error("error: failed to create tag: %s", tag) return else: logger.debug("tag exists: %s", tag) src_path = path src_dirent = func_dir.resolve_path(src_path) src_name = func_dir.get_entry_name(src_dirent) dst_name = src_name dst_path = f"{tag_path}/{dst_name}" if src_path == dst_path: logger.info("skipping move to itself") return logger.info("moving %s from %s to %s", src_name, src_path, dst_path) e = func_dir.rename(src_path, dst_path) if e != ida_dirtree.DTE_OK: logger.error("error: %s", ida_dirtree.dirtree_t_errstr(e)) return set_func_folder_cmt(f.start_ea, tag)
def is_mapped(ea=None): """ Static method which allow to know if an address is mapped or not. :param ea: The address to test for being mapped or not. If ``None`` the screen address will be used. :return: True if the address is mapped, False otherwise. """ if ea is None: ea = ida_kernwin.get_screen_ea() return ida_bytes.is_mapped(ea)
def join_session(self): """Join the collaborative session.""" self._plugin.logger.debug("Joining session") if self._project and self._database: name = self._plugin.config["user"]["name"] color = self._plugin.config["user"]["color"] ea = ida_kernwin.get_screen_ea() self._plugin.network.send_packet( JoinSession(self._project, self._database, self._tick, name, color, ea)) self.hook_all()
def activate(self, ctx): screen_ea = ida_kernwin.get_screen_ea() finder = SignatureFinder() sig = finder.get_signature(screen_ea) print('FakePDB/signatures_find:') print(' * address : %s' % hex(screen_ea)) print(' * name : %s' % ida_name.get_name(screen_ea)) print(' * signature: %s' % sig) print('') return 0
def get_cstring(ea=None, size=-1): """ Static method for getting a C string from an address. :param ea: The address of the string. If ``None`` the screen address is used. :param size: The size of the string. If ``-1`` (default), until a ``\0`` is found. :return: Bytes representing the string """ if ea is None: ea = ida_kernwin.get_screen_ea() return idc.get_strlit_contents(ea, length=size)
def __init__(self, version=f"{__ver_major__}{__ver_minor__}"): kw.Form.__init__( self, f"""Miasm CFG deobfuscator for IDA. v{version} {{FormChangeCb}} <#Entry : {{iAddr}}> <#(E/R)AX:{{iAX}}> <#(E/R)DX:{{iDX}}> <#(E/R)CX:{{iCX}}> <#(E/R)BX:{{iBX}}> <#(E/R)SI:{{iSI}}> <#(E/R)DI:{{iDI}}> <#(E/R)SP:{{iSP}}> <#(E/R)BP:{{iBP}}> <#Disable patch:{{rMode}}> <#Verbose logging:{{rModeLogging}}>{{cModeGroup1}}> """, { 'iAddr': kw.Form.NumericInput(tp=idaapi.Form.FT_ADDR, value=kw.get_screen_ea()), 'cModeGroup1': idaapi.Form.ChkGroupControl(( "rMode", "rModeLogging", )), 'FormChangeCb': idaapi.Form.FormChangeCb(self.OnFormChange), 'iAX': kw.Form.NumericInput(tp=idaapi.Form.FT_ADDR, value=REGISTER_DEFAULT_VALUE), 'iDX': kw.Form.NumericInput(tp=idaapi.Form.FT_ADDR, value=REGISTER_DEFAULT_VALUE), 'iCX': kw.Form.NumericInput(tp=idaapi.Form.FT_ADDR, value=REGISTER_DEFAULT_VALUE), 'iBX': kw.Form.NumericInput(tp=idaapi.Form.FT_ADDR, value=REGISTER_DEFAULT_VALUE), 'iSI': kw.Form.NumericInput(tp=idaapi.Form.FT_ADDR, value=REGISTER_DEFAULT_VALUE), 'iDI': kw.Form.NumericInput(tp=idaapi.Form.FT_ADDR, value=REGISTER_DEFAULT_VALUE), 'iSP': kw.Form.NumericInput(tp=idaapi.Form.FT_ADDR, value=REGISTER_DEFAULT_VALUE), 'iBP': kw.Form.NumericInput(tp=idaapi.Form.FT_ADDR, value=REGISTER_DEFAULT_VALUE), })
def activate(self, ctx): user_input = ida_kernwin.ask_yn( ida_kernwin.ASKBTN_YES, "Would you like to export all functions?") if user_input == ida_kernwin.ASKBTN_CANCEL: return 1 output_file_name_hint = "" p = anvill.get_program() if user_input == ida_kernwin.ASKBTN_NO: screen_cursor = ida_kernwin.get_screen_ea() function_name = ida_funcs.get_func_name(screen_cursor) if function_name is None: print("anvill: The cursor is not located inside a function") return 1 output_file_name_hint = function_name + ".json" try: p.add_function_definition(screen_cursor) except: print( "anvill: Failed to process the function at address {0:x}". format(screen_cursor)) return 1 else: function_address_list = idautils.Functions() for function_address in function_address_list: try: p.add_function_definition(function_address) except: print( "anvill: Failed to process the function at address {0:x}" .format(function_address)) output_file_name_hint = "program.json" output_path = ida_kernwin.ask_file( True, output_file_name_hint, "Select where to save the spec file") if not output_path: return 1 output = json.dumps(p.proto(), sort_keys=False, indent=2) print("anvill: Saving the spec file to {}".format(output_path)) with open(output_path, "w") as f: f.write(output)
def dump_ctree_to_lambda(create_subgraph=False): w = ida_kernwin.get_current_widget() if ida_kernwin.get_widget_type(w) == ida_kernwin.BWN_PSEUDOCODE: vu = ida_hexrays.get_widget_vdui(w) if vu: vu.get_current_item(ida_hexrays.USE_MOUSE) focusitem = vu.cfunc.body if create_subgraph: focusitem = vu.item.e if vu.item.is_citem() else None if focusitem: gd = graph_dumper_t() gd.apply_to(focusitem, vu.cfunc.body) lines = "(%s)" % " and\n".join(gd.lines) print("%s\n%x:\n%s" % ("-" * 80, ida_kernwin.get_screen_ea(), lines))
def get_qword(ea=None, original=False): """ Static method allowing to get the value of one qword at an address. :param ea: The address at which recuperating the value. If ``None`` the screen address is used. :param original: If True the value recuperated will be the original one (before a patch). Default: False. :return: An integer corresponding to the value at the address. """ if ea is None: ea = ida_kernwin.get_screen_ea() if original: return ida_bytes.get_original_qword(ea) else: return ida_bytes.get_qword(ea)
def activate(self, ctx): # get active filename if not ida_nalt.get_root_filename(): print('FakePDB/import offsets: file not loaded') return 1 screen_ea = ida_kernwin.get_screen_ea() finder = SignatureFinder() sig = finder.get_signature(screen_ea) print('FakePDB/signatures_find:') print(' * address : %s' % hex(screen_ea)) print(' * name : %s' % ida_name.get_name(screen_ea)) print(' * signature: %s' % sig) print('') return 0