def finish_populating_widget_popup(self, widget, popup): if ida_kernwin.get_widget_type(widget) == \ ida_kernwin.BWN_DISASM: ida_kernwin.attach_action_to_popup(widget, popup, act_name, None)
def show_ctree_graph(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.item.e if vu.item.is_citem() else None sub = None if create_subgraph: if not focusitem: return sub = "subgraph %x" % focusitem.obj_id # create graphviewer cg = cfunc_graph_t(focusitem, HRDevHelper.config, close_open=True, subtitle=sub) # build graph for current function gb = graph_builder_t(cg, None if create_subgraph else vu.cfunc) gb.apply_to(focusitem if create_subgraph else vu.cfunc.body, vu.cfunc.body) # show graph cg.Show() # set zoom and dock position cg.zoom_and_dock(w) return
def finish_populating_widget_popup(self, widget, popup_handle): if kw.get_widget_type(widget) == kw.BWN_PSEUDOCODE: class FilterHandler(kw.action_handler_t): def __init__(self, name): self.name = name kw.action_handler_t.__init__(self) def activate(self, ctx): obj = FILTERS[self.name] obj.set_activated(not obj.is_activated()) vu = hr.get_widget_vdui(ctx.widget) if vu: vu.refresh_view(not obj.is_activated()) return 1 def update(self, ctx): return kw.AST_ENABLE_FOR_WIDGET for name, obj in FILTERS.items(): action_desc = kw.action_desc_t( '%s%s' % (ACTION_NAME, name), name, FilterHandler(name), None, None, 34 if obj.is_activated() else -1) kw.attach_dynamic_action_to_popup(widget, popup_handle, action_desc, POPUP_ENTRY)
def get_lines_rendering_info_ev(self, out, widget, rin): wt = ida_kernwin.get_widget_type(widget) if wt == ida_kernwin.BWN_PSEUDOCODE: vu = ida_hexrays.get_widget_vdui(widget) if vu: cf = vu.cfunc if cf.entry_ea not in self.funcs: return vusync = self.funcs[cf.entry_ea] ea = self.ea if ea in vusync: slist = vusync.get_items(ea) for section_lines in rin.sections_lines: for line in section_lines: lnnum = ida_kernwin.place_t.as_simpleline_place_t(line.at).n for sync_info in slist: ix, iy, ilen = sync_info if lnnum == iy: e = ida_kernwin.line_rendering_output_entry_t(line) e.bg_color = COLOR e.cpx = ix e.nchars = ilen e.flags |= ida_kernwin.LROEF_CPS_RANGE out.entries.push_back(e) return
def finish_populating_widget_popup(self, widget, popup_handle): if ida_kernwin.get_widget_type(widget) == idaapi.BWN_DISASM: for item in self.MENU_ITEMS: if item.popup: idaapi.attach_action_to_popup(widget, popup_handle, item.action, self.plugin_name + "/")
def finish_populating_widget_popup(self, widget, popup_handle): if ida_kernwin.get_widget_type(widget) == ida_kernwin.BWN_PSEUDOCODE: class menu_handler_t(ida_kernwin.action_handler_t): def __init__(self, name): ida_kernwin.action_handler_t.__init__(self) self.name = name def activate(self, ctx): if self.name == HRDevHelper.get_action_name( HRDevHelper.act_show_ctree): show_ctree_graph() elif self.name == HRDevHelper.get_action_name( HRDevHelper.act_show_sub_tree): show_ctree_graph(create_subgraph=True) elif self.name == HRDevHelper.get_action_name( HRDevHelper.act_show_context): context_viewer_t.open() else: ida_kernwin.warning("Not implemented") return 1 def update(self, ctx): return ida_kernwin.AST_ENABLE_FOR_WIDGET for actname, data in self.actions.items(): desc, hotkey = data action_desc = ida_kernwin.action_desc_t( actname, desc, menu_handler_t(actname), hotkey, None, -1) ida_kernwin.attach_dynamic_action_to_popup( widget, popup_handle, action_desc, "%s/" % PLUGIN_NAME)
def _render_lines(self, lines_out, widget, lines_in): """ (Event) IDA is about to render code viewer lines. """ widget_type = ida_kernwin.get_widget_type(widget) if widget_type == ida_kernwin.BWN_DISASM: self._highlight_disassesmbly(lines_out, widget, lines_in) return
def finish_populating_widget_popup(self, widget, popup): # We'll add our action to all "IDA View-*"s. # If we wanted to add it only to "IDA View-A", we could # also discriminate on the widget's title: # # if ida_kernwin.get_widget_title(widget) == "IDA View-A": # ... # if ida_kernwin.get_widget_type(widget) == ida_kernwin.BWN_DISASM: ida_kernwin.attach_action_to_popup(widget, popup, act_name, None)
def screen_ea_changed_ev(self, ea, prev_ea): # react to screen ea changes issued by PSEUDOCODE and DISASM views if (ida_kernwin.get_widget_type(ida_kernwin.get_current_widget()) in [ida_kernwin.BWN_PSEUDOCODE, ida_kernwin.BWN_DISASM]): self.ea = ea # why does refresh_idaview_anyway() work but request_refresh() doesn't? #ida_kernwin.clear_refresh_request(ida_kernwin.IWID_PSEUDOCODE) #ida_kernwin.request_refresh(ida_kernwin.IWID_PSEUDOCODE, True) ida_kernwin.refresh_idaview_anyway() return
def render_lines(self, lines_out, widget, lines_in): """ (Event) IDA is about to render code viewer lines. """ widget_type = ida_kernwin.get_widget_type(widget) if widget_type == ida_kernwin.BWN_PSEUDOCODE and self._sync_status: self._highlight_hexrays(lines_out, widget, lines_in) elif widget == self._code_widget: self._highlight_microcode(lines_out, widget, lines_in) return
def make_name(): """rename current item""" """TODO:replace with custom implementation that allows parameters such as name and flags ("create name anyway") to be set """ cv = ida_kernwin.get_current_viewer() if cv: hx = ida_kernwin.get_widget_type(cv) == ida_kernwin.BWN_PSEUDOCODE ida_kernwin.process_ui_action("hx:Rename" if hx else "MakeName") return
def view_dblclick(self, viewer, point): widget_type = ida_kernwin.get_widget_type(viewer) if not (widget_type == 48 or widget_type == 28): return # Decompiler or Structures window place, x, y = ida_kernwin.get_custom_viewer_place(viewer, False) line = utils.get_curline_striped_from_viewer(viewer) func_cand_name = cpp_utils.find_valid_cppname_in_line(line, x) if func_cand_name is not None: func_cand_ea = ida_name.get_name_ea(BADADDR, func_cand_name) if func_cand_ea is not None and utils.is_func(func_cand_ea): idc.jumpto(func_cand_ea)
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 finish_populating_widget_popup(self, form, popup): tft = ida_kernwin.get_widget_type(form) if tft != idaapi.BWN_DISASM: return pos = idc.get_screen_ea() register_dynamic_action(form, popup, 'Decode All IOCTLs in Function', DecodeAllHandler()) register_dynamic_action(form, popup, 'Decode IOCTLs using Angr', DecodeAngrHandler()) # If the second argument to the current selected instruction is an immediately # then give the option to decode it. if idc.get_operand_type(pos, 1) == 5: register_dynamic_action(form, popup, 'Decode IOCTL', DecodeHandler()) if pos in ioctl_tracker.ioctl_locs: register_dynamic_action(form, popup, 'Invalid IOCTL', InvalidHandler()) if len(ioctl_tracker.ioctl_locs) > 0: register_dynamic_action(form, popup, 'Show All IOCTLs', ShowAllHandler())
def rename_func(): """rename function, suggests current identifier as function name""" name = _get_identifier() if name: str = ida_kernwin.ask_str(name, -1, "Rename function") if str: f = ida_funcs.get_func(ida_kernwin.get_screen_ea()) if f: if ida_name.set_name(f.start_ea, str, ida_name.SN_NOCHECK): cv = ida_kernwin.get_current_viewer() if ida_kernwin.get_widget_type( cv) == ida_kernwin.BWN_PSEUDOCODE: vd = ida_hexrays.get_widget_vdui(cv) if vd: vd.refresh_view(True) return
def get_custom_viewer_hint(self, view, place): try: widget = ida_kernwin.get_current_widget() if ida_kernwin.get_widget_type(widget) != ida_kernwin.BWN_DISASM: return None curline = ida_kernwin.get_custom_viewer_curline(view, True) # sometimes get_custom_viewer_place() returns [x, y] and sometimes [place_t, x, y]. # we want the place_t. viewer_place = ida_kernwin.get_custom_viewer_place(view, True) if len(viewer_place) != 3: return None _, x, y = viewer_place ea = place.toea() # "color" is a bit of misnomer: its the type of the symbol currently hinted color = get_color_at_char(curline, x) if color != ida_lines.COLOR_ADDR: return None # grab the FAR references to code (not necessarilty a branch/call/jump by itself) far_code_references = [ xref.to for xref in idautils.XrefsFrom(ea, ida_xref.XREF_FAR) if ida_bytes.is_code(ida_bytes.get_flags(xref.to)) ] if len(far_code_references) != 1: return None fva = far_code_references[0] # ensure its actually a function if not idaapi.get_func(fva): return None # this magic constant is the number of "important lines" to display by default. # the remaining lines get shown if you scroll down while the hint is displayed, revealing more lines. return render_function_hint(fva), DEFAULT_IMPORTANT_LINES_NUM except Exception as e: logger.warning( 'unexpected exception: %s. Get in touch with @williballenthin.', e, exc_info=True) return None
def run(self, arg): w = ida_kernwin.get_current_widget() if ida_kernwin.get_widget_type(w) == ida_kernwin.BWN_PSEUDOCODE: vu = ida_hexrays.get_widget_vdui(w) vu_title = ida_kernwin.get_widget_title(w) if vu: vu.get_current_item(ida_hexrays.USE_KEYBOARD) highlight = vu.item.e if vu.item.is_citem() else None # create graphviewer cg = cfunc_graph_t(highlight, True) # build graph for current function gb = graph_builder_t(cg) gb.apply_to(vu.cfunc.body, None) # show graph cg.Show() # set zoom and dock position cg.zoom_and_dock(vu_title, ZOOM, DOCK_POSITION)
def run(self, arg): global tainted_pcs # this is called when select the plugin from the Edit>Plugins menu curwidget = ida_kernwin.get_current_widget() if (ida_kernwin.BWN_PSEUDOCODE == ida_kernwin.get_widget_type( curwidget)): reuse = HIT2_ReuseDialog.GET_NEW_PROCESS clear_old = False if (len(tainted_pcs) > 0): reuse = HIT2_ReuseDialog.askToReuse() if (HIT2_ReuseDialog.GET_NEW_PROCESS == reuse): tainted_pcs.clear() # need to clear old colors in case changing process on the # same decompiled function that colored before clear_old = True if (HIT2_ReuseDialog.CANCEL_REQUEST != reuse): self.color_pseudocode(curwidget, clear_old) else: ida_kernwin.msg("Current window is not a pseudocode window\n")
def run(self, arg): w = ida_kernwin.get_current_widget() if ida_kernwin.get_widget_type(w) == ida_kernwin.BWN_PSEUDOCODE: vu = ida_hexrays.get_widget_vdui(w) vu_title = ida_kernwin.get_widget_title(w) if vu: vu.get_current_item(ida_hexrays.USE_KEYBOARD) focusitem = vu.item.e if vu.item.is_citem() else None # create graphviewer cg = cfunc_graph_t(focusitem, self.config, close_open=True) # build graph for current function gb = graph_builder_t(cg) gb.apply_to(vu.cfunc.body, None) # show graph cg.Show() # set zoom and dock position cg.zoom_and_dock(vu_title, self.config["options"]["zoom"], self.config["options"]["dockpos"])
def get_custom_viewer_hint(self, viewer, place): widget_type = ida_kernwin.get_widget_type(viewer) if widget_type != ida_kernwin.BWN_DISASM: return flags = ida_bytes.get_flags(place.toea()) if place else 0 if not ida_bytes.is_code(flags): return item = AMIE.extract_item(viewer) if not item: return tag, val = item hint = self.arch.hint(place.toea(), tag, val) if not hint: return return AMIE.format_hint(*hint)
def view_dblclick(self, viewer, point): widget_type = ida_kernwin.get_widget_type(viewer) if not (widget_type == 48 or widget_type == 28): return # Decompiler or Structures window func_cand_name = None place, x, y = ida_kernwin.get_custom_viewer_place(viewer, False) if place.name() == "structplace_t": # Structure window: structplace = ida_kernwin.place_t_as_structplace_t(place) if structplace is not None: s = ida_struct.get_struc(ida_struct.get_struc_by_idx(structplace.idx)) if s: member = ida_struct.get_member(s, structplace.offset) if member: func_cand_name = ida_struct.get_member_name(member.id) if func_cand_name is None: line = utils.get_curline_striped_from_viewer(viewer) func_cand_name = cpp_utils.find_valid_cppname_in_line(line, x) if func_cand_name is not None: func_cand_ea = ida_name.get_name_ea(BADADDR, func_cand_name) if func_cand_ea is not None and utils.is_func_start(func_cand_ea): idc.jumpto(func_cand_ea)
def finish_populating_widget_popup(self, w, popup): if ida_kernwin.get_widget_type(w) == ida_kernwin.BWN_FUNCS: ida_kernwin.attach_action_to_popup(w, popup, ACTION_NAME, None)
def get_lines_rendering_info(self, out, widget, info): if kw.get_widget_type(widget) == kw.BWN_PSEUDOCODE: for name, obj in FILTERS.items(): if obj.is_activated(): obj.get_lines_rendering_info_ev(out, widget, info) return
def get_widget_type(form): if idaapi.IDA_SDK_VERSION <= 699: retval = idaapi.get_tform_type(form) else: retval = ida_kernwin.get_widget_type(form) return retval
def populating_widget_popup(self, widget, popup): if ida_kernwin.get_widget_type(widget) == ida_kernwin.BWN_PSEUDOCODE: ida_kernwin.attach_action_to_popup(widget, popup, ACTION_NAME)
def _popup_hook(self, widget, popup): """ (Event) IDA is about to show a popup for the given TWidget. """ # TODO: return if plugin/trace is not active pass # fetch the (IDA) window type (eg, disas, graph, hex ...) view_type = ida_kernwin.get_widget_type(widget) # only attach these context items to popups in disas views if view_type == ida_kernwin.BWN_DISASMS: # prep for some shady hacks p_qmenu = ctypes.cast(int(popup), ctypes.POINTER(ctypes.c_void_p))[0] qmenu = sip.wrapinstance(int(p_qmenu), QtWidgets.QMenu) # # inject and organize the Tenet plugin actions # ida_kernwin.attach_action_to_popup( widget, popup, self.ACTION_NEXT_EXECUTION, # The action ID (see above) "Rename", # Relative path of where to add the action ida_kernwin.SETMENU_APP # We want to append the action after ^ ) # # this is part of our bodge to inject a plugin action submenu # at a specific location in the QMenu, cuz I don't think it's # actually possible with the native IDA API's (for groups...) # for action in qmenu.actions(): if action.text() == "Go to next execution": # inject a group for the exta 'go to' actions goto_submenu = QtWidgets.QMenu("Go to...") qmenu.insertMenu(action, goto_submenu) # hold a Qt ref of the submenu so it doesn't GC self.__goto_submenu = goto_submenu break ida_kernwin.attach_action_to_popup( widget, popup, self.ACTION_FIRST_EXECUTION, # The action ID (see above) "Go to.../", # Relative path of where to add the action ida_kernwin.SETMENU_APP # We want to append the action after ^ ) ida_kernwin.attach_action_to_popup( widget, popup, self.ACTION_FINAL_EXECUTION, # The action ID (see above) "Go to.../", # Relative path of where to add the action ida_kernwin.SETMENU_APP # We want to append the action after ^ ) ida_kernwin.attach_action_to_popup( widget, popup, self.ACTION_PREV_EXECUTION, # The action ID (see above) "Rename", # Relative path of where to add the action ida_kernwin.SETMENU_APP # We want to append the action after ^ ) # # inject a seperator to help insulate our plugin action group # for action in qmenu.actions(): if action.text() == "Go to previous execution": qmenu.insertSeparator(action) break
def finish_populating_widget_popup(self, form, popup): if ida_kernwin.get_widget_type(form) == ida_kernwin.BWN_CPUREGS: ida_kernwin.attach_action_to_popup(form, popup, ACTION_NAME)
def finish_populating_widget_popup_ev(self, widget, popup_handle): if ida_kernwin.get_widget_type(widget) == ida_kernwin.BWN_PSEUDOCODE: class EAHandler(ida_kernwin.action_handler_t): def __init__(self, ea): self.ea = ea ida_kernwin.action_handler_t.__init__(self) def activate(self, ctx): ida_kernwin.jumpto(self.ea) return 1 def update(self, ctx): return ida_kernwin.AST_ENABLE_FOR_WIDGET class callees_t: def __init__(self, start_ea, max_recursion=MAX_DEPTH, max_func=MAX_FUNC): self.ea = start_ea name = ida_name.get_short_name(self.ea) if not len(name): name = "unkn_%x" % self.ea self.base_path = "childs [%s]" % name self.mr = max_recursion self.mf = max_func self.paths = {} self._recurse(self.ea, self.base_path, 0) # TODO: check processing of recursive functions def _recurse(self, ea, path, depth): if depth >= self.mr: self.paths[path] = [("[...]", BADADDR)] return # for all callees of ea... i = 0 for cea in Callees(ea): if i + 1 >= self.mf: self.paths[path].append(("...", BADADDR)) break loc_name = ida_name.get_short_name(cea) if not len(loc_name): loc_name = "unkn_%x" % cea elem = (loc_name, cea) # if path doesn't exist yet if path not in self.paths: self.paths[path] = [elem] # if caller doesn't exist yet if elem not in self.paths[path]: self.paths[path].append(elem) i += 1 newpath = "%s/%s" % (path, loc_name) self._recurse(cea, newpath, depth + 1) return class callers_t: def __init__(self, start_ea, max_recursion=MAX_DEPTH, max_func=MAX_FUNC): self.ea = start_ea name = ida_name.get_short_name(self.ea) if not len(name): name = "unkn_%x" % self.ea self.base_path = "parents [%s]" % name self.mr = max_recursion self.mf = max_func self.paths = {} self._recurse(self.ea, self.base_path, 0) # TODO: check processing of recursive functions def _recurse(self, ea, path, depth): if depth + 1 >= self.mr: self.paths[path] = [("[...]", BADADDR)] return # for all callers of ea... i = 0 for ref in idautils.CodeRefsTo(ea, False): if i + 1 >= self.mf: self.paths[path].append(("...", BADADDR)) break cea = ref func = ida_funcs.get_func(cea) if func: cea = func.start_ea loc_name = ida_name.get_short_name(cea) if not len(loc_name): loc_name = "unkn_%x" % cea elem = (loc_name, cea) # if path doesn't exist yet if path not in self.paths: self.paths[path] = [elem] # if caller doesn't exist yet if elem not in self.paths[path]: self.paths[path].append(elem) i += 1 newpath = "%s/%s" % (path, loc_name) self._recurse(cea, newpath, depth + 1) return def build_menu(item_ea): callers = callers_t(item_ea) for path, info in callers.paths.items(): for loc_name, ea in info: desc = ida_kernwin.action_desc_t( "abyss:caller_%s_%s" % (path, loc_name), "%s" % (loc_name), EAHandler(ea), None, None, 41 if ea != BADADDR else -1) ida_kernwin.attach_dynamic_action_to_popup( widget, popup_handle, desc, "%s (%d)/" % (path, len(info)), ida_kernwin.SETMENU_APP) callees = callees_t(item_ea) for path, info in callees.paths.items(): for loc_name, ea in info: desc = ida_kernwin.action_desc_t( "abyss:callee_%s_%s" % (path, loc_name), "%s" % (loc_name), EAHandler(ea), None, None, 41 if ea != BADADDR else -1) ida_kernwin.attach_dynamic_action_to_popup( widget, popup_handle, desc, "%s (%d)/" % (path, len(info)), ida_kernwin.SETMENU_APP) ea = ida_kernwin.get_screen_ea() vu = ida_hexrays.get_widget_vdui(widget) if vu and vu.get_current_item(ida_hexrays.USE_KEYBOARD): if vu.item.it.is_expr( ) and vu.item.it.op is ida_hexrays.cot_obj: _ea = vu.item.e.cexpr.obj_ea if _ea != BADADDR: ea = _ea pfn = ida_funcs.get_func(ea) if pfn and pfn.start_ea == ea: build_menu(ea)