示例#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)
    def create_containing_record(self, expression, index, offset):
        negative_lvar = self.negative_lvars[index]
        logger.debug("Creating CONTAINING_RECORD macro, offset: {}, negative offset: {}, TYPE: {}".format(
            negative_lvar.offset,
            offset,
            negative_lvar.parent_tinfo.dstr()
        ))

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

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

        arg_field = idaapi.carg_t()
        cexpr_helper = idaapi.create_helper(
            True,
            self.pvoid_tinfo,
            negative_lvar.member_name
        )
        arg_field.assign(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.thisown = False

        parent = reversed(self.parents).next().cexpr

        diff = negative_lvar.offset + offset
        if diff:
            number = idaapi.make_num(diff)
            number.thisown = False
            new_cexpr_add = Helper.my_cexpr_t(idaapi.cot_add, x=new_cexpr_call, y=number)
            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 = Helper.my_cexpr_t(idaapi.cot_cast, x=new_cexpr_add)
                new_cexpr_cast.thisown = False
                new_cexpr_cast.type = tmp_tinfo
                expression.assign(new_cexpr_cast)
            else:
                expression.assign(new_cexpr_add)
        else:
            if parent.op == idaapi.cot_ptr:
                tmp_tinfo = idaapi.tinfo_t()
                tmp_tinfo.create_ptr(parent.type)
                new_cexpr_cast = Helper.my_cexpr_t(idaapi.cot_cast, x=new_cexpr_call)
                new_cexpr_cast.thisown = False
                new_cexpr_cast.type = tmp_tinfo
                expression.assign(new_cexpr_cast)
            else:
                expression.assign(new_cexpr_call)
    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