コード例 #1
0
 def call_effects(self, ad, instr):
     call_assignblk = AssignBlock([
         ExprAssign(
             self.ret_reg,
             ExprOp(
                 'call_func_ret',
                 ad,
                 self.sp,
                 self.arch.regs.RCX,
                 self.arch.regs.RDX,
                 self.arch.regs.R8,
                 self.arch.regs.R9,
             )),
         ExprAssign(self.sp, ExprOp('call_func_stack', ad, self.sp)),
     ], instr)
     return [call_assignblk], []
コード例 #2
0
ファイル: sem.py プロジェクト: w4kfu/miasm
def jmp(ir, instr, reg_or_imm):
    """JMP - Change PC to a register content or an immediate.
       Note: the behavior in VLIW mode is not implemented"""

    take_jmp = ExprInt(1, 32)

    if isinstance(reg_or_imm, ExprId):
        # PC <- Rm31..1||0
        new_PC = ExprAssign(PC, reg_or_imm)
    else:
        # PC <- PC31..28||0000||(target24)23..1||0
        new_PC = ExprAssign(
            PC,
            ExprOp("+", ExprOp("&", PC, ExprInt(0xF0000000, 32)), reg_or_imm))

    return [new_PC, ExprAssign(ir.IRDst, new_PC)], []
コード例 #3
0
def simp_cond_logic_ext(expr_s, expr):
    """(X.zeroExt() + ... + Int) ? A:B => X + ... + int[:] ? A:B"""
    cond = expr.cond
    if not cond.is_op():
        return expr
    if cond.op not in ["&", "^", "|"]:
        return expr
    is_ok = True
    sizes = set()
    for arg in cond.args:
        if arg.is_int():
            continue
        if (arg.is_op() and
            arg.op.startswith("zeroExt")):
            sizes.add(arg.args[0].size)
            continue
        is_ok = False
        break
    if not is_ok:
        return expr
    if len(sizes) != 1:
        return expr
    size = list(sizes)[0]
    args = [expr_s(arg[:size]) for arg in cond.args]
    cond = ExprOp(cond.op, *args)
    return ExprCond(cond, expr.src1, expr.src2)
コード例 #4
0
ファイル: arch.py プロジェクト: gavz/PinkyVM
    def asm_ast_to_expr(self, arg, loc_db):
        """Convert AST to expressions
       Note: - Must be implemented"""

        if isinstance(arg, AstId):
            if isinstance(arg.name, ExprId):
                return arg.name
            if isinstance(arg.name, str) and arg.name in gpr_names:
                return None  # GV: why?
            loc_key = loc_db.get_or_create_name_location(arg.name.encode())
            return ExprLoc(loc_key, 32)

        elif isinstance(arg, AstMem):
            addr = self.asm_ast_to_expr(arg.ptr, loc_db)
            if addr is None:
                return None
            return ExprMem(addr, 32)

        elif isinstance(arg, AstInt):
            return ExprInt(arg.value, 32)

        elif isinstance(arg, AstOp):
            args = [self.asm_ast_to_expr(tmp, loc_db) for tmp in arg.args]
            if None in args:
                return None
            return ExprOp(arg.op, *args)

        # Raise an exception if the argument was not processed
        message = "mep_arg.asm_ast_to_expr(): don't know what \
                to do with a '%s' instance." % type(arg)
        raise Exception(message)
コード例 #5
0
def btstm(ir, instr, r0, rm_deref, imm3):
    """BTSTM - Bit Test Memory"""

    # R0 <- ZeroExt( MemByte(Rm) and (1<<imm3) )
    e = []
    e.append(ExprAssign(r0, ExprOp("&", ExprMem(rm_deref.ptr, 8), i8(1) << imm3[:8]).zeroExtend(32)))
    return e, []
コード例 #6
0
def bnotm(ir, instr, rm_deref, imm3):
    """BNOTM - Bit Not Memory"""

    # MemByte(Rm) <- MemByte(Rm) xor (1<<imm3)
    e = []
    e.append(ExprAssign(ExprMem(rm_deref.ptr, 8), ExprOp("^", ExprMem(rm_deref.ptr, 8), (i8(1) << imm3[:8]))))
    return e, []
コード例 #7
0
def bsetm(ir, instr, rm_deref, imm3):
    """BSETM - Bit Set Memory"""

    # MemByte(Rm) <- MemByte(Rm) or (1<<imm3)
    e = []
    e.append(ExprAssign(ExprMem(rm_deref.ptr, 8), ExprOp("|", ExprMem(rm_deref.ptr, 8), (i8(1) << imm3[:8]))))
    return e, []
コード例 #8
0
def simp_slice_of_op_ext(expr_s, expr):
    """
    (X.zeroExt() + {Z, } + ... + Int)[0:8] => X + ... + int[:]
    (X.zeroExt() | ... | Int)[0:8] => X | ... | int[:]
    ...
    """
    if expr.start != 0:
        return expr
    src = expr.arg
    if not src.is_op():
        return expr
    if src.op not in ['+', '|', '^', '&']:
        return expr
    is_ok = True
    for arg in src.args:
        if arg.is_int():
            continue
        if (arg.is_op() and
            arg.op.startswith("zeroExt") and
            arg.args[0].size == expr.stop):
            continue
        if arg.is_compose():
            continue
        is_ok = False
        break
    if not is_ok:
        return expr
    args = [expr_s(arg[:expr.stop]) for arg in src.args]
    return ExprOp(src.op, *args)
コード例 #9
0
 def call_effects(self, addr, instr):
     assignblks, extra = super(IRADelModCallStack,
                               self).call_effects(addr, instr)
     if use_ida_stack:
         stk_before = idc.get_spd(instr.offset)
         stk_after = idc.get_spd(instr.offset + instr.l)
         stk_diff = stk_after - stk_before
         print(hex(stk_diff))
         call_assignblk = AssignBlock([
             ExprAssign(self.ret_reg, ExprOp('call_func_ret', addr)),
             ExprAssign(self.sp,
                        self.sp + ExprInt(stk_diff, self.sp.size))
         ], instr)
         return [call_assignblk], []
     else:
         if not dontmodstack:
             return assignblks, extra
         out = []
         for assignblk in assignblks:
             dct = dict(assignblk)
             dct = {
                 dst: src
                 for (dst, src) in viewitems(dct) if dst != self.sp
             }
             out.append(AssignBlock(dct, assignblk.instr))
     return out, extra
コード例 #10
0
def update_flag_arith_addwc_zn(arg1, arg2, arg3):
    """
    Compute znp flags for (arg1 + arg2 + cf)
    """
    e = []
    e += update_flag_zfaddwc_eq(arg1, arg2, arg3)
    e += [ExprAssign(nf, ExprOp("FLAG_SIGN_ADDWC", arg1, arg2, arg3))]
    return e
コード例 #11
0
def update_flag_arith_sub_zn(arg1, arg2):
    """
    Compute zf and nf flags for (arg1 - arg2)
    """
    e = []
    e += update_flag_zf_eq(arg1, arg2)
    e += [ExprAssign(nf, ExprOp("FLAG_SIGN_SUB", arg1, arg2))]
    return e
コード例 #12
0
ファイル: sem.py プロジェクト: J4ckKn1ght/nkn
def sbvck3(ir, instr, r0, rn, rm):
    """SBVCK3 - Check subtraction overflow"""

    # if(Overflow(Rn-Rm)) R0<-1 else R0<-0 (Signed)

    # Subtract registers
    reg_sub = ExprOp("+", rn, rm)

    # Get the register storing the highest value
    max_rn_rm = ExprCond(ExprOp(">", rn, rm), rn, rm)

    # Check for an overflow
    overflow_test = ExprOp(">", reg_sub, max_rn_rm)

    # Return the result
    condition = ExprCond(overflow_test, ExprInt(1, 32), ExprInt(0, 32))
    return [ExprAssign(r0, condition)], []
コード例 #13
0
 def eval_exprop(self, expr, **kwargs):
     """[DEV]: Evaluate an ExprOp using the current state"""
     args = []
     for oarg in expr.args:
         arg = self.eval_expr_visitor(oarg, **kwargs)
         args.append(arg)
     ret = ExprOp(expr.op, *args)
     return ret
コード例 #14
0
def update_flag_arith_subwc_zn(arg1, arg2, arg3):
    """
    Compute znp flags for (arg1 - (arg2 + cf))
    """
    e = []
    e += update_flag_zfsubwc_eq(arg1, arg2, arg3)
    e += [ExprAssign(nf, ExprOp("FLAG_SIGN_SUBWC", arg1, arg2, arg3))]
    return e
コード例 #15
0
def tst(ir, instr, arg1, arg2):
    e = []
    arg2 = extend_arg(arg1, arg2)
    res = arg1 & arg2

    e += [ExprAssign(zf, ExprOp('FLAG_EQ_AND', arg1, arg2))]
    e += update_flag_nf(res)

    return e, []
コード例 #16
0
ファイル: sem.py プロジェクト: J4ckKn1ght/nkn
def bgei(reg_test, imm4, disp16):
    """BGEI - Branch if the register is greater or equal to imm4."""

    # if(Rn>=ZeroExt(imm4)) PC <- PC +SignExt((disp17)16..1||0) - (Signed comparison)
    cond = i32(1) if ExprOp(TOK_EQUAL, reg_test, imm4) else compute_s_inf(imm4, reg_test).zeroExtend(32)
    dst = disp16 if cond else ExprLoc(ir.get_next_break_loc_key(instr), 32)
    take_jmp = ExprInt(1, 32) if cond else ExprInt(0, 32)
    PC = dst
    ir.IRDst = dst
コード例 #17
0
def simp_double_signext(_, expr):
    """A.signExt(X).signExt(Y) => A.signExt(Y)"""
    if not (expr.is_op() and expr.op.startswith("signExt")):
        return expr
    arg1 = expr.args[0]
    if not (arg1.is_op() and arg1.op.startswith("signExt")):
        return expr
    arg2 = arg1.args[0]
    return ExprOp(expr.op, arg2)
コード例 #18
0
def simp_cond_inf_eq_unsigned_zero(expr_s, expr):
    """
    (a <=u 0) => a == 0
    """
    if not expr.is_op(TOK_INF_EQUAL_UNSIGNED):
        return expr
    if not expr.args[1].is_int(0):
        return expr
    return ExprOp(TOK_EQUAL, expr.args[0], expr.args[1])
コード例 #19
0
 def check(self):
     regs = self.dse.lifter.arch.regs
     value = self.dse.eval_expr(regs.EDX)
     # The expected value should contains '<<', showing it has been in the
     # corresponding generated label
     expected = ExprOp(
         '<<', regs.EDX,
         ExprCompose(regs.ECX[0:8], ExprInt(0x0, 24)) & ExprInt(0x1F, 32))
     assert value == expected
コード例 #20
0
ファイル: parse_asm.py プロジェクト: yarhrn/miasm
def asm_ast_to_expr_with_size(arg, loc_db, size):
    if isinstance(arg, AstId):
        return ExprId(arg.name.encode(), size)
    if isinstance(arg, AstOp):
        args = [asm_ast_to_expr_with_size(tmp, loc_db, size) for tmp in arg.args]
        return ExprOp(arg.op, *args)
    if isinstance(arg, AstInt):
        return ExprInt(arg.value, size)
    return None
コード例 #21
0
def simp_cond_factor(e_s, expr):
    "Merge similar conditions"
    if not expr.op in ["+", "|", "^", "&", "*", '<<', '>>', 'a>>']:
        return expr
    if len(expr.args) < 2:
        return expr

    if expr.op in ['>>', '<<', 'a>>']:
        assert len(expr.args) == 2

    # Note: the following code is correct for non-commutative operation only if
    # there is 2 arguments. Otherwise, the order is not conserved

    # Regroup sub-expression by similar conditions
    conds = {}
    not_conds = []
    multi_cond = False
    for arg in expr.args:
        if not arg.is_cond():
            not_conds.append(arg)
            continue
        cond = arg.cond
        if not cond in conds:
            conds[cond] = []
        else:
            multi_cond = True
        conds[cond].append(arg)
    if not multi_cond:
        return expr

    # Rebuild the new expression
    c_out = not_conds
    for cond, vals in viewitems(conds):
        new_src1 = [x.src1 for x in vals]
        new_src2 = [x.src2 for x in vals]
        src1 = e_s.expr_simp_wrapper(ExprOp(expr.op, *new_src1))
        src2 = e_s.expr_simp_wrapper(ExprOp(expr.op, *new_src2))
        c_out.append(ExprCond(cond, src1, src2))

    if len(c_out) == 1:
        new_e = c_out[0]
    else:
        new_e = ExprOp(expr.op, *c_out)
    return new_e
コード例 #22
0
def simp_sign_inf_zeroext(expr_s, expr):
    """
    /!\ Ensure before: X.zeroExt(X.size) => X

    X.zeroExt() <s 0 => 0
    X.zeroExt() <=s 0 => X == 0

    X.zeroExt() <s cst => X.zeroExt() <u cst (cst positive)
    X.zeroExt() <=s cst => X.zeroExt() <=u cst (cst positive)

    X.zeroExt() <s cst => 0 (cst negative)
    X.zeroExt() <=s cst => 0 (cst negative)

    """
    if not (expr.is_op(TOK_INF_SIGNED) or expr.is_op(TOK_INF_EQUAL_SIGNED)):
        return expr
    arg1, arg2 = expr.args
    if not arg2.is_int():
        return expr
    if not (arg1.is_op() and arg1.op.startswith("zeroExt")):
        return expr
    src = arg1.args[0]
    assert src.size < arg1.size

    # If cst is zero
    if arg2.is_int(0):
        if expr.is_op(TOK_INF_SIGNED):
            # X.zeroExt() <s 0 => 0
            return ExprInt(0, expr.size)
        else:
            # X.zeroExt() <=s 0 => X == 0
            return ExprOp(TOK_EQUAL, src, ExprInt(0, src.size))

    # cst is not zero
    cst = int(arg2)
    if cst & (1 << (arg2.size - 1)):
        # cst is negative
        return ExprInt(0, expr.size)
    # cst is positive
    if expr.is_op(TOK_INF_SIGNED):
        # X.zeroExt() <s cst => X.zeroExt() <u cst (cst positive)
        return ExprOp(TOK_INF_UNSIGNED, src, expr_s(arg2[:src.size]))
    # X.zeroExt() <=s cst => X.zeroExt() <=u cst (cst positive)
    return ExprOp(TOK_INF_EQUAL_UNSIGNED, src, expr_s(arg2[:src.size]))
コード例 #23
0
    def from_ExprOp(self, expr: Expr) -> Expr:
        """
        Translates an ExprOp.
        
        Args:
            expr: Expression to translate.
        
        Returns:
            Expression as ExprOp.
        """
        args = list(map(self.from_expr, expr.args))
        res = args[0]

        if len(args) > 1:
            for arg in args[1:]:
                res = ExprOp(expr.op, res, self.from_expr(arg))
        else:
            res = ExprOp(expr.op, res)
        return res
コード例 #24
0
    def call_effects(self, addr, instr):
        """Default modelisation of a function call to @addr. This may be used to:

        * insert dependencies to arguments (stack base, registers, ...)
        * add some side effects (stack clean, return value, ...)

        Return a couple:
        * list of assignments to add to the current irblock
        * list of additional irblocks

        @addr: (Expr) address of the called function
        @instr: native instruction which is responsible of the call
        """

        call_assignblk = AssignBlock([
            ExprAssign(self.ret_reg, ExprOp('call_func_ret', addr, self.sp)),
            ExprAssign(self.sp, ExprOp('call_func_stack', addr, self.sp))
        ], instr)
        return [call_assignblk], []
コード例 #25
0
    def _fill_phi(self, *args):
        """
        Fills a phi function with variables.

        phi(x.1, x.5, x.6)

        :param args: list of ExprId
        :return: ExprOp
        """
        return ExprOp(self.PHI_STR, *set(args))
コード例 #26
0
def ands(ir, instr, arg1, arg2, arg3):
    e = []
    arg3 = extend_arg(arg2, arg3)
    res = arg2 & arg3

    e += [ExprAssign(zf, ExprOp('FLAG_EQ_AND', arg2, arg3))]
    e += update_flag_nf(res)

    e.append(ExprAssign(arg1, res))
    return e, []
コード例 #27
0
def bics(ir, instr, arg1, arg2, arg3):
    e = []
    tmp1, tmp2 = arg2, (~extend_arg(arg2, arg3))
    res = tmp1 & tmp2

    e += [ExprAssign(zf, ExprOp('FLAG_EQ_AND', tmp1, tmp2))]
    e += update_flag_nf(res)

    e.append(ExprAssign(arg1, res))
    return e, []
コード例 #28
0
ファイル: expression_reduce.py プロジェクト: J4ckKn1ght/nkn
    def categorize(self, node, lvl=0, **kwargs):
        """Recursively apply rules to @node

        @node: ExprNode to analyze
        @lvl: actual recursion level
        """

        expr = node.expr
        log_reduce.debug("\t" * lvl + "Reduce...: %s", node.expr)
        if isinstance(expr, ExprId):
            node = ExprNodeId(expr)
        elif isinstance(expr, ExprInt):
            node = ExprNodeInt(expr)
        elif isinstance(expr, ExprLoc):
            node = ExprNodeLoc(expr)
        elif isinstance(expr, ExprMem):
            ptr = self.categorize(node.ptr, lvl=lvl + 1, **kwargs)
            node = ExprNodeMem(ExprMem(ptr.expr, expr.size))
            node.ptr = ptr
        elif isinstance(expr, ExprSlice):
            arg = self.categorize(node.arg, lvl=lvl + 1, **kwargs)
            node = ExprNodeSlice(ExprSlice(arg.expr, expr.start, expr.stop))
            node.arg = arg
        elif isinstance(expr, ExprOp):
            new_args = []
            for arg in node.args:
                new_a = self.categorize(arg, lvl=lvl + 1, **kwargs)
                assert new_a.expr.size == arg.expr.size
                new_args.append(new_a)
            node = ExprNodeOp(ExprOp(expr.op, *[x.expr for x in new_args]))
            node.args = new_args
            expr = node.expr
        elif isinstance(expr, ExprCompose):
            new_args = []
            new_expr_args = []
            for arg in node.args:
                arg = self.categorize(arg, lvl=lvl + 1, **kwargs)
                new_args.append(arg)
                new_expr_args.append(arg.expr)
            new_expr = ExprCompose(*new_expr_args)
            node = ExprNodeCompose(new_expr)
            node.args = new_args
        elif isinstance(expr, ExprCond):
            cond = self.categorize(node.cond, lvl=lvl + 1, **kwargs)
            src1 = self.categorize(node.src1, lvl=lvl + 1, **kwargs)
            src2 = self.categorize(node.src2, lvl=lvl + 1, **kwargs)
            node = ExprNodeCond(ExprCond(cond.expr, src1.expr, src2.expr))
            node.cond, node.src1, node.src2 = cond, src1, src2
        else:
            raise TypeError("Unknown Expr Type %r", type(expr))

        node.info = self.apply_rules(node, lvl=lvl, **kwargs)
        log_reduce.debug("\t" * lvl + "Reduce result: %s %r", node.expr,
                         node.info)
        return node
コード例 #29
0
def simp_cond_add(expr_s, expr):
    """
    (a+b)?X:Y => (a == b)?Y:X
    (a^b)?X:Y => (a == b)?Y:X
    """
    cond = expr.cond
    if not cond.is_op():
        return expr
    if cond.op not in ['+', '^']:
        return expr
    if len(cond.args) != 2:
        return expr
    arg1, arg2 = cond.args
    if cond.is_op('+'):
        new_cond = ExprOp('==', arg1, expr_s(-arg2))
    elif cond.is_op('^'):
        new_cond = ExprOp('==', arg1, arg2)
    else:
        raise ValueError('Bad case')
    return ExprCond(new_cond, expr.src2, expr.src1)
コード例 #30
0
 def get_ir(self, instr):
     args = instr.args
     if len(args) and isinstance(args[-1], ExprOp):
         if (args[-1].op in ['<<', '>>', '<<a', 'a>>', '<<<', '>>>']
                 and isinstance(args[-1].args[-1], ExprId)):
             args[-1] = ExprOp(args[-1].op, args[-1].args[0],
                               args[-1].args[-1][:8].zeroExtend(32))
     instr_ir, extra_ir = get_mnemo_expr(self, instr, *args)
     self.mod_pc(instr, instr_ir, extra_ir)
     instr_ir, extra_ir = self.del_dst_zr(instr, instr_ir, extra_ir)
     return instr_ir, extra_ir
コード例 #31
0
ファイル: sem.py プロジェクト: cea-sec/miasm
def bclrm(rm_deref, imm3):
    """BCLRM - Bit Clear Memory"""

    # MemByte(Rm) <- MemByte(Rm) and ~(1<<imm3)
    shift = ExprOp("<<", i8(1), imm3[:8])
    mem8[rm_deref.ptr] = ExprOp("&", mem8[rm_deref.ptr], shift.__invert__())