Exemple #1
0
def ins(ir, instr, a, b, c, d):
    e = []
    pos = int(c)
    l = int(d)

    my_slices = []
    if pos != 0:
        my_slices.append(a[:pos])
    if l != 0:
        my_slices.append(b[:l])
    if pos + l != 32:
        my_slices.append(a[pos + l:])
    r = m2_expr.ExprCompose(*my_slices)
    e.append(m2_expr.ExprAssign(a, r))
    return e, []
Exemple #2
0
    def compose(cls, size=32, depth=1):
        """Return an ExprCompose
        @size: (optional) Operation size
        @depth: (optional) Expression depth
        """
        # First layer
        upper_bound = random.randint(1, size)
        args = [cls._gen(size=upper_bound, depth=depth - 1)]

        # Next layers
        while (upper_bound < size):
            if len(args) == (cls.compose_max_layer - 1):
                # We reach the maximum size
                new_upper_bound = size
            else:
                new_upper_bound = random.randint(upper_bound + 1, size)

            args.append(cls._gen(size=new_upper_bound - upper_bound))
            upper_bound = new_upper_bound
        return m2_expr.ExprCompose(*args)
Exemple #3
0
    def _set(self, dst, src):
        """
        Special cases:
        * if dst is an ExprSlice, expand it to assign the full Expression
        * if dst already known, sources are merged
        """
        if dst.size != src.size:
            raise RuntimeError("sanitycheck: args must have same size! %s" %
                               ([(str(arg), arg.size) for arg in [dst, src]]))

        if isinstance(dst, m2_expr.ExprSlice):
            # Complete the source with missing slice parts
            new_dst = dst.arg
            rest = [(m2_expr.ExprSlice(dst.arg, r[0], r[1]), r[0], r[1])
                    for r in dst.slice_rest()]
            all_a = [(src, dst.start, dst.stop)] + rest
            all_a.sort(key=lambda x: x[1])
            args = [expr for (expr, _, _) in all_a]
            new_src = m2_expr.ExprCompose(*args)
        else:
            new_dst, new_src = dst, src

        if new_dst in self._assigns and isinstance(new_src,
                                                   m2_expr.ExprCompose):
            if not isinstance(self[new_dst], m2_expr.ExprCompose):
                # prev_RAX = 0x1122334455667788
                # input_RAX[0:8] = 0x89
                # final_RAX -> ? (assignment are in parallel)
                raise RuntimeError("Concurrent access on same bit not allowed")

            # Consider slice grouping
            expr_list = [(new_dst, new_src), (new_dst, self[new_dst])]
            # Find collision
            e_colision = reduce(lambda x, y: x.union(y),
                                (self.get_modified_slice(dst, src)
                                 for (dst, src) in expr_list), set())

            # Sort interval collision
            known_intervals = sorted([(x[1], x[2]) for x in e_colision])

            for i, (_, stop) in enumerate(known_intervals[:-1]):
                if stop > known_intervals[i + 1][0]:
                    raise RuntimeError(
                        "Concurrent access on same bit not allowed")

            # Fill with missing data
            missing_i = get_missing_interval(known_intervals, 0, new_dst.size)
            remaining = ((m2_expr.ExprSlice(new_dst, *interval), interval[0],
                          interval[1]) for interval in missing_i)

            # Build the merging expression
            args = list(e_colision.union(remaining))
            args.sort(key=lambda x: x[1])
            starts = [start for (_, start, _) in args]
            assert len(set(starts)) == len(starts)
            args = [expr for (expr, _, _) in args]
            new_src = m2_expr.ExprCompose(*args)

        # Sanity check
        if not isinstance(new_dst, (m2_expr.ExprId, m2_expr.ExprMem)):
            raise TypeError("Destination cannot be a %s" % type(new_dst))

        self._assigns[new_dst] = new_src
Exemple #4
0
def possible_values(expr):
    """Return possible values for expression @expr, associated with their
    condition constraint as a ConstrainedValues instance
    @expr: Expr instance
    """

    consvals = ConstrainedValues()

    # Terminal expression
    if (isinstance(expr, m2_expr.ExprInt) or isinstance(expr, m2_expr.ExprId)
            or isinstance(expr, m2_expr.ExprLoc)):
        consvals.add(ConstrainedValue(frozenset(), expr))
    # Unary expression
    elif isinstance(expr, m2_expr.ExprSlice):
        consvals.update(
            ConstrainedValue(consval.constraints,
                             consval.value[expr.start:expr.stop])
            for consval in possible_values(expr.arg))
    elif isinstance(expr, m2_expr.ExprMem):
        consvals.update(
            ConstrainedValue(consval.constraints,
                             m2_expr.ExprMem(consval.value, expr.size))
            for consval in possible_values(expr.ptr))
    elif isinstance(expr, m2_expr.ExprAssign):
        consvals.update(possible_values(expr.src))
    # Special case: constraint insertion
    elif isinstance(expr, m2_expr.ExprCond):
        src1cond = CondConstraintNotZero(expr.cond)
        src2cond = CondConstraintZero(expr.cond)
        consvals.update(
            ConstrainedValue(consval.constraints.union([src1cond]),
                             consval.value)
            for consval in possible_values(expr.src1))
        consvals.update(
            ConstrainedValue(consval.constraints.union([src2cond]),
                             consval.value)
            for consval in possible_values(expr.src2))
    # N-ary expression
    elif isinstance(expr, m2_expr.ExprOp):
        # For details, see ExprCompose
        consvals_args = [possible_values(arg) for arg in expr.args]
        for consvals_possibility in itertools.product(*consvals_args):
            args_value = [consval.value for consval in consvals_possibility]
            args_constraint = itertools.chain(
                *[consval.constraints for consval in consvals_possibility])
            consvals.add(
                ConstrainedValue(frozenset(args_constraint),
                                 m2_expr.ExprOp(expr.op, *args_value)))
    elif isinstance(expr, m2_expr.ExprCompose):
        # Generate each possibility for sub-argument, associated with the start
        # and stop bit
        consvals_args = [list(possible_values(arg)) for arg in expr.args]
        for consvals_possibility in itertools.product(*consvals_args):
            # Merge constraint of each sub-element
            args_constraint = itertools.chain(
                *[consval.constraints for consval in consvals_possibility])
            # Gen the corresponding constraints / ExprCompose
            args = [consval.value for consval in consvals_possibility]
            consvals.add(
                ConstrainedValue(frozenset(args_constraint),
                                 m2_expr.ExprCompose(*args)))
    else:
        raise RuntimeError("Unsupported type for expr: %s" % type(expr))

    return consvals
Exemple #5
0
    def test_Variables_Identifier(self):
        import miasm.expression.expression as m2_expr
        from miasm.expression.expression_helper import Variables_Identifier

        # Build a complex expression
        cst = m2_expr.ExprInt(0x100, 16)
        eax = m2_expr.ExprId("EAX", 32)
        ebx = m2_expr.ExprId("EBX", 32)
        ax = eax[0:16]
        expr = eax + ebx
        expr = m2_expr.ExprCompose(ax, expr[16:32])
        expr2 = m2_expr.ExprMem((eax + ebx) ^ (eax), size=16)
        expr2 = expr2 | ax | expr2 | cst
        exprf = expr - expr + m2_expr.ExprCompose(expr2, cst)

        # Identify variables
        vi = Variables_Identifier(exprf)

        # Use __str__
        print(vi)

        # Test the result
        new_expr = vi.equation

        ## Force replace in the variable dependency order
        for var_id, var_value in reversed(list(viewitems(vi.vars))):
            new_expr = new_expr.replace_expr({var_id: var_value})
        self.assertEqual(exprf, new_expr)

        # Test prefix
        vi = Variables_Identifier(exprf, var_prefix="prefix_v")

        ## Use __str__
        print(vi)

        ## Test the result
        new_expr = vi.equation
        ### Force replace in the variable dependency order
        for var_id, var_value in reversed(list(viewitems(vi.vars))):
            new_expr = new_expr.replace_expr({var_id: var_value})
        self.assertEqual(exprf, new_expr)

        # Test an identify on an expression already containing identifier
        vi = Variables_Identifier(exprf)
        vi2 = Variables_Identifier(vi.equation)

        ## Test the result
        new_expr = vi2.equation
        ### Force replace in the variable dependency order
        for var_id, var_value in reversed(list(viewitems(vi2.vars))):
            new_expr = new_expr.replace_expr({var_id: var_value})
        self.assertEqual(vi.equation, new_expr)

        ## Corner case: each sub var depends on itself
        mem1 = m2_expr.ExprMem(ebx, size=32)
        mem2 = m2_expr.ExprMem(mem1, size=32)
        cst2 = m2_expr.ExprInt(-1, 32)
        expr_mini = ((eax ^ mem2 ^ cst2) & (mem2 ^ (eax + mem2)))[31:32]

        ## Build
        vi = Variables_Identifier(expr_mini)
        vi2 = Variables_Identifier(vi.equation)

        ## Test the result
        new_expr = vi2.equation
        ### Force replace in the variable dependency order
        for var_id, var_value in reversed(list(viewitems(vi2.vars))):
            new_expr = new_expr.replace_expr({var_id: var_value})
        self.assertEqual(vi.equation, new_expr)
Exemple #6
0
def wsbh(arg1, arg2):
    arg1 = m2_expr.ExprCompose(arg2[8:16], arg2[0:8], arg2[24:32], arg2[16:24])
Exemple #7
0
def lui(arg1, arg2):
    """The immediate value @arg2 is shifted left 16 bits and stored in the
    register @arg1. The lower 16 bits are zeroes."""
    arg1 = m2_expr.ExprCompose(i16(0), arg2[:16])