Esempio n. 1
0
    def patch_div(ir, instr, src1):

        # print '[*] Calling patched div.'

        e = []
        size = src1.size
        if size == 8:
            src2 = mRAX[instr.mode][:16]
        elif size in [16, 32, 64]:
            s1, s2 = mRDX[size], mRAX[size]
            src2 = m2_expr.ExprCompose(s2, s1)
        else:
            raise ValueError('div arg not impl', src1)

        c_d = m2_expr.ExprOp('udiv', src2, src1.zeroExtend(src2.size))
        c_r = m2_expr.ExprOp('umod', src2, src1.zeroExtend(src2.size))

        # if 8 bit div, only ax is affected
        if size == 8:
            e.append(
                m2_expr.ExprAff(src2, m2_expr.ExprCompose(c_d[:8], c_r[:8])))
        else:
            e.append(m2_expr.ExprAff(s1, c_r[:size]))
            e.append(m2_expr.ExprAff(s2, c_d[:size]))

        return e, []
Esempio n. 2
0
    def test_Variables_Identifier(self):
        import miasm2.expression.expression as m2_expr
        from miasm2.expression.expression_helper import Variables_Identifier

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

        # 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(vi.vars.items()):
            new_expr = new_expr.replace_expr({var_id: var_value})
        self.assertEqual(exprf, new_expr)
Esempio n. 3
0
File: ir.py Progetto: zhencang/miasm
    def _set(self, dst, src):
        """
        Special cases:
        * if dst is an ExprSlice, expand it to affect 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("Concurent 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(
                        "Concurent 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)

        self._assigns[new_dst] = new_src
Esempio n. 4
0
    def patch_rotate_with_carry_tpl(ir, instr, op, dst, src):
        # Compute results
        shifter = get_shift(dst, src).zeroExtend(dst.size + 1)
        result = m2_expr.ExprOp(op, m2_expr.ExprCompose(dst, cf), shifter)

        new_cf = result[dst.size:dst.size + 1]
        new_dst = result[:dst.size]

        result_trunc = result[:dst.size]
        if op == '<<<':
            of_value = result_trunc.msb() ^ new_cf
        else:
            of_value = (dst ^ result_trunc).msb()
        # OF is defined only for @b == 1
        new_of = m2_expr.ExprCond(src - m2_expr.ExprInt(1, size=src.size),
                                  m2_expr.ExprInt(0, size=of.size), of_value)

        # Build basic blocks
        e_do = [
            m2_expr.ExprAff(cf, new_cf),
            m2_expr.ExprAff(of, new_of),
            m2_expr.ExprAff(dst, new_dst)
        ]

        return (e_do, [])
Esempio n. 5
0
def lui(ir, instr, a, b):
    """The immediate value @b is shifted left 16 bits and stored in the register
    @a. The lower 16 bits are zeroes."""
    e = []
    e.append(m2_expr.ExprAff(a,
                             m2_expr.ExprCompose([(m2_expr.ExprInt16(0), 0, 16),
                                                  (b[:16], 16, 32)])))
    return e, []
Esempio n. 6
0
def ins(ir, instr, a, b, c, d):
    e = []
    pos = int(c)
    l = int(d)
    r = None
    if pos != 0:
        if l != 0:
            if pos + l != 32:
                r = m2_expr.ExprCompose(a[:pos], b[:l], a[pos + l:])
            else:
                r = m2_expr.ExprCompose(a[:pos], b[:l])
        else:
            if pos + l != 32:
                r = m2_expr.ExprCompose(a[:pos], a[pos + l:])
            else:
                r = m2_expr.ExprCompose(a[:pos])
    else:
        if l != 0:
            if pos + l != 32:
                r = m2_expr.ExprCompose(b[:l], a[pos + l:])
            else:
                r = m2_expr.ExprCompose(b[:l])
        else:
            if pos + l != 32:
                r = m2_expr.ExprCompose(a[pos + l:])
    if r is not None:
        e.append(m2_expr.ExprAff(a, r))
    return e, []
Esempio n. 7
0
    def merge_multi_affect(self, affect_list):
        """
        If multiple affection to a same ExprId are present in @affect_list,
        merge them (in place).
        For instance, XCGH AH, AL semantic is
        [
            RAX = {RAX[0:8],0,8, RAX[0:8],8,16, RAX[16:64],16,64}
            RAX = {RAX[8:16],0,8, RAX[8:64],8,64}
        ]
        This function will update @affect_list to replace previous ExprAff by
        [
            RAX = {RAX[8:16],0,8, RAX[0:8],8,16, RAX[16:64],16,64}
        ]
        """

        # Extract side effect
        effect = {}
        for expr in affect_list:
            effect[expr.dst] = effect.get(expr.dst, []) + [expr]

        # Find candidates
        for dst, expr_list in effect.items():
            if len(expr_list) <= 1:
                continue

            # Only treat ExprCompose list
            if any(map(lambda e: not(isinstance(e.src, m2_expr.ExprCompose)),
                       expr_list)):
                continue

            # Find collision
            e_colision = reduce(lambda x, y: x.union(y),
                                (e.get_modified_slice() for e in expr_list),
                                set())
            # Sort interval collision
            known_intervals = sorted([(x[1], x[2]) for x in e_colision])

            # Fill with missing data
            missing_i = get_missing_interval(known_intervals, 0, dst.size)

            remaining = ((m2_expr.ExprSlice(dst, *interval),
                          interval[0],
                          interval[1])
                         for interval in missing_i)

            # Build the merging expression
            slices = sorted(e_colision.union(remaining), key=lambda x: x[1])
            final_dst = m2_expr.ExprCompose(slices)

            # Remove unused expression
            for expr in expr_list:
                affect_list.remove(expr)

            # Add the merged one
            affect_list.append(m2_expr.ExprAff(dst, final_dst))
Esempio n. 8
0
    def apply_expr_on_state_visit_cache(self, expr, state, cache, level=0):
        """
        Deep First evaluate nodes:
            1. evaluate node's sons
            2. simplify
        """

        expr = self.expr_simp(expr)

        #print '\t'*level, "Eval:", expr
        if expr in cache:
            ret = cache[expr]
            #print "In cache!", ret
        elif expr.is_int():
            return expr
        elif expr.is_id():
            if isinstance(expr.name, asmblock.AsmLabel) and expr.name.offset is not None:
                ret = m2_expr.ExprInt(expr.name.offset, expr.size)
            else:
                ret = state.get(expr, expr)
        elif expr.is_mem():
            ptr = self.apply_expr_on_state_visit_cache(expr.arg, state, cache, level+1)
            ret = m2_expr.ExprMem(ptr, expr.size)
            ret = self.get_mem_state(ret)
            assert expr.size == ret.size
        elif expr.is_cond():
            cond = self.apply_expr_on_state_visit_cache(expr.cond, state, cache, level+1)
            src1 = self.apply_expr_on_state_visit_cache(expr.src1, state, cache, level+1)
            src2 = self.apply_expr_on_state_visit_cache(expr.src2, state, cache, level+1)
            ret = m2_expr.ExprCond(cond, src1, src2)
        elif expr.is_slice():
            arg = self.apply_expr_on_state_visit_cache(expr.arg, state, cache, level+1)
            ret = m2_expr.ExprSlice(arg, expr.start, expr.stop)
        elif expr.is_op():
            args = []
            for oarg in expr.args:
                arg = self.apply_expr_on_state_visit_cache(oarg, state, cache, level+1)
                assert oarg.size == arg.size
                args.append(arg)
            ret = m2_expr.ExprOp(expr.op, *args)
        elif expr.is_compose():
            args = []
            for arg in expr.args:
                args.append(self.apply_expr_on_state_visit_cache(arg, state, cache, level+1))
            ret = m2_expr.ExprCompose(*args)
        else:
            raise TypeError("Unknown expr type")
        #print '\t'*level, "Result", ret
        ret = self.expr_simp(ret)
        #print '\t'*level, "Result simpl", ret

        assert expr.size == ret.size
        cache[expr] = ret
        return ret
Esempio n. 9
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], 0, pos))
    if l != 0:
        my_slices.append((b[:l], pos, pos + l))
    if pos + l != 32:
        my_slices.append((a[pos + l:], pos + l, 32))
    r = m2_expr.ExprCompose(my_slices)
    e.append(m2_expr.ExprAff(a, r))
    return e, []
Esempio n. 10
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)
Esempio n. 11
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), 0, upper_bound)]

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

            args.append((cls._gen(size=upper_bound - args[-1][-1]),
                         args[-1][-1], upper_bound))

        return m2_expr.ExprCompose(args)
Esempio n. 12
0
    def get_mem_state(self, expr):
        """
        Evaluate the @expr memory in the current state using @cache
        @expr: the memory key
        """
        ptr, size = expr.arg, expr.size
        ret = self.find_mem_by_addr(ptr)
        if not ret:
            overlaps = self.get_mem_overlapping(expr)
            if not overlaps:
                if self.func_read and ptr.is_int():
                    expr = self.func_read(expr)
                return expr

            out = []
            off_base = 0
            for off, mem in overlaps:
                if off >= 0:
                    new_size = min(size - off * 8, mem.size)
                    tmp = self.expr_simp(self.symbols[mem][0:new_size])
                    out.append((tmp, off_base, off_base + new_size))
                    off_base += new_size
                else:
                    new_size = min(size - off * 8, mem.size)
                    tmp = self.expr_simp(self.symbols[mem][-off * 8:new_size])
                    new_off_base = off_base + new_size + off * 8
                    out.append((tmp, off_base, new_off_base))
                    off_base = new_off_base

            missing_slice = self.rest_slice(out, 0, size)
            for slice_start, slice_stop in missing_slice:
                ptr = self.expr_simp(ptr + m2_expr.ExprInt(slice_start / 8, ptr.size))
                mem = m2_expr.ExprMem(ptr, slice_stop - slice_start)
                if self.func_read and ptr.is_int():
                    mem = self.func_read(mem)
                out.append((mem, slice_start, slice_stop))
            out.sort(key=lambda x: x[1])
            args = [expr for (expr, _, _) in out]
            ret = self.expr_simp(m2_expr.ExprCompose(*args)[:size])
            return ret

        # bigger lookup
        if size > ret.size:
            rest = size
            out = []
            while rest:
                mem = self.find_mem_by_addr(ptr)
                if mem is None:
                    mem = m2_expr.ExprMem(ptr, 8)
                    if self.func_read and ptr.is_int():
                        value = self.func_read(mem)
                    else:
                        value = mem
                elif rest >= mem.size:
                    value = self.symbols[mem]
                else:
                    value = self.symbols[mem][:rest]
                out.append(value)
                rest -= value.size
                ptr = self.expr_simp(ptr + m2_expr.ExprInt(mem.size / 8, ptr.size))
            ret = self.expr_simp(m2_expr.ExprCompose(*out))
            return ret
        # part lookup
        ret = self.expr_simp(self.symbols[ret][:size])
        return ret
Esempio n. 13
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)):
        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.arg))
    elif isinstance(expr, m2_expr.ExprAff):
        consvals.update(possible_values(expr.src))
    # Special case: constraint insertion
    elif isinstance(expr, m2_expr.ExprCond):
        to_ret = set()
        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 = [map(lambda x: x, 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
Esempio n. 14
0
    def callback(self, jitter):

        # Check previous state
        is_symbolic = lambda expr: (isinstance(expr, m2_expr.ExprMem) and
                                    not isinstance(expr.arg, m2_expr.ExprInt))

        # When it is possible, consider only elements modified in the last run
        # -> speed up to avoid browsing the whole memory
        to_consider = self.symb.modified_exprs

        for symbol in to_consider:
            # Do not consider PC
            if symbol == self.ira.pc:
                continue

            # Write to @NN[... argX ...]
            if is_symbolic(symbol):
                self.memories_write.add(symbol)

            # Read from ... @NN[... argX ...] ...
            symb_value = self.symb.eval_expr(symbol)
            to_replace = {}
            for expr in m2_expr.ExprAff(symbol,
                                        symb_value).get_r(mem_read=True):
                if is_symbolic(expr):
                    if isinstance(expr, m2_expr.ExprMem):
                        # Consider each byte individually
                        # Case: @32[X] with only @8[X+1] to replace
                        addr_expr = expr.arg
                        new_expr = []
                        consider = False
                        for offset in xrange(expr.size / 8):
                            sub_expr = m2_expr.ExprMem(
                                self.symb.expr_simp(
                                    addr_expr + m2_expr.ExprInt(
                                        offset, size=addr_expr.size)), 8)
                            if not self.is_pointer(sub_expr):
                                # Not a PTR, we have to replace with the real value
                                original_sub_expr = sub_expr.replace_expr(
                                    self.init_values)
                                new_expr.append(
                                    self.symb.eval_expr(original_sub_expr))
                                consider = True
                            else:
                                new_expr.append(sub_expr)

                        # Rebuild the corresponding expression
                        if consider:
                            assert len(new_expr) == expr.size / 8
                            to_replace[expr] = m2_expr.ExprCompose(*new_expr)

                    if expr not in self.memories_write:
                        # Do not consider memory already written during the run
                        self.memories_read.add(expr)

            # Replace with real value for non-pointer symbols
            if to_replace:
                symb_value = self.symb.expr_simp(
                    symb_value.replace_expr(to_replace))
                if isinstance(symbol, m2_expr.ExprMem):
                    # Replace only in ptr (case to_replace: @[arg] = 8, expr:
                    # @[arg] = @[arg])
                    symbol = m2_expr.ExprMem(
                        self.symb.expr_simp(
                            symbol.arg.replace_expr(to_replace)), symbol.size)
                self.symb.apply_change(symbol, symb_value)

            # Check computed values against real ones
            # TODO idem memory
            if (isinstance(symbol, m2_expr.ExprId)
                    and isinstance(symb_value, m2_expr.ExprInt)):
                if hasattr(jitter.cpu, symbol.name):
                    value = m2_expr.ExprInt(getattr(jitter.cpu, symbol.name),
                                            symbol.size)
                    assert value == self.symb.symbols[symbol]

        cur_addr = jitter.pc
        self.logger.debug("Current address: %s", hex(cur_addr))
        if cur_addr == 0x1337BEEF or cur_addr == self.return_addr:
            # End reached
            if self.logger.isEnabledFor(logging.DEBUG):
                print "In:"
                for x in self.memories_read:
                    print "\t%s (%s)" % (
                        x,
                        self.c_handler.expr_to_c(x),
                    )
                print "Out:"
                for x in self.memories_write:
                    print "\t%s (%s)" % (
                        x,
                        self.c_handler.expr_to_c(x),
                    )
            return True

        # Update state
        ## Reset cache structures
        self.mdis.job_done.clear()
        self.symb_ir.blocs.clear()

        ## Update current state
        asm_block = self.mdis.dis_bloc(cur_addr)
        irblocks = self.symb_ir.add_bloc(asm_block)

        self.symb.emul_ir_blocks(cur_addr)

        return True
Esempio n. 15
0
    def eval_ExprMem(self, e, eval_cache=None):
        if eval_cache is None:
            eval_cache = {}
        a_val = self.expr_simp(self.eval_expr(e.arg, eval_cache))
        if a_val != e.arg:
            a = self.expr_simp(m2_expr.ExprMem(a_val, size=e.size))
        else:
            a = e
        if a in self.symbols:
            return self.symbols[a]
        tmp = None
        # test if mem lookup is known
        if a_val in self.symbols.symbols_mem:
            tmp = self.symbols.symbols_mem[a_val][0]
        if tmp is None:

            v = self.find_mem_by_addr(a_val)
            if not v:
                out = []
                ov = self.get_mem_overlapping(a, eval_cache)
                off_base = 0
                ov.sort()
                # ov.reverse()
                for off, x in ov:
                    # off_base = off * 8
                    # x_size = self.symbols[x].size
                    if off >= 0:
                        m = min(a.size - off * 8, x.size)
                        ee = m2_expr.ExprSlice(self.symbols[x], 0, m)
                        ee = self.expr_simp(ee)
                        out.append((ee, off_base, off_base + m))
                        off_base += m
                    else:
                        m = min(a.size - off * 8, x.size)
                        ee = m2_expr.ExprSlice(self.symbols[x], -off * 8, m)
                        ff = self.expr_simp(ee)
                        new_off_base = off_base + m + off * 8
                        out.append((ff, off_base, new_off_base))
                        off_base = new_off_base
                if out:
                    missing_slice = self.rest_slice(out, 0, a.size)
                    for sa, sb in missing_slice:
                        ptr = self.expr_simp(
                            a_val + m2_expr.ExprInt_from(a_val, sa / 8))
                        mm = m2_expr.ExprMem(ptr, size=sb - sa)
                        mm.is_term = True
                        mm.is_simp = True
                        out.append((mm, sa, sb))
                    out.sort(key=lambda x: x[1])
                    # for e, sa, sb in out:
                    #    print str(e), sa, sb
                    ee = m2_expr.ExprSlice(m2_expr.ExprCompose(out), 0, a.size)
                    ee = self.expr_simp(ee)
                    return ee
            if self.func_read and isinstance(a.arg, m2_expr.ExprInt):
                return self.func_read(a)
            else:
                # XXX hack test
                a.is_term = True
                return a
        # bigger lookup
        if a.size > tmp.size:
            rest = a.size
            ptr = a_val
            out = []
            ptr_index = 0
            while rest:
                v = self.find_mem_by_addr(ptr)
                if v is None:
                    # raise ValueError("cannot find %s in mem"%str(ptr))
                    val = m2_expr.ExprMem(ptr, 8)
                    v = val
                    diff_size = 8
                elif rest >= v.size:
                    val = self.symbols[v]
                    diff_size = v.size
                else:
                    diff_size = rest
                    val = self.symbols[v][0:diff_size]
                val = (val, ptr_index, ptr_index + diff_size)
                out.append(val)
                ptr_index += diff_size
                rest -= diff_size
                ptr = self.expr_simp(
                    self.eval_expr(
                        m2_expr.ExprOp('+', ptr,
                                       m2_expr.ExprInt_from(ptr, v.size / 8)),
                        eval_cache))
            e = self.expr_simp(m2_expr.ExprCompose(out))
            return e
        # part lookup
        tmp = self.expr_simp(m2_expr.ExprSlice(self.symbols[tmp], 0, a.size))
        return tmp
Esempio n. 16
0
def wsbh(ir, instr, a, b):
    e = [m2_expr.ExprAff(a, m2_expr.ExprCompose([(b[8:16],  0, 8),
                                 (b[0:8]  , 8, 16),
                                 (b[24:32], 16, 24),
                                 (b[16:24], 24, 32)]))]
    return e, []
Esempio n. 17
0
def extr(arg1, arg2, arg3, arg4):
    compose = m2_expr.ExprCompose([(arg2, 0, arg2.size),
                                   (arg3, arg2.size, arg2.size + arg3.size)])
    arg1 = compose[int(arg4.arg):int(arg4.arg) + arg1.size]
Esempio n. 18
0
    def test_Variables_Identifier(self):
        import miasm2.expression.expression as m2_expr
        from miasm2.expression.expression_helper import Variables_Identifier

        # Build a complex expression
        cst = m2_expr.ExprInt16(0x100)
        eax = m2_expr.ExprId("EAX")
        ebx = m2_expr.ExprId("EBX")
        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(vi.vars.items()):
            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(vi.vars.items()):
            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(vi2.vars.items()):
            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.ExprInt32(-1)
        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(vi2.vars.items()):
            new_expr = new_expr.replace_expr({var_id: var_value})
        self.assertEqual(vi.equation, new_expr)
Esempio n. 19
0
    def get_mem_state(self, expr):
        """
        Evaluate the @expr memory in the current state using @cache
        @expr: the memory key
        """
        ptr, size = expr.arg, expr.size
        ret = self.find_mem_by_addr(ptr)
        if not ret:
            out = []
            overlaps = self.get_mem_overlapping(expr)
            off_base = 0
            for off, mem in overlaps:
                if off >= 0:
                    new_size = min(size - off * 8, mem.size)
                    tmp = self.expr_simp(self.symbols[mem][0:new_size])
                    out.append((tmp, off_base, off_base + new_size))
                    off_base += new_size
                else:
                    new_size = min(size - off * 8, mem.size)
                    tmp = self.expr_simp(self.symbols[mem][-off * 8:new_size])
                    new_off_base = off_base + new_size + off * 8
                    out.append((tmp, off_base, new_off_base))
                    off_base = new_off_base
            if out:
                missing_slice = self.rest_slice(out, 0, size)
                for slice_start, slice_stop in missing_slice:
                    ptr = self.expr_simp(
                        ptr + m2_expr.ExprInt(slice_start / 8, ptr.size))
                    mem = m2_expr.ExprMem(ptr, slice_stop - slice_start)
                    out.append((mem, slice_start, slice_stop))
                out.sort(key=lambda x: x[1])
                args = [expr for (expr, _, _) in out]
                tmp = m2_expr.ExprSlice(m2_expr.ExprCompose(*args), 0, size)
                tmp = self.expr_simp(tmp)
                return tmp

            if self.func_read and isinstance(ptr, m2_expr.ExprInt):
                return self.func_read(expr)
            else:
                return expr
        # bigger lookup
        if size > ret.size:
            rest = size
            ptr = ptr
            out = []
            ptr_index = 0
            while rest:
                mem = self.find_mem_by_addr(ptr)
                if mem is None:
                    value = m2_expr.ExprMem(ptr, 8)
                    mem = value
                    diff_size = 8
                elif rest >= mem.size:
                    value = self.symbols[mem]
                    diff_size = mem.size
                else:
                    diff_size = rest
                    value = self.symbols[mem][0:diff_size]
                out.append((value, ptr_index, ptr_index + diff_size))
                ptr_index += diff_size
                rest -= diff_size
                ptr = self.expr_simp(ptr +
                                     m2_expr.ExprInt(mem.size / 8, ptr.size))
            out.sort(key=lambda x: x[1])
            args = [expr for (expr, _, _) in out]
            ret = self.expr_simp(m2_expr.ExprCompose(*args))
            return ret
        # part lookup
        ret = self.expr_simp(self.symbols[ret][:size])
        return ret
Esempio n. 20
0
def extr(arg1, arg2, arg3, arg4):
    compose = m2_expr.ExprCompose(arg2, arg3)
    arg1 = compose[int(arg4.arg):int(arg4)+arg1.size]