Beispiel #1
0
 def _color_var(self, vu, item):
     global COLOR_VARS
     if not item:
         return
     pc = vu.cfunc.get_pseudocode()
     if item in COLOR_VARS:
         for sl in pc:
             sl.line = sl.line.replace(
                 ida_lines.COLSTR(item, ida_lines.SCOLOR_ERROR), item)
         COLOR_VARS.remove(item)
     else:
         for sl in pc:
             pos = 0
             while True:
                 pos = sl.line.find(item, pos)
                 if pos < 0:
                     break
                 if not sl.line[pos + len(item)].isalnum():
                     sl.line = sl.line[:pos] + ida_lines.COLSTR(
                         item,
                         ida_lines.SCOLOR_ERROR) + sl.line[pos + len(item):]
                     pos += len(
                         ida_lines.COLSTR(item, ida_lines.SCOLOR_ERROR))
                 else:
                     pos += 1
             # sl.line = sl.line.replace(item, ida_lines.COLSTR(item, ida_lines.SCOLOR_ERROR))
         COLOR_VARS.append(item)
     refresh_idaview_anyway()
 def disasm(self, inst):
     """A simple local disassembler. In reality one can use a full-blown disassembler to render the text"""
     opbyte = ord(inst[0]) if sys.version_info.major < 3 else inst[0]
     op = opbyte >> 4
     if not (1 <= op <= 5):
         return None
     r1 = (opbyte & 0xf) >> 2
     r2 = opbyte & 3
     sz = 0
     if r2 == 0:
         if len(inst) != 5:
             return None
         imm = struct.unpack_from('L', inst, 1)[0]
         sz = 5
     else:
         imm = None
         sz = 1
     text = "%s %s, %s" % (
         ida_lines.COLSTR(simplevm_data_format.INST[op],
                          ida_lines.SCOLOR_INSN),
         ida_lines.COLSTR(simplevm_data_format.REGS[r1],
                          ida_lines.SCOLOR_REG),
         ida_lines.COLSTR("0x%08X" % imm, ida_lines.SCOLOR_NUMBER)
         if imm is not None else ida_lines.COLSTR(
             simplevm_data_format.REGS[r2], ida_lines.SCOLOR_REG))
     return (sz, text)
Beispiel #3
0
 def as_id(self, s):
     t = s.lower()
     if t in self.register_list:
         return ida_lines.COLSTR(s, ida_lines.SCOLOR_REG)
     elif t in self.instruction_list:
         return ida_lines.COLSTR(s, ida_lines.SCOLOR_INSN)
     else:
         return s
Beispiel #4
0
def render_function_hint(fva):
    '''
    create a textual report for the call and string references in the given function.
    
    eg.

        3 calls, 4 strings

        calls:
          - call     new
          - call     gethostbyname
          - call     delete
    
        strings:
          - www.google.com
          - www.bing.com
          - www.yahoo.com
          - www.cnn.com
    
    Args:
      fva (int): the starting address of a function

    Returns:
      str: the report
    '''
    ret = []

    # use `uniq` here (vs using a set) cause we want to maintain *some* semblance of order.
    calls = list(uniq(d for f, d in enum_calls_in_function(fva)))
    strings = list(uniq(s for o, r, s in enum_string_refs_in_function(fva)))

    # this would be a good place to use Jinja2 templating,
    #  but lets not require that external dependency
    title = ida_lines.COLSTR('%d calls, ' % len(calls),
                             ida_lines.SCOLOR_CODNAME)
    title += ida_lines.COLSTR('%s strings' % len(strings),
                              ida_lines.SCOLOR_DSTR)
    ret.append(title)

    ret.append('')
    if calls:
        ret.append(ida_lines.COLSTR('calls:', ida_lines.SCOLOR_CODNAME))
        for call in calls:
            ret.append('  - ' + call)
        ret.append('')

    if strings:
        ret.append(ida_lines.COLSTR('strings:', ida_lines.SCOLOR_DSTR))
        for s in strings:
            ret.append('  - ' + ida_lines.COLSTR(s, ida_lines.SCOLOR_DSTR))

    return '\n'.join(ret)
Beispiel #5
0
 def _contains_item(self, pc, items, remove=False):
     for sl in pc:
         line = self._strip_line(sl.line)
         s = ''.join(items)
         count = line.count(s)
         if count <= 0:
             continue
         #print(count, line)
         start = 0
         fact = 0
         for i in range(13):  # max 13 times to try to match
             if fact == count:
                 continue  # find all arguments
             pos = len(sl.line)
             found = True
             pos = sl.line.find(items[-1], start, pos)
             old_start = start
             start = pos + 1
             if pos < 0 or (pos+len(items[-1])<len(sl.line) and sl.line[pos+len(items[-1])].isalnum()) or \
                 ((pos-1) >= 0 and sl.line[pos-1].isalnum()):
                 continue
             for item in items[-2::-1]:
                 pos = sl.line.rfind(item, old_start, pos)
                 if pos < 0 or (pos+len(item)<len(sl.line) and sl.line[pos+len(item)].isalnum()) or \
                     ((pos-1) >= 0 and sl.line[pos-1].isalnum()):
                     found = False
                     break
             if found:
                 fact += 1
                 for item in items:
                     pos = sl.line.find(item, pos, start)
                     if pos + len(item) == len(
                             sl.line
                     ) or not sl.line[pos + len(item)].isalnum(
                     ) or pos - 1 < 0 or not sl.line[pos - 1].isalnum():
                         if remove:
                             sl.line = sl.line[:pos - 2] + item + sl.line[
                                 pos + len(item) + 2:]
                             start -= 4
                         else:
                             sl.line = sl.line[:pos] + ida_lines.COLSTR(
                                 item, ida_lines.SCOLOR_ERROR
                             ) + sl.line[pos + len(item):]
                             pos += len(
                                 ida_lines.COLSTR(item,
                                                  ida_lines.SCOLOR_ERROR))
                             start += 4
                     elif pos < 0:
                         continue
                     else:
                         pos += 1
Beispiel #6
0
    def Create(self, sn=None, use_colors=True):
        # Form the title
        title = "Simple custom view test"
        if sn:
            title += " %d" % sn
        self.use_colors = use_colors

        # Create the customviewer
        if not ida_kernwin.simplecustviewer_t.Create(self, title):
            return False

        for i in range(0, 100):
            prefix, bg = ida_lines.COLOR_DEFAULT, None
            # make every 10th line a bit special
            if i % 10 == 0:
                prefix = ida_lines.COLOR_DNAME  # i.e., dark yellow...
                bg = 0xFFFF00  # ...on cyan
            pfx = ida_lines.COLSTR("%3d" % i, ida_lines.SCOLOR_PREFIX)
            if self.use_colors:
                self.AddLine("%s: Line %d" % (pfx, i),
                             fgcolor=prefix,
                             bgcolor=bg)
            else:
                self.AddLine("%s: Line %d" % (pfx, i))

        return True
Beispiel #7
0
 def ResetOutput(self):
     self.ClearLines()
     self.AddLine(
         ida_lines.COLSTR(
             "Please press INS to enter command; X to clear output",
             ida_lines.SCOLOR_AUTOCMT))
     self.Refresh()
Beispiel #8
0
 def OnKeydown(self, vkey, shift):
     """
     User pressed a key
     @param vkey: Virtual key code
     @param shift: Shift flag
     @return: Boolean. True if you handled the event
     """
     print("OnKeydown, vk=%d shift=%d" % (vkey, shift))
     # ESCAPE?
     if vkey == 27:
         self.Close()
     # VK_DELETE
     elif vkey == 46:
         n = self.GetLineNo()
         if n is not None:
             self.DelLine(n)
             self.Refresh()
             print("Deleted line %d" % n)
     # Goto?
     elif vkey == ord('G'):
         n = self.GetLineNo()
         if n is not None:
             v = ida_kernwin.ask_long(self.GetLineNo(), "Where to go?")
             if v:
                 self.Jump(v, 0, 5)
     elif vkey == ord('R'):
         print("refreshing....")
         self.Refresh()
     elif vkey == ord('C'):
         print("refreshing current line...")
         self.RefreshCurrent()
     elif vkey == ord('A'):
         s = ida_kernwin.ask_str("NewLine%d" % self.Count(), 0,
                                 "Append new line")
         self.AddLine(s)
         self.Refresh()
     elif vkey == ord('X'):
         print("Clearing all lines")
         self.ClearLines()
         self.Refresh()
     elif vkey == ord('I'):
         n = self.GetLineNo()
         s = ida_kernwin.ask_str("InsertedLine%d" % n, 0, "Insert new line")
         self.InsertLine(n, s)
         self.Refresh()
     elif vkey == ord('E'):
         l = self.GetCurrentLine(notags=1)
         if not l:
             return False
         n = self.GetLineNo()
         print("curline=<%s>" % l)
         l = l + ida_lines.COLSTR("*", ida_lines.SCOLOR_VOIDOP)
         self.EditLine(n, l)
         self.RefreshCurrent()
         print("Edited line %d" % n)
     else:
         return False
     return True
Beispiel #9
0
def replace_addr_tags(s):
    tag = "%c%c" % (il.COLOR_ON, il.COLOR_ADDR)
    tag_size = len(tag)
    ti = {}
    p = s.find(tag)
    while p != -1:
        ti[s[p+tag_size:p+tag_size+il.COLOR_ADDR_SIZE]] = 0
        p = s.find(tag, p+tag_size+il.COLOR_ADDR_SIZE)
    for addr in ti.keys():
        s = s.replace(tag+addr, il.COLSTR("<%s>" % addr, il.SCOLOR_AUTOCMT)+tag+addr)
    return s
Beispiel #10
0
 def maturity_ev(self, cfunc, new_maturity):
     if new_maturity == ida_hexrays.CMAT_FINAL:
         lvars = cfunc.get_lvars()
         for lvar in lvars:
             if lvar.has_nice_name and not lvar.has_user_name:
                 vtype = "s" if lvar.is_stk_var(
                 ) else "r" if lvar.is_reg_var() else "u"
                 suffix = "_%s%d" % (vtype, lvar.width)
                 lvar.name += ida_lines.COLSTR(suffix,
                                               ida_lines.SCOLOR_AUTOCMT)
                 lvar.set_user_name()
     return 0
Beispiel #11
0
    def IssueCommand(self):
        s = ida_kernwin.ask_str(self.last_cmd, 0,
                                "Please enter a debugger command")
        if not s:
            return

        # Save last command
        self.last_cmd = s

        # Add it using a different color
        self.AddLine("debugger>" +
                     ida_lines.COLSTR(s, ida_lines.SCOLOR_VOIDOP))

        ok, out = ida_dbg.send_dbg_command(s)
        if ok:
            for line in out.split("\n"):
                self.AddLine(ida_lines.COLSTR(line, ida_lines.SCOLOR_LIBNAME))
        else:
            self.AddLine(
                ida_lines.COLSTR(
                    "Debugger is not active or does not export ida_dbg.send_dbg_command() (%s)"
                    % out, ida_lines.SCOLOR_ERROR))
        self.Refresh()
    def printf(self, value, current_ea, operand_num, dtid):
        # Is it already cached?
        val = self.cache_node.supval(current_ea)

        # Not cached?
        if val == None:
            # Retrieve it
            num = ida_idaapi.struct_unpack(value)
            val = self.get_rsrc_string(ida_nalt.get_input_file_path(), num)
            # Cache it
            self.cache_node.supset(current_ea, val)

        # Failed to retrieve?
        if val == "" or val == "\x00":
            return None
        # Return the format
        return "RSRC_STR(\"%s\")" % ida_lines.COLSTR(val, ida_lines.SCOLOR_IMPNAME)
Beispiel #13
0
 def tag_signed_ops(self, cf, item_codes):
     ci = hr.ctree_item_t()
     ccode = cf.get_pseudocode()
     for line_idx in range(cf.hdrlines, len(ccode)):
         items = []
         sl = ccode[line_idx]
         for char_idx in range(len(sl.line)):
             if cf.get_line_item(sl.line, char_idx, True, None, ci, None):
                 if ci.it.is_expr() and ci.e.op in item_codes:
                     #print("%s: unsigned op. line %d, pos %d" % (__file__, line_idx+1, char_idx))
                     items.append(ci.it.index)
         for item in list(dict.fromkeys(items)):
             tag = FMT % (ida_lines.COLOR_ON, ida_lines.COLOR_ADDR, item)
             sample = "/*signed*/"
             sl.line = sl.line.replace(
                 tag,
                 tag + ida_lines.COLSTR(sample, ida_lines.SCOLOR_ERROR))
Beispiel #14
0
def replace_addr_tags(cfunc, s):
    tag = "%c%c" % (il.COLOR_ON, il.COLOR_ADDR)
    tag_size = len(tag)
    ti = {}
    p = s.find(tag)
    while p != -1:
        ti[s[p+tag_size:p+tag_size+il.COLOR_ADDR_SIZE]] = 0
        p = s.find(tag, p+tag_size+il.COLOR_ADDR_SIZE)
    for addr in ti.keys():
        idx = int(addr, 16)
        a = ida_hexrays.ctree_anchor_t()
        a.value = idx
        if a.is_valid_anchor() and a.is_citem_anchor():
            item = cfunc.treeitems.at(a.get_index())
            if item:
                ctype_name = ida_hexrays.get_ctype_name(item.op)
                s = s.replace(tag+addr, il.COLSTR("<%s>" % ctype_name, il.SCOLOR_AUTOCMT)+tag+addr)
    return s
Beispiel #15
0
    def get_node_label(self, n, highlight_node=False):
        item = self.items[n]
        op = item.op
        insn = item.cinsn
        expr = item.cexpr
        type_name = ida_hexrays.get_ctype_name(op)
        parts = []
        if op == ida_hexrays.cot_ptr:
            parts.append("%s.%d" % (type_name, expr.ptrsize))
        elif op == ida_hexrays.cot_memptr:
            parts.append("%s.%d (m=%d)" % (type_name, expr.ptrsize, expr.m))
        elif op == ida_hexrays.cot_memref:
            parts.append("%s (m=%d)" % (
                type_name,
                expr.m,
            ))
        elif op in [ida_hexrays.cot_obj, ida_hexrays.cot_var]:
            name = self.get_expr_name(expr)
            parts.append("%s.%d %s" % (type_name, expr.refwidth, name))
        elif op in [
                ida_hexrays.cot_num, ida_hexrays.cot_helper,
                ida_hexrays.cot_str
        ]:
            name = self.get_expr_name(expr)
            parts.append("%s %s" % (
                type_name,
                name,
            ))
        elif op == ida_hexrays.cit_goto:
            parts.append("%s LABEL_%d" % (type_name, insn.cgoto.label_num))
        elif op == ida_hexrays.cit_asm:
            parts.append("%s <asm statements; unsupported ATM>" % type_name)
            # parts.append(" %a.%d" % ())
        else:
            parts.append("%s" % type_name)

        parts.append("ea: %08X" % item.ea)
        if item.is_expr() and not expr.type.empty():
            tstr = expr.type._print()
            parts.append(tstr if tstr else "?")
        scolor = ida_lines.SCOLOR_EXTRA if highlight_node else ida_lines.SCOLOR_DEFAULT
        parts = [ida_lines.COLSTR("%s" % part, scolor) for part in parts]
        return "\n".join(parts)
Beispiel #16
0
 def func_printed_ev(self, cfunc):
     pc = cfunc.get_pseudocode()
     for sl in pc:
         for token in FUNC_NAMES:
             sl.line = sl.line.replace(token, ida_lines.COLSTR(token, ida_lines.SCOLOR_ERROR))
     return 0
Beispiel #17
0
    def _get_node_label(self, n, highlight_node=False):
        item = self.items[n]
        op = item.op
        insn = item.cinsn
        expr = item.cexpr
        type_name = ida_hexrays.get_ctype_name(op)
        parts = []

        if op == ida_hexrays.cot_ptr:
            parts.append("%s.%d" % (type_name, expr.ptrsize))
        elif op == ida_hexrays.cot_memptr:
            parts.append("%s.%d (m=%d)" % (type_name, expr.ptrsize, expr.m))
        elif op == ida_hexrays.cot_memref:
            parts.append("%s (m=%d)" % (
                type_name,
                expr.m,
            ))
        elif op in [ida_hexrays.cot_obj, ida_hexrays.cot_var]:
            name = self._get_expr_name(expr)
            parts.append("%s.%d %s" % (type_name, expr.refwidth, name))
        elif op in [
                ida_hexrays.cot_num, ida_hexrays.cot_helper,
                ida_hexrays.cot_str
        ]:
            name = self._get_expr_name(expr)
            parts.append("%s %s" % (
                type_name,
                name,
            ))
        elif op == ida_hexrays.cit_goto:
            parts.append("%s LABEL_%d" % (type_name, insn.cgoto.label_num))
        elif op == ida_hexrays.cit_asm:
            parts.append("%s <asm statements; unsupported ATM>" % type_name)
            # parts.append(" %a.%d" % ())
        else:
            parts.append("%s" % type_name)

        parts.append("ea: %x" % item.ea)
        # add type
        if item.is_expr() and not expr.type.empty():
            tstr = expr.type._print()
            parts.append(tstr if tstr else "?")

        if self.debug:
            parts.append("-" * 20)
            parts.append("obj_id: %x" % item.obj_id)
            if op is ida_hexrays.cot_var:
                parts.append("idx: %d" % expr.v.idx)
                lv = expr.v.getv()
                if lv:
                    parts.append("width: %d" % lv.width)
                    parts.append("defblk: %d" % lv.defblk)
                    parts.append("cmt: %s" % lv.cmt)
                    parts.append("arg_var: %r" % lv.is_arg_var)
                    parts.append("thisarg: %r" % lv.is_thisarg())
                    parts.append("result_var: %r" % lv.is_result_var)
                    parts.append("used_byref: %r" % lv.is_used_byref())
                    parts.append("mapdst_var: %r" % lv.is_mapdst_var)
                    parts.append("overlapped_var: %r" % lv.is_overlapped_var)
                    parts.append("floating_var: %r" % lv.is_floating_var)
                    parts.append("typed: %r" % lv.typed)
                    if self.debug > 1:
                        parts.append("divisor: %d" % lv.divisor)
                        parts.append("automapped: %r" % lv.is_automapped())
                        parts.append("fake_var: %r" % lv.is_fake_var)
                        parts.append("spoiled_var: %r" % lv.is_spoiled_var)
                        parts.append("noptr_var: %r" % lv.is_noptr_var())
                        parts.append("forced_var: %r" % lv.is_forced_var())
                        parts.append("dummy_arg: %r" % lv.is_dummy_arg())
                        parts.append("used: %r" % lv.used)
                        parts.append("user_info: %r" % lv.has_user_info)
                        parts.append("user_name: %r" % lv.has_user_name)
                        parts.append("user_type: %r" % lv.has_user_type)
                        parts.append("regname: %r" % lv.has_regname())
                        parts.append("mreg_done: %r" % lv.mreg_done)
                        parts.append("nice_name: %r" % lv.has_nice_name)
                        parts.append("unknown_width: %r" % lv.is_unknown_width)
                        parts.append("in_asm: %r" % lv.in_asm())
                        parts.append("notarg: %r" % lv.is_notarg())
                        parts.append("decl_unused: %r" % lv.is_decl_unused())
            elif op is ida_hexrays.cot_obj:
                parts.append("obj_ea: %x" % expr.obj_ea)

        # disable hightlight color for now -> requires labels to be re-generated/graph to be redrawn
        #scolor = self.COLOR_TEXT_HIGHLIGHT if highlight_node else self.COLOR_TEXT_DEFAULT
        scolor = self.COLOR_TEXT_DEFAULT
        parts = [ida_lines.COLSTR("%s" % part, scolor) for part in parts]
        return "\n".join(parts)
Beispiel #18
0
 def process_text(self, vu):
     pc = vu.cfunc.get_pseudocode()
     for sl in pc:
         for token in FUNC_NAMES:
             sl.line = sl.line.replace(token, ida_lines.COLSTR(token, ida_lines.SCOLOR_ERROR))
     return 0
Beispiel #19
0
 def as_comment(self, s):
     return ida_lines.COLSTR(s, ida_lines.SCOLOR_RPTCMT)
Beispiel #20
0
 def as_directive(self, s):
     return ida_lines.COLSTR(s, ida_lines.SCOLOR_KEYWORD)
Beispiel #21
0
 def as_num(self, s):
     return ida_lines.COLSTR(s, ida_lines.SCOLOR_NUMBER)
Beispiel #22
0
 def as_string(self, s):
     return ida_lines.COLSTR(s, ida_lines.SCOLOR_STRING)