Пример #1
0
    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()
Пример #2
0
 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
Пример #3
0
 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
Пример #4
0
    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
Пример #5
0
 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
Пример #6
0
    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
Пример #7
0
def get_curline_striped_from_viewer(viewer):
    line = ida_kernwin.get_custom_viewer_curline(viewer, False)
    line = ida_lines.tag_remove(line)
    return line
Пример #8
0
def get_curline_striped_from_viewer(viewer):
    return ida_lines.tag_remove(ida_kernwin.get_custom_viewer_curline(viewer, False))