コード例 #1
0
    def create_containing_record(self, expression, index, offset):

        negative_lvar = self.negative_lvars[index]
        # print "[DEBUG] Rebuilding negative offset", negative_lvar.offset, offset, negative_lvar.parent_tinfo.dstr()
        diff = negative_lvar.offset + offset

        arg_address = idaapi.carg_t()
        if expression.op == idaapi.cot_var:
            arg_address.consume_cexpr(expression)
        else:
            arg_address.consume_cexpr(expression.x)

        arg_type = idaapi.carg_t()
        cexpr_helper = idaapi.create_helper(True, self.pvoid_tinfo,
                                            negative_lvar.parent_tinfo.dstr())
        arg_type.consume_cexpr(cexpr_helper)

        arg_field = idaapi.carg_t()
        cexpr_helper = idaapi.create_helper(True, self.pvoid_tinfo,
                                            negative_lvar.member_name)
        arg_field.consume_cexpr(cexpr_helper)
        return_tinfo = idaapi.tinfo_t(negative_lvar.parent_tinfo)
        return_tinfo.create_ptr(return_tinfo)
        new_cexpr_call = idaapi.call_helper(return_tinfo, None,
                                            "CONTAINING_RECORD")
        new_cexpr_call.a.push_back(arg_address)
        new_cexpr_call.a.push_back(arg_type)
        new_cexpr_call.a.push_back(arg_field)
        # new_cexpr_call.ea = expression.ea
        # new_cexpr_call.x.ea = expression.ea

        parent = reversed(self.parents).next().cexpr
        if diff:
            number = idaapi.make_num(diff)
            new_cexpr_add = idaapi.cexpr_t(idaapi.cot_add, new_cexpr_call,
                                           number)
            new_cexpr_add.thisown = False
            new_cexpr_add.type = return_tinfo
            if parent.op == idaapi.cot_ptr:
                tmp_tinfo = idaapi.tinfo_t()
                tmp_tinfo.create_ptr(parent.type)
                new_cexpr_cast = idaapi.cexpr_t(idaapi.cot_cast, new_cexpr_add)
                new_cexpr_cast.thisown = False
                new_cexpr_cast.type = tmp_tinfo
                expression.replace_by(new_cexpr_cast)
            else:
                expression.replace_by(new_cexpr_add)
        else:
            if parent.op == idaapi.cot_ptr:
                tmp_tinfo = idaapi.tinfo_t()
                tmp_tinfo.create_ptr(parent.type)
                new_cexpr_cast = idaapi.cexpr_t(idaapi.cot_cast,
                                                new_cexpr_call)
                new_cexpr_cast.thisown = False
                new_cexpr_cast.type = tmp_tinfo
                expression.replace_by(new_cexpr_cast)
            else:
                expression.replace_by(new_cexpr_call)
コード例 #2
0
    def visit_insn(self, instruction):
        if instruction.op == idaapi.cit_block:
            while True:
                cblock = instruction.cblock
                size = cblock.size()
                if size >= 2:
                    # Find block that has "If" and "return" as last 2 statements
                    if cblock.back().op == idaapi.cit_return and \
                                    cblock.at(size - 2).op == idaapi.cit_if and not cblock.at(size - 2).cif.ielse:

                        cit_then = cblock.at(size - 2).cif.ithen

                        # Skip if only one (not "if") statement in "then" branch
                        if cit_then.cblock.size(
                        ) == 1 and cit_then.cblock.front().op != idaapi.cit_if:
                            return 0

                        # Replacing condition to opposite
                        cit_if_condition = cblock.at(size - 2).cif.expr
                        if cit_if_condition.op == idaapi.cot_lnot:
                            # Ida has following bug:
                            # when return type of call cexpr_t is not signed int, function idaapi.lnot leads to crash
                            new_if_condition = idaapi.cexpr_t(
                                cit_if_condition.x)
                        else:
                            new_if_condition = idaapi.cexpr_t(
                                idaapi.lnot(cit_if_condition))
                        new_if_condition.thisown = False
                        cblock.at(size - 2).cif.expr = new_if_condition
                        del cit_if_condition

                        # Take return from list of statements and later put it back
                        cit_return = idaapi.cinsn_t(instruction.cblock.back())
                        cit_return.thisown = False
                        instruction.cblock.pop_back()

                        # Fill main block with statements from "Then" branch
                        while cit_then.cblock:
                            instruction.cblock.push_back(
                                cit_then.cblock.front())
                            cit_then.cblock.pop_front()

                        # Put back main return if there's no another return or "GOTO" already
                        if instruction.cblock.back().op not in (
                                idaapi.cit_return, idaapi.cit_goto):
                            new_return = idaapi.cinsn_t(cit_return)
                            new_return.thisown = False
                            instruction.cblock.push_back(new_return)

                        # Put return into "Then" branch
                        cit_then.cblock.push_back(cit_return)
                        continue
                break
        return 0
コード例 #3
0
def inverse_if(cif):
    idaapi.qswap(cif.ithen, cif.ielse)
    cit_if_condition = cif.expr

    if cit_if_condition.op == idaapi.cot_lnot:
        new_if_condition = idaapi.cexpr_t(cit_if_condition.x)
    else:
        new_if_condition = idaapi.cexpr_t(idaapi.lnot(cit_if_condition))

    new_if_condition.thisown = False
    cif.expr = new_if_condition
    del cit_if_condition
コード例 #4
0
    def visit_expr(self, expr):
        """
        Search for simple assignents to stack vars
        """
        if expr.op != ida_hexrays.cot_asg:
            return 0

        _x = expr.x
        _y = expr.y

        if _x.op == ida_hexrays.cot_var and _y.op == ida_hexrays.cot_num:
            # Something like "v1 = 65"
            num_value = _y.n.value(_y.type)

            # Bail out soon
            if num_value < 1 or num_value > 255:
                return 0

            if chr(num_value) not in string.printable:
                return 0

            # Create a new expr object to replace _y
            # This will be of type cot_str
            z = idaapi.cexpr_t()

            # In order to modify an existing cexpr
            # you have to swap it with a newly created one
            z.swap(_y)
            _y.op = ida_hexrays.cot_str
            _y.string = chr(num_value)

        return 0
コード例 #5
0
def inverse_if_condition(cif):
    # cexpr_t has become broken but fortunately still exist `assing` method which copies one expr into another
    cit_if_condition = cif.expr
    tmp_cexpr = idaapi.cexpr_t()
    tmp_cexpr.assign(cit_if_condition)
    new_if_condition = idaapi.lnot(tmp_cexpr)
    cif.expr.swap(new_if_condition)
    del cit_if_condition
コード例 #6
0
        def leave_expr(self, e):
            if e.op == idaapi.cot_call:
                self.reset()
            elif self.func is not None and e.is_child_of(self.func):
                if (self.viable is False or
                    self.cast_type is None or
                    self.func is None or
                    self.type is None):
                    self.reset()
                    return 0
                else:
                    self.type.remove_ptr_or_array()

                    # Currently we do this so that base classes have a
                    # cast_type that is equal to this_type, but maybe
                    # it causes problems sometimes?
                    self.cast_type.remove_ptr_or_array()

                    this_type = get_type_by_name(self.type.dstr())

                    cast_type = get_type_by_name(self.cast_type.dstr())

                    if cast_type != this_type:
                        table = this_type.table_for_cast(cast_type)
                    else:
                        table = this_type.tablegroup.primary_table()

                    if self.index is None:
                        self.index = 0

                    func = table.functions[self.index]

                    # Create a new cot_obj expression and fill it with
                    # the ea of the function. Also use the type of the
                    # function.
                    obj = idaapi.cexpr_t()
                    obj.op = idaapi.cot_obj
                    t = tinfo_for_ea(func)
                    if t is not None:
                        t.create_ptr(t)
                        obj.type = t

                        #FIXME: this is a quick fix to correct the number of
                        # args to agree with the function type. Type info is
                        # still not propagated correctly. This might be fixed
                        # by running the visitor at an earlier maturity, but
                        # it is more difficult to identify virtual calls at
                        # earlier stages.
                        self.func.a.resize(t.get_nargs())
                    else:
                        obj.type = self.func.x.type
                    set_obj_ea(obj, func)

                    # Replace the existing func object (the virtual function
                    # pointer) with the new cot_obj
                    obj.swap(self.func.x)
                    self.reset()
            return 0
コード例 #7
0
def my_cexpr_t(*args, **kwargs):
    """ Replacement of bugged cexpr_t() function """

    if len(args) == 0:
        return idaapi.cexpr_t()

    if len(args) != 1:
        raise NotImplementedError

    cexpr = idaapi.cexpr_t()
    cexpr.thisown = False
    if type(args[0]) == idaapi.cexpr_t:
        cexpr.assign(args[0])
    else:
        op = args[0]
        cexpr._set_op(op)

        if 'x' in kwargs:
            cexpr._set_x(kwargs['x'])
        if 'y' in kwargs:
            cexpr._set_y(kwargs['y'])
        if 'z' in kwargs:
            cexpr._set_z(kwargs['z'])
    return cexpr
コード例 #8
0
    def invert_if(self, cfunc, insn):

        if insn.opname != 'if':
            return False

        cif = insn.details

        if not cif.ithen or not cif.ielse:
            return False

        idaapi.qswap(cif.ithen, cif.ielse)
        cond = idaapi.cexpr_t(cif.expr)
        notcond = idaapi.lnot(cond)

        cif.expr.swap(notcond)

        return True
コード例 #9
0
    def invert_if(self, cfunc, insn):

        if insn.opname != 'if':
            return False

        cif = insn.details

        if not cif.ithen or not cif.ielse:
            return False

        idaapi.qswap(cif.ithen, cif.ielse)
        cond = idaapi.cexpr_t(cif.expr)
        notcond = idaapi.lnot(cond)
        cond.thisown = 0  # the new wrapper 'notcond' now holds the reference to the cexpr_t

        cif.expr.swap(notcond)

        return True
コード例 #10
0
ファイル: vds3.py プロジェクト: Hehouhua/idapython
    def invert_if(self, cfunc, insn):

        if insn.opname != 'if':
            return False

        cif = insn.details

        if not cif.ithen or not cif.ielse:
            return False

        idaapi.qswap(cif.ithen, cif.ielse)
        cond = idaapi.cexpr_t(cif.expr)
        notcond = idaapi.lnot(cond)
        cond.thisown = 0 # the new wrapper 'notcond' now holds the reference to the cexpr_t

        cif.expr.swap(notcond)

        return True
コード例 #11
0
ファイル: vds3.py プロジェクト: xcode2010/XMicro
    def invert_if(self, cfunc, insn):

        if insn.opname != 'if':
            return False

        cif = insn.details

        if not cif.ithen or not cif.ielse:
            return False

        idaapi.qswap(cif.ithen, cif.ielse)
        # Make a copy of 'cif.expr': 'lnot' might destroy its toplevel
        # cexpr_t and return a pointer to its direct child (but we'll want to
        # 'swap' it later, the 'cif.expr' cexpr_t object must remain valid.)
        cond = idaapi.cexpr_t(cif.expr)
        notcond = idaapi.lnot(cond)

        cif.expr.swap(notcond)

        return True
コード例 #12
0
ファイル: hnight7.py プロジェクト: zhuotong/idastuff
 def visit_expr(self, expr):
     try:
         if expr.op == idaapi.cot_call and expr.x.op == idaapi.cot_helper:
             #print idaapi.tag_remove(expr.x.print1(None))
             if expr.x.helper == "ARM64_SYSREG" and len(expr.a) == 5: # and idaapi.getseg(expr.ea).use64():
                 reg = 0
                 for j, i in enumerate(expr.a):
                     if i.type != inttype:
                         break
                     #print i.n.value(i.type)
                     reg = reg | (i.numval() << shifts[j])
                 else:
                     if reg in regs64.keys():
                         n = idaapi.cexpr_t()
                         n.op = idaapi.cot_helper
                         n.helper = regs64[reg]
                         n.exflags = idaapi.EXFL_ALONE
                         expr.cleanup()
                         expr.replace_by(n)
                         #print "ok"
             elif expr.x.helper == "__mrc" and len(expr.a) == 5: # and not idaapi.getseg(expr.ea).use64():
                 reg = 0
                 for j, i in enumerate(expr.a):
                     if i.type != inttype:
                         break
                     reg = reg | (i.numval() << shifts[j])
                 else:
                     if reg in regs32.keys():
                         n = idaapi.cexpr_t()
                         n.op = idaapi.cot_helper
                         n.helper = regs32[reg]
                         n.exflags = idaapi.EXFL_ALONE
                         #expr.x.helper = "_ReadSystemReg"
                         while len(expr.a) > 1:
                             expr.a.pop_back()
                         expr.a[0].cleanup()
                         expr.a[0].replace_by(n)
             elif expr.x.helper == "__mcr" and len(expr.a) == 6: # and not idaapi.getseg(expr.ea).use64():
                 reg = 0
                 for j, i in enumerate(expr.a):
                     if shiftz[j] < 0:
                         continue
                     if i.type != inttype:
                         break
                     reg = reg | (i.numval() << shiftz[j])
                 else:
                     if reg in regs32.keys():
                         n = idaapi.cexpr_t()
                         n.op = idaapi.cot_helper
                         n.helper = regs32[reg]
                         n.exflags = idaapi.EXFL_ALONE
                         #expr.x.helper = "_WriteSystemReg"
                         expr.a[1] = expr.a[2]
                         while len(expr.a) > 2:
                             expr.a.pop_back()
                         expr.a[0].cleanup()
                         expr.a[0].replace_by(n)
                         print "ok"
     except:
         traceback.print_exc()
     return 0
コード例 #13
0
    def visit_expr(self, expression):
        global Storage
        self.nodes.append(expression)
        if expression.op == idaapi.cot_obj:
            for start, end, off, func in Storage:
                if expression.obj_ea >= start and expression.obj_ea <= end:
                    if func and self.cfunc.entry_ea != func:
                        return 0

                    target_ea = expression.obj_ea + off
                    head_ea = idaapi.get_item_head(target_ea)
                    if head_ea != target_ea and idaapi.isStruct(idaapi.getFlags(head_ea)):
                        ref_parent = self.cfunc.body.find_parent_of(expression)
                        if ref_parent.op == idaapi.cot_ref:
                            parent = self.cfunc.body.find_parent_of(ref_parent)
                            if parent.op == idaapi.cot_add:
                                v = target_ea - head_ea
                                num_node = idaapi.make_num(v)
                                num_node.thisown = False
                                num_node.n.thisown = False
                                parent = parent.cexpr
                                # parent.thisown = False
                                tif = idaapi.tinfo_t()
                                if not idaapi.get_tinfo(tif, head_ea):
                                    idaapi.guess_tinfo(tif, head_ea)
                                if parent.x == ref_parent.cexpr:
                                    # ref_parent.thisown = False
                                    # ref_parent.cexpr.thisown = False
                                    ref_parent = parent.x
                                    # expression = ref_parent.x
                                    ref_new = idaapi.cexpr_t(ref_parent)
                                    ref_new.thisown = False
                                    # expression.thisown = False
                                    # expression_new.type.thisown = False
                                    # tif.thisown = False
                                    element_tif = tif.get_ptrarr_object()
                                    element_tif.create_ptr(element_tif)
                                    ref_new.type = element_tif
                                    ref_new.x.type = tif
                                    ref_new.x.obj_ea = head_ea
                                    expr_add = idaapi.cexpr_t(idaapi.cot_add, ref_new, num_node)
                                    expr_add.thisown = False
                                    # expr_add.type = element_tif
                                    ref_parent.cexpr.assign(expr_add)
                                    # parent.x.thisown = False
                                    # parent.x.swap(expr_add)
                                    # ref_parent1 = idaapi.cexpr_t(ref_parent.cexpr)
                                    # parent.x.swap(ref_parent1)
                                elif parent.y == ref_parent.cexpr:
                                    ref_parent.thisown = False
                                    ref_parent.cexpr.thisown = False
                                    ref_parent = idaapi.cexpr_t(ref_parent.cexpr)
                                    expression.thisown = False
                                    expression = idaapi.cexpr_t(expression)
                                    ref_parent.x.replace_by(expression)
                                    expr_add = idaapi.cexpr_t(idaapi.cot_add, ref_parent, num_node)
                                    parent.y.thisown = False
                                    parent.y.replace_by(expr_add)
                                else:
                                    print "F**K!"


                                rc = self.recalc_parent_types()
                        # parent = self.nodes[-2]
                        # parent = self.nodes[-3]
                        # parent = self.nodes[-4]
        return 0