""" summary: retrieve & dump current selection description: Shows how to retrieve the selection from a listing widget ("IDA View-A", "Hex View-1", "Pseudocode-A", ...) as two "cursors", and from there retrieve (in fact, generate) the corresponding text. After running this script: * select some text in one of the listing widgets (i.e., "IDA View-...", "Local Types", "Pseudocode-...") * press Ctrl+Shift+S to dump the selection level: advanced """ import ida_kernwin import ida_lines def get_widget_lines(widget, tp0, tp1): """ get lines between places tp0 and tp1 in widget """ ud = ida_kernwin.get_viewer_user_data(widget) lnar = ida_kernwin.linearray_t(ud) lnar.set_place(tp0.at) lines = [] while True: cur_place = lnar.get_place() first_line_ref = ida_kernwin.l_compare2(cur_place, tp0.at, ud) last_line_ref = ida_kernwin.l_compare2(cur_place, tp1.at, ud) if last_line_ref > 0: # beyond last line break line = ida_lines.tag_remove(lnar.down()) if last_line_ref == 0: # at last line line = line[0:tp1.x] elif first_line_ref == 0: # at first line line = " " * tp0.x + line[tp0.x:] lines.append(line) return lines class dump_selection_handler_t(ida_kernwin.action_handler_t): def activate(self, ctx): if ctx.has_flag(ida_kernwin.ACF_HAS_SELECTION): lines = get_widget_lines(ctx.widget, ctx.cur_sel._from, ctx.cur_sel.to) for line in lines: print(line) return 1 def update(self, ctx): ok_widgets = [ ida_kernwin.BWN_DISASM, ida_kernwin.BWN_TILVIEW, ida_kernwin.BWN_PSEUDOCODE, ] return ida_kernwin.AST_ENABLE_FOR_WIDGET \ if ctx.widget_type in ok_widgets \ else ida_kernwin.AST_DISABLE_FOR_WIDGET # ----------------------------------------------------------------------- # create actions (and attach them to IDA View-A's context menu if possible) ACTION_NAME = "dump_selection" ACTION_SHORTCUT = "Ctrl+Shift+S" if ida_kernwin.unregister_action(ACTION_NAME): print("Unregistered previously-registered action \"%s\"" % ACTION_NAME) if ida_kernwin.register_action( ida_kernwin.action_desc_t( ACTION_NAME, "Dump selection", dump_selection_handler_t(), ACTION_SHORTCUT)): print("Registered action \"%s\"" % ACTION_NAME) # dump current selection p0 = ida_kernwin.twinpos_t() p1 = ida_kernwin.twinpos_t() view = ida_kernwin.get_last_widget(ida_kernwin.IWID_ANY_LISTING) if ida_kernwin.read_selection(view, p0, p1): lines = get_widget_lines(view, p0, p1) print("\n".join(lines))