def extract_item(viewer, stripped=False): cnt = ida_kernwin.get_custom_viewer_place(viewer, True)[1] line = ida_kernwin.get_custom_viewer_curline(viewer, True) tags = [ida_lines.SCOLOR_ON, ida_lines.SCOLOR_OFF] expr = re.compile("[A-Z0-9_]") def find_pos(line, pos, inc): while 0 <= pos < len(line): if not stripped and line[pos] in tags: break if stripped and not expr.match(line[pos]): break pos += inc return pos pos = ida_lines.tag_advance(line, cnt) if pos < 0 or pos >= len(line): return while line[pos] in [ida_lines.SCOLOR_ON, ida_lines.SCOLOR_OFF]: pos += 2 if pos < 0 or pos >= len(line): return prev_pos, next_pos = find_pos(line, pos, -1), find_pos(line, pos, +1) if stripped: return None, line[prev_pos + 1:next_pos].strip() return line[prev_pos + 1], line[prev_pos + 2:next_pos].strip()
def OnKeydown(self, vkey, shift): if shift == 0 and vkey == ord("G"): microcode_graphviewer_t(self._mba, self.title).Show() return True elif shift == 0 and vkey == ord("I"): widget = self.GetWidget() line = kw.get_custom_viewer_curline(widget, False) line = ida_lines.tag_remove(line) if '.' in line: block, serial = line.split('.')[:2] serial = serial.strip().split(' ')[0] microcode_insnviewer_t(self._mba, self.mmat_name, self.fn_name, int(block), int(serial)).Show() return True return False
def OnKeydown(self, vkey, shift): if shift == 0 and vkey == ord("G"): MCGraphView(self._mba, self._func, self._mmat).Show() return True elif shift == 0 and vkey == ord("I"): widget = self.GetWidget() line = ida_kernwin.get_custom_viewer_curline(widget, False) line = ida_lines.tag_remove(line) if '.' in line: block, serial = line.split('.')[:2] serial = serial.strip().split(' ')[0] MCInsnView(self._mba, self._func, self._mmat, int(block), int(serial)).Show() return True return False
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 OnKeydown(self, vkey, shift): if vkey == ord("G"): g = microcode_graphviewer_t(self._mba, self.title, self.lines) if g: g.Show() self._fit_graph(g) self._dock_widgets( g, dockpos=kw.DP_FLOATING if shift else kw.DP_RIGHT) return True elif vkey == ord("I"): """TODO: at some point, the textual representation of the mba should manually be created. -> we would no longer have to parse the textual output that is created by the gen_microcode() function .> we may insert COLOR_ADDR tags which would allow us to contextually link different viewers""" widget = self.GetWidget() line = kw.get_custom_viewer_curline(widget, False) line = ida_lines.tag_remove(line) p = line.find(" ") if p != -1 and '.' in line[:p]: block, serial = line.split('.')[:2] serial = serial.strip().split(' ')[0] g = microcode_insnviewer_t(self._mba, self.mmat_name, self.fn_name, int(block), int(serial)) if g: g.Show() self._fit_graph(g) self._dock_widgets( g, dockpos=kw.DP_FLOATING if shift else kw.DP_TAB) else: message = ( "There is something wrong with the output generated by gen_microcode()!\n" "Please rerun '%s.py'!" % PLUGIN_NAME) if line.startswith(";") or not (len(line)): message = "Please position the cursor on a microcode instruction." kw.warning(message) return True return False
def activate(self, ctx): # get the current item vu = ida_hexrays.get_widget_vdui(ctx.widget) vu.get_current_item(ida_hexrays.USE_KEYBOARD) # REGION1, will be referenced later # check that the current item is a union field if not vu.item.is_citem(): ida_kernwin.warning("Please position the cursor on a union member") return 0 e = vu.item.e while True: op = e.op if op != ida_hexrays.cot_memptr and op != ida_hexrays.cot_memref: ida_kernwin.warning( "Please position the cursor on a union member") return 0 e = e.x if op == ida_hexrays.cot_memptr: if e.type.is_union(): break else: if ida_typeinf.remove_pointer(e.type).is_union(): break if not e.type.is_udt(): ida_kernwin.warning( "Please position the cursor on a union member") return 0 # END REGION1 # REGION2 # calculate the member offset off = 0 e = vu.item.e while True: e2 = e.x tif = ida_typeinf.remove_pointer(e2.type) if not tif.is_union(): off += e.m e = e2 if e2.op != ida_hexrays.cot_memptr and e2.op != ida_hexrays.cot_memref: break if not e2.type.is_udt(): break # END REGION2 # REGION3 # go up and collect more member references (in order to calculate the final offset) p = vu.item.e while True: p2 = vu.cfunc.body.find_parent_of(p) if p2.op == ida_hexrays.cot_memptr: break if p2.op == ida_hexrays.cot_memref: e2 = p2.cexpr tif = ida_typeinf.remove_pointer(e2.x.type) if not tif.is_union(): off += e2.m p = p2 continue if p2.op == ida_hexrays.cot_ref: # handle &a.b + N (this expression may appear if the user previously selected # a wrong field) delta = 0 add = vu.cfunc.body.find_parent_of(p2) if add.op == ida_hexrays.cot_cast: add = vu.cfunc.body.find_parent_of(add) if add.op == ida_hexrays.cot_add and add.y.op == ida_hexrays.cot_num: delta = add.y.numval() objsize = add.type.get_ptrarr_objsize() nbytes = delta * objsize off += nbytes # we could use helpers like WORD/BYTE/... to calculate a more precise offset # if ( p2->op == cot_call && (e2->exflags & EXFL_LVALUE) != 0 ) break # END REGION3 # REGION4 ea = vu.item.e.ea # the item itself may be unaddressable. # TODO: find its addressable parent if ea == ida_idaapi.BADADDR: ida_kernwin.warning("Sorry, the current item is not addressable") return 0 # END REGION4 # REGION5 # prepare the text representation for the item, # use the neighborhoods of cursor line = ida_lines.tag_remove( ida_kernwin.get_custom_viewer_curline(vu.ct, False)) line_len = len(line) x = max(0, vu.cpos.x - 10) l = min(10, line_len - vu.cpos.x) + 10 line = line[x:x + l] # END REGION5 # REGION6 ops = ida_hexrays.ui_stroff_ops_t() op = ops.push_back() op.offset = off op.text = line # END REGION6 # REGION7 class set_union_sel_t(ida_hexrays.ui_stroff_applicator_t): def __init__(self, ea): ida_hexrays.ui_stroff_applicator_t.__init__(self) self.ea = ea def apply(self, opnum, path, top_tif, spath): typename = ida_typeinf.print_tinfo('', 0, 0, ida_typeinf.PRTYPE_1LINE, top_tif, '', '') ida_kernwin.msg("User selected %s of type %s\n" % (spath, typename)) if path.empty(): return False vu.cfunc.set_user_union_selection(self.ea, path) vu.cfunc.save_user_unions() return True # END REGION7 # REGION8 su = set_union_sel_t(ea) res = ida_hexrays.select_udt_by_offset(None, ops, su) if res != 0: # regenerate ctree vu.refresh_view(True) # END REGION8 return 1
def get_curline_striped_from_viewer(viewer): line = ida_kernwin.get_custom_viewer_curline(viewer, False) line = ida_lines.tag_remove(line) return line
def get_curline_striped_from_viewer(viewer): return ida_lines.tag_remove(ida_kernwin.get_custom_viewer_curline(viewer, False))