Esempio n. 1
0
    def _gen_path_constraints(self, translator, expr, expected):
        """Generate path constraint from @expr. Handle special case with
        generated labels
        """
        out = []
        expected_is_label = expr_is_label(expected)
        for consval in possible_values(expr):
            if (expected_is_label and consval.value != expected):
                continue
            if (not expected_is_label and expr_is_label(consval.value)):
                continue

            conds = z3.And(*[
                translator.from_expr(cond.to_constraint())
                for cond in consval.constraints
            ])
            if expected != consval.value:
                conds = z3.And(
                    conds,
                    translator.from_expr(
                        m2_expr.ExprAff(consval.value, expected)))
            out.append(conds)

        if out:
            conds = z3.Or(*out)
        else:
            # Ex: expr: lblgen1, expected: 0x1234
            # -> Avoid unconsistent solution lblgen1 = 0x1234
            conds = translator.from_expr(self.unsat_expr)
        return conds
Esempio n. 2
0
def csneg(ir, instr, arg1, arg2, arg3, arg4):
    e = []
    cond_expr = cond2expr[arg4.name]
    e.append(m2_expr.ExprAff(arg1, m2_expr.ExprCond(cond_expr,
                                                    arg2,
                                                    -arg3)))
    return e, []
Esempio n. 3
0
def strh(ir, instr, arg1, arg2):
    e = []
    addr, updt = get_mem_access(arg2)
    e.append(m2_expr.ExprAff(m2_expr.ExprMem(addr, 16), arg1[:16]))
    if updt:
        e.append(updt)
    return e, []
Esempio n. 4
0
def l_str(ir, instr, arg1, arg2):
    e = []
    addr, updt = get_mem_access(arg2)
    e.append(m2_expr.ExprAff(m2_expr.ExprMem(addr, arg1.size), arg1))
    if updt:
        e.append(updt)
    return e, []
Esempio n. 5
0
def ands(ir, instr, arg1, arg2, arg3):
    e = []
    arg3 = extend_arg(arg2, arg3)
    res = arg2 & arg3
    e += update_flag_logic(res)
    e.append(m2_expr.ExprAff(arg1, res))
    return e, []
Esempio n. 6
0
def csinc(ir, instr, arg1, arg2, arg3, arg4):
    e = []
    cond_expr = cond2expr[arg4.name]
    e.append(m2_expr.ExprAff(arg1, m2_expr.ExprCond(cond_expr,
                                                    arg2,
                                                    arg3 + m2_expr.ExprInt(1, arg3.size))))
    return e, []
Esempio n. 7
0
def csetm(ir, instr, arg1, arg2):
    e = []
    cond_expr = cond2expr[arg2.name]
    e.append(m2_expr.ExprAff(arg1, m2_expr.ExprCond(cond_expr,
                                                    m2_expr.ExprInt_from(
                                                        arg1, -1),
                                                    m2_expr.ExprInt_from(arg1, 0))))
    return e, []
def emit_mov(ir, instr, a, b):
    # movの中間表現を生成
    instr_ir, extra_ir = sem.mov(ir, instr, a, b)
    # カウンタをインクリメントする中間表現を追加
    dst = expr.ExprMem(expr.ExprInt64(ADDR_COUNTER), 64)
    new_value = dst + expr.ExprInt64(1)
    instr_ir.append(expr.ExprAff(dst, new_value))
    return instr_ir, extra_ir
Esempio n. 9
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. 10
0
def ldr_size(ir, instr, arg1, arg2, size):
    e = []
    addr, updt = get_mem_access(arg2)
    e.append(
        m2_expr.ExprAff(arg1, m2_expr.ExprMem(addr, size).zeroExtend(arg1.size)))
    if updt:
        e.append(updt)
    return e, []
Esempio n. 11
0
def ldrsw(ir, instr, arg1, arg2):
    e = []
    addr, updt = get_mem_access(arg2)
    e.append(
        m2_expr.ExprAff(arg1, m2_expr.ExprMem(addr, 32).signExtend(arg1.size)))
    if updt:
        e.append(updt)
    return e, []
Esempio n. 12
0
def subs(ir, instr, arg1, arg2, arg3):
    e = []
    arg3 = extend_arg(arg2, arg3)
    res = arg2 - arg3
    e += update_flag_arith(res)
    e += update_flag_sub(arg2, arg3, res)
    e.append(m2_expr.ExprAff(arg1, res))
    return e, []
Esempio n. 13
0
def csetm(ir, instr, arg1, arg2):
    e = []
    cond_expr = cond2expr[arg2.name]
    e.append(m2_expr.ExprAff(arg1, m2_expr.ExprCond(cond_expr,
                                                    m2_expr.ExprInt(
                                                        -1, arg1.size),
                                                    m2_expr.ExprInt(0, arg1.size))))
    return e, []
Esempio n. 14
0
 def set_empty_dst_to_next(self, bloc, ir_blocs):
     for b in ir_blocs:
         if b.dst is not None:
             continue
         dst = m2_expr.ExprId(self.get_next_label(bloc.lines[-1]),
                              self.pc.size)
         b.irs.append([m2_expr.ExprAff(self.IRDst, dst)])
         b.lines.append(b.lines[-1])
Esempio n. 15
0
 def mod_pc(self, instr, instr_ir, extra_ir):
     "Replace PC by the instruction's offset"
     cur_offset = m2_expr.ExprInt64(instr.offset)
     for i, expr in enumerate(instr_ir):
         dst, src = expr.dst, expr.src
         if dst != self.pc:
             dst = dst.replace_expr({self.pc: cur_offset})
         src = src.replace_expr({self.pc: cur_offset})
         instr_ir[i] = m2_expr.ExprAff(dst, src)
     for b in extra_ir:
         for irs in b.irs:
             for i, expr in enumerate(irs):
                 dst, src = expr.dst, expr.src
                 if dst != self.pc:
                     dst = dst.replace_expr({self.pc: cur_offset})
                 src = src.replace_expr({self.pc: cur_offset})
                 irs[i] = m2_expr.ExprAff(dst, src)
Esempio n. 16
0
def ubfm(ir, instr, arg1, arg2, arg3, arg4):
    e = []
    rim, sim = int(arg3.arg), int(arg4) + 1
    if sim > rim:
        res = arg2[rim:sim].zeroExtend(arg1.size)
    else:
        shift = m2_expr.ExprInt(arg2.size - rim, arg2.size)
        res = (arg2[:sim].zeroExtend(arg1.size) << shift)
    e.append(m2_expr.ExprAff(arg1, res))
    return e, []
Esempio n. 17
0
    def _set_dst(self, value):
        """Find and replace the IRDst affectation's source by @value"""
        if self._dst_linenb is None:
            self._get_dst()

        ir = self.irs[self._dst_linenb]
        for i, expr in enumerate(ir):
            if isinstance(expr.dst, m2_expr.ExprId) and expr.dst.name == "IRDst":
                ir[i] = m2_expr.ExprAff(expr.dst, value)
        self._dst = value
Esempio n. 18
0
    def get_ir(self, instr):
        args = instr.args
        instr_ir, extra_ir = get_mnemo_expr(self, instr, *args)

        for i, x in enumerate(instr_ir):
            x = m2_expr.ExprAff(
                x.dst,
                x.src.replace_expr(
                    {self.pc: m2_expr.ExprInt(instr.offset + 4, 32)}))
            instr_ir[i] = x
        for irblock in extra_ir:
            for irs in irblock.irs:
                for i, x in enumerate(irs):
                    x = m2_expr.ExprAff(
                        x.dst,
                        x.src.replace_expr(
                            {self.pc: m2_expr.ExprInt(instr.offset + 4, 32)}))
                    irs[i] = x
        return instr_ir, extra_ir
Esempio n. 19
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. 20
0
 def set_dst(self, value):
     """Find and replace the IRDst affectation's source by @value"""
     dst = None
     for ir in self.irs:
         for i, expr in enumerate(ir):
             if isinstance(expr.dst, m2_expr.ExprId) and expr.dst.name == "IRDst":
                 if dst is not None:
                     raise ValueError('Multiple destinations!')
                 dst = value
                 ir[i] = m2_expr.ExprAff(expr.dst, value)
     self._dst = value
Esempio n. 21
0
 def set_empty_dst_to_next(self, bloc, ir_blocs):
     for b in ir_blocs:
         if b.dst is not None:
             continue
         next_lbl = bloc.get_next()
         if next_lbl is None:
             dst = m2_expr.ExprId(self.get_next_label(bloc.lines[-1]),
                                  self.pc.size)
         else:
             dst = m2_expr.ExprId(next_lbl, self.pc.size)
         b.irs.append(AssignBlock([m2_expr.ExprAff(self.IRDst, dst)]))
         b.lines.append(b.lines[-1])
Esempio n. 22
0
    def get_ir(self, instr):
        args = instr.args
        instr_ir, extra_ir = get_mnemo_expr(self, instr, *args)

        pc_fixed = {self.pc: m2_expr.ExprInt(instr.offset + 4, 32)}

        instr_ir = [m2_expr.ExprAff(expr.dst, expr.src.replace_expr(pc_fixed))
                    for expr in instr_ir]

        new_extra_ir = [irblock.modify_exprs(mod_src=lambda expr: expr.replace_expr(pc_fixed))
                        for irblock in extra_ir]
        return instr_ir, new_extra_ir
Esempio n. 23
0
    def apply_expr(self, expr):
        """Evaluate @expr and apply side effect if needed (ie. if expr is an
        assignment). Return the evaluated value"""

        # Eval expression
        to_eval = expr.src if isinstance(expr, m2_expr.ExprAff) else expr
        ret = self.expr_simp(self.eval_expr(to_eval))

        # Update value if needed
        if isinstance(expr, m2_expr.ExprAff):
            self.eval_ir(AssignBlock([m2_expr.ExprAff(expr.dst, ret)]))

        return ret
Esempio n. 24
0
 def irbloc_fix_regs_for_mode(self, irbloc, mode=64):
     for irs in irbloc.irs:
         for i, e in enumerate(irs):
             """
             special case for 64 bits:
             if destination is a 32 bit reg, zero extend the 64 bit reg
             """
             if (isinstance(e.dst, m2_expr.ExprId) and e.dst.size == 32
                     and e.dst in replace_regs):
                 src = self.expr_fix_regs_for_mode(e.src)
                 dst = replace_regs[e.dst].arg
                 e = m2_expr.ExprAff(dst, src.zeroExtend(64))
             irs[i] = self.expr_fix_regs_for_mode(e)
     irbloc.dst = self.expr_fix_regs_for_mode(irbloc.dst)
Esempio n. 25
0
    def mod_pc(self, instr, instr_ir, extra_ir):
        "Replace PC by the instruction's offset"
        cur_offset = m2_expr.ExprInt(instr.offset, 64)
        pc_fixed = {self.pc: cur_offset}
        for i, expr in enumerate(instr_ir):
            dst, src = expr.dst, expr.src
            if dst != self.pc:
                dst = dst.replace_expr(pc_fixed)
            src = src.replace_expr(pc_fixed)
            instr_ir[i] = m2_expr.ExprAff(dst, src)

        for idx, irblock in enumerate(extra_ir):
            extra_ir[idx] = irblock.modify_exprs(lambda expr: expr.replace_expr(pc_fixed) \
                                                 if expr != self.pc else expr,
                                                 lambda expr: expr.replace_expr(pc_fixed))
Esempio n. 26
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. 27
0
def teq(ir, instr, arg1, arg2):
    e = []

    loc_except, loc_except_expr = ir.gen_loc_key_and_expr(ir.IRDst.size)
    loc_next = ir.get_next_loc_key(instr)
    loc_next_expr = m2_expr.ExprLoc(loc_next, ir.IRDst.size)

    do_except = []
    do_except.append(
        m2_expr.ExprAff(
            exception_flags,
            m2_expr.ExprInt(EXCEPT_DIV_BY_ZERO, exception_flags.size)))
    do_except.append(m2_expr.ExprAff(ir.IRDst, loc_next_expr))
    blk_except = IRBlock(loc_except.index, [AssignBlock(do_except, instr)])

    cond = arg1 - arg2

    e = []
    e.append(
        m2_expr.ExprAff(ir.IRDst,
                        m2_expr.ExprCond(cond, loc_next_expr,
                                         loc_except_expr)))

    return e, [blk_except]
Esempio n. 28
0
    def patch_idiv(ir, instr, src1):
        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('idiv', src2, src1.signExtend(src2.size))
        c_r = m2_expr.ExprOp('imod', src2, src1.signExtend(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. 29
0
def ccmp(ir, instr, arg1, arg2, arg3, arg4):
    e = []
    if (arg2.is_int):
        arg2 = m2_expr.ExprInt(arg2.arg.arg, arg1.size)
    default_nf = arg3[0:1]
    default_zf = arg3[1:2]
    default_cf = arg3[2:3]
    default_of = arg3[3:4]
    cond_expr = cond2expr[arg4.name]
    res = arg1 - arg2
    new_nf = nf
    new_zf = update_flag_zf(res)[0].src
    new_cf = update_flag_sub_cf(arg1, arg2, res).src
    new_of = update_flag_sub_of(arg1, arg2, res).src

    e.append(
        m2_expr.ExprAff(nf, m2_expr.ExprCond(cond_expr, new_nf, default_nf)))
    e.append(
        m2_expr.ExprAff(zf, m2_expr.ExprCond(cond_expr, new_zf, default_zf)))
    e.append(
        m2_expr.ExprAff(cf, m2_expr.ExprCond(cond_expr, new_cf, default_cf)))
    e.append(
        m2_expr.ExprAff(of, m2_expr.ExprCond(cond_expr, new_of, default_of)))
    return e, []
Esempio n. 30
0
    def emul(self, ctx=None, step=False):
        # Init
        ctx_init = self._ira.arch.regs.regs_init
        if ctx is not None:
            ctx_init.update(ctx)
        depnodes = self.relevant_nodes
        solver = z3.Solver()
        symb_exec = symbexec(self._ira, ctx_init)
        temp_label = asm_label("Temp")
        history = self.relevant_labels[::-1]
        history_size = len(history)

        for hist_nb, label in enumerate(history):
            # Build block with relevant lines only
            affected_lines = set(depnode.line_nb for depnode in depnodes
                                 if depnode.label == label)
            irs = self._ira.blocs[label].irs
            affects = []

            for line_nb in sorted(affected_lines):
                affects.append(irs[line_nb])

            # Emul the block and get back destination
            dst = symb_exec.emulbloc(irbloc(temp_label, affects), step=step)

            # Add constraint
            if hist_nb + 1 < history_size:
                next_label = history[hist_nb + 1]
                expected = symb_exec.eval_expr(m2_expr.ExprId(next_label, 32))
                constraint = m2_expr.ExprAff(dst, expected)
                solver.add(Translator.to_language("z3").from_expr(constraint))

        # Save the solver
        self._solver = solver

        # Return only inputs values (others could be wrongs)
        return {
            depnode.element: symb_exec.symbols[depnode.element]
            for depnode in self.input
        }