示例#1
0
def simp_cmp_int_arg(expr_simp, expr):
    """
    (0x10 <= R0) ? A:B
    =>
    (R0 < 0x10) ? B:A
    """
    cond = expr.cond
    if not cond.is_op():
        return expr
    op = cond.op
    if op not in ['==', '<s', '<=s', '<u', '<=u']:
        return expr
    arg1, arg2 = cond.args
    if arg2.is_int():
        return expr
    if not arg1.is_int():
        return expr
    src1, src2 = expr.src1, expr.src2
    if op == "==":
        return ExprCond(ExprOp('==', arg2, arg1), src1, src2)

    arg1, arg2 = arg2, arg1
    src1, src2 = src2, src1
    if op == '<s':
        op = '<=s'
    elif op == '<=s':
        op = '<s'
    elif op == '<u':
        op = '<=u'
    elif op == '<=u':
        op = '<u'
    return ExprCond(ExprOp(op, arg1, arg2), src1, src2)
示例#2
0
def simp_cmp_int_arg(expr_simp, expr):
    """
    (0x10 <= R0) ? A:B
    =>
    (R0 < 0x10) ? B:A
    """
    cond = expr.cond
    if not cond.is_op():
        return expr
    op = cond.op
    if op not in [
            TOK_EQUAL, TOK_INF_SIGNED, TOK_INF_EQUAL_SIGNED, TOK_INF_UNSIGNED,
            TOK_INF_EQUAL_UNSIGNED
    ]:
        return expr
    arg1, arg2 = cond.args
    if arg2.is_int():
        return expr
    if not arg1.is_int():
        return expr
    src1, src2 = expr.src1, expr.src2
    if op == TOK_EQUAL:
        return ExprCond(ExprOp(TOK_EQUAL, arg2, arg1), src1, src2)

    arg1, arg2 = arg2, arg1
    src1, src2 = src2, src1
    if op == TOK_INF_SIGNED:
        op = TOK_INF_EQUAL_SIGNED
    elif op == TOK_INF_EQUAL_SIGNED:
        op = TOK_INF_SIGNED
    elif op == TOK_INF_UNSIGNED:
        op = TOK_INF_EQUAL_UNSIGNED
    elif op == TOK_INF_EQUAL_UNSIGNED:
        op = TOK_INF_UNSIGNED
    return ExprCond(ExprOp(op, arg1, arg2), src1, src2)
示例#3
0
def simp_cmp_int(expr_simp, expr):
    """
    ({X, 0} == int) => X == int[:]
    X + int1 == int2 => X == int2-int1
    """
    if (expr.is_op(TOK_EQUAL) and expr.args[1].is_int()
            and expr.args[0].is_compose() and len(expr.args[0].args) == 2
            and expr.args[0].args[1].is_int(0)):
        # ({X, 0} == int) => X == int[:]
        src = expr.args[0].args[0]
        int_val = int(expr.args[1])
        new_int = ExprInt(int_val, src.size)
        expr = expr_simp(ExprOp(TOK_EQUAL, src, new_int))
    elif (expr.is_op() and expr.op in [
            TOK_EQUAL,
    ] and expr.args[1].is_int() and expr.args[0].is_op("+")
          and expr.args[0].args[-1].is_int()):
        # X + int1 == int2 => X == int2-int1
        # WARNING:
        # X - 0x10 <=u 0x20 gives X in [0x10 0x30]
        # which is not equivalet to A <=u 0x10

        left, right = expr.args
        left, int_diff = left.args[:-1], left.args[-1]
        if len(left) == 1:
            left = left[0]
        else:
            left = ExprOp('+', *left)
        new_int = expr_simp(right - int_diff)
        expr = expr_simp(ExprOp(expr.op, left, new_int), )
    return expr
示例#4
0
def simp_zeroext_and_cst_eq_cst(expr_s, expr):
    """
    A.zeroExt(X) & ... & int == int => A & ... & int[:A.size] == int[:A.size]
    """
    if not expr.is_op(TOK_EQUAL):
        return expr
    arg1, arg2 = expr.args
    if not arg2.is_int():
        return expr
    if not arg1.is_op('&'):
        return expr
    is_ok = True
    sizes = set()
    for arg in arg1.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]
    if int(arg2) > ((1 << size) - 1):
        return expr
    args = [expr_s(arg[:size]) for arg in arg1.args]
    left = ExprOp('&', *args)
    right = expr_s(arg2[:size])
    ret = ExprOp(TOK_EQUAL, left, right)
    return ret
示例#5
0
    def test_sbvck3(self):
        """Test SBVCK3 execution"""

        # SBVCK3 R0,Rn,Rm
        exec_instruction(
            "SBVCK3 R0, R1, R2", [(ExprId("R1", 32), ExprInt(2, 32)),
                                  (ExprId("R2", 32), ExprInt(1, 32))],
            [(ExprId("R0", 32),
              ExprCond(
                  ExprOp(
                      ">", ExprInt(3, 32),
                      ExprCond(ExprOp(">", ExprInt(0x2, 32), ExprInt(0x1, 32)),
                               ExprInt(0x2, 32), ExprInt(0x1, 32))),
                  ExprInt(1, 32), ExprInt(0, 32)))])

        exec_instruction(
            "SBVCK3 R0, R1, R2", [(ExprId("R1", 32), ExprInt(0, 32)),
                                  (ExprId("R2", 32), ExprInt(1, 32))],
            [(ExprId("R0", 32),
              ExprCond(
                  ExprOp(
                      ">", ExprInt(1, 32),
                      ExprCond(ExprOp(">", ExprInt(0, 32), ExprInt(1, 32)),
                               ExprInt(0, 32), ExprInt(1, 32))), ExprInt(
                                   1, 32), ExprInt(0, 32)))])
def simp_cond_op_int(e_s, expr):
    "Extract conditions from operations"


    # x?a:b + x?c:d + e => x?(a+c+e:b+d+e)
    if not expr.op in ["+", "|", "^", "&", "*", '<<', '>>', 'a>>']:
        return expr
    if len(expr.args) < 2:
        return expr
    conds = set()
    for arg in expr.args:
        if arg.is_cond():
            conds.add(arg)
    if len(conds) != 1:
        return expr
    cond = list(conds).pop()

    args1, args2 = [], []
    for arg in expr.args:
        if arg.is_cond():
            args1.append(arg.src1)
            args2.append(arg.src2)
        else:
            args1.append(arg)
            args2.append(arg)

    return ExprCond(cond.cond,
                    ExprOp(expr.op, *args1),
                    ExprOp(expr.op, *args2))
示例#7
0
文件: sem.py 项目: manwefm/miasm
def fcmpe(ir, instr, arg1, arg2):
    e = []
    e.append(ExprAssign(nf, ExprOp('fcom_c0', arg1, arg2)))
    e.append(ExprAssign(cf, ~ExprOp('fcom_c0', arg1, arg2)))
    e.append(ExprAssign(zf, ExprOp('fcom_c3', arg1, arg2)))
    e.append(ExprAssign(of, ExprInt(0, 1)))
    return e, []
示例#8
0
def simp_cond_int(expr_simp, expr):
    if (expr.cond.is_op(TOK_EQUAL) and expr.cond.args[1].is_int()
            and expr.cond.args[0].is_compose()
            and len(expr.cond.args[0].args) == 2
            and expr.cond.args[0].args[1].is_int(0)):
        # ({X, 0} == int) => X == int[:]
        src = expr.cond.args[0].args[0]
        int_val = int(expr.cond.args[1])
        new_int = ExprInt(int_val, src.size)
        expr = expr_simp(
            ExprCond(ExprOp(TOK_EQUAL, src, new_int), expr.src1, expr.src2))
    elif (expr.cond.is_op() and expr.cond.op in [
            TOK_EQUAL, TOK_INF_SIGNED, TOK_INF_EQUAL_SIGNED, TOK_INF_UNSIGNED,
            TOK_INF_EQUAL_UNSIGNED
    ] and expr.cond.args[1].is_int() and expr.cond.args[0].is_op("+")
          and expr.cond.args[0].args[-1].is_int()):
        # X + int1 == int2 => X == int2-int1
        left, right = expr.cond.args
        left, int_diff = left.args[:-1], left.args[-1]
        if len(left) == 1:
            left = left[0]
        else:
            left = ExprOp('+', *left)
        new_int = expr_simp(right - int_diff)
        expr = expr_simp(
            ExprCond(ExprOp(expr.cond.op, left, new_int), expr.src1,
                     expr.src2))
    return expr
示例#9
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
    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
    c_out = not_conds[:]
    for cond, vals in conds.items():
        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
示例#10
0
文件: sem.py 项目: manwefm/miasm
def ucvtf(ir, instr, arg1, arg2):
    # XXX TODO: rounding
    e = []
    src = ExprOp('uint_to_fp', arg2)
    if arg1.size != src.size:
        src = ExprOp('fpconvert_fp%d' % arg1.size, src)
    e.append(ExprAssign(arg1, src))
    return e, []
示例#11
0
文件: sem.py 项目: manwefm/miasm
def fcvtzu(ir, instr, arg1, arg2):
    # XXX TODO: rounding
    e = []
    e.append(
        ExprAssign(
            arg1,
            ExprOp('fp_to_uint%d' % arg1.size,
                   ExprOp('fpround_towardszero', arg2))))
    return e, []
示例#12
0
 def call_effects(self, ad):
     """
     Default simulation of a function call to @ad
     @ad: (Expr) address of the called function
     """
     return [
         AssignBlock([
             ExprAff(self.ret_reg, ExprOp('call_func_ret', ad, self.sp)),
             ExprAff(self.sp, ExprOp('call_func_stack', ad, self.sp)),
         ])
     ]
示例#13
0
    def call_effects(self, ad, instr):
        new_sp = ExprOp("+", self.sp, ExprOp("-", ExprInt(0x4, 32)))
        next_addr = instr.offset + len(instr.b)
        next_label = self.symbol_pool.getby_offset(next_addr)

        block1 = AssignBlock([
            ExprAff(self.sp, new_sp),
            ExprAff(ExprMem(new_sp, 32), ExprId(next_label, 32))
        ])
        block2 = AssignBlock([ExprAff(self.IRDst, ad)])
        return [block1, block2]
示例#14
0
文件: ira.py 项目: sploving/miasm
 def call_effects(self, ad, instr):
     return [AssignBlock([ExprAff(self.ret_reg, ExprOp('call_func_ret', ad,
                                                       self.sp,
                                                       self.arch.regs.R3,
                                                       self.arch.regs.R4,
                                                       self.arch.regs.R5,
                                                       )),
                          ExprAff(self.sp, ExprOp('call_func_stack',
                                                  ad, self.sp)),
                         ],
                          instr
                        )]
示例#15
0
def add3(ir, instr, reg_dst, reg_src, reg_or_imm):
    """ADD3 - Add two register and store the result to a register, or
              add a register and an immediate and store the result to a register"""

    if isinstance(reg_or_imm, ExprId):
        # Rl <- Rn + Rm
        result = ExprOp("+", reg_src, reg_or_imm)
    else:
        # Rn <- Rm + SignExt(imm16)
        value = int(reg_or_imm.arg)
        result = ExprOp("+", reg_src, ExprInt(value, 32))

    return [ExprAff(reg_dst, result)], []
示例#16
0
    def to_expr(self):
        """Generate Miasm expression representing the C access"""

        if isinstance(self.ctype, ObjCPtr):
            return ExprOp(
                "addr",
                ExprOp("[]", self.name.to_expr(),
                       ExprInt(self.element, self.default_size)))
        elif isinstance(self.ctype, ObjCArray):
            return ExprOp("[]", self.name.to_expr(),
                          ExprInt(self.element, self.default_size))
        else:
            raise RuntimeError("Strange case")
示例#17
0
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)], []
示例#18
0
def simp_cmp_int(expr_simp, expr):
    """
    ({X, 0} == int) => X == int[:]
    X + int1 == int2 => X == int2-int1
    X ^ int1 == int2 => X == int1^int2
    """
    if (expr.is_op(TOK_EQUAL) and expr.args[1].is_int()
            and expr.args[0].is_compose() and len(expr.args[0].args) == 2
            and expr.args[0].args[1].is_int(0)):
        # ({X, 0} == int) => X == int[:]
        src = expr.args[0].args[0]
        int_val = int(expr.args[1])
        new_int = ExprInt(int_val, src.size)
        expr = expr_simp(ExprOp(TOK_EQUAL, src, new_int))
    elif not expr.is_op(TOK_EQUAL):
        return expr
    assert len(expr.args) == 2

    left, right = expr.args
    if left.is_int() and not right.is_int():
        left, right = right, left
    if not right.is_int():
        return expr
    if not (left.is_op() and left.op in ['+', '^']):
        return expr
    if not left.args[-1].is_int():
        return expr
    # X + int1 == int2 => X == int2-int1
    # WARNING:
    # X - 0x10 <=u 0x20 gives X in [0x10 0x30]
    # which is not equivalet to A <=u 0x10

    left_orig = left
    left, last_int = left.args[:-1], left.args[-1]

    if len(left) == 1:
        left = left[0]
    else:
        left = ExprOp(left.op, *left)

    if left_orig.op == "+":
        new_int = expr_simp(right - last_int)
    elif left_orig.op == '^':
        new_int = expr_simp(right ^ last_int)
    else:
        raise RuntimeError("Unsupported operator")

    expr = expr_simp(ExprOp(TOK_EQUAL, left, new_int), )
    return expr
示例#19
0
def ast_get_c_access_expr(ast, expr_types, lvl=0):
    """Transform C ast object into a C Miasm expression

    @ast: parsed pycparser.c_ast object
    @expr_types: a dictionnary linking ID names to their types
    @lvl: actual recursion level

    Example:

    IN:
    StructRef: ->
      ID: ptr_Test
      ID: a

    OUT:
    ExprOp('->', ExprId('ptr_Test', 64), ExprId('a', 64))
    """

    if isinstance(ast, c_ast.Constant):
        obj = ExprInt(int(ast.value), 64)
    elif isinstance(ast, c_ast.StructRef):
        name, field = ast.name, ast.field.name
        name = ast_get_c_access_expr(name, expr_types)
        if ast.type == "->":
            s_name = name
            s_field = ExprId(field, 64)
            obj = ExprOp('->', s_name, s_field)
        elif ast.type == ".":
            s_name = name
            s_field = ExprId(field, 64)
            obj = ExprOp("field", s_name, s_field)
        else:
            raise RuntimeError("Unknown struct access")
    elif isinstance(ast, c_ast.UnaryOp) and ast.op == "&":
        tmp = ast_get_c_access_expr(ast.expr, expr_types, lvl + 1)
        obj = ExprOp("addr", tmp)
    elif isinstance(ast, c_ast.ArrayRef):
        tmp = ast_get_c_access_expr(ast.name, expr_types, lvl + 1)
        index = ast_get_c_access_expr(ast.subscript, expr_types, lvl + 1)
        obj = ExprOp("[]", tmp, index)
    elif isinstance(ast, c_ast.ID):
        assert ast.name in expr_types
        obj = ExprId(ast.name, 64)
    elif isinstance(ast, c_ast.UnaryOp) and ast.op == "*":
        tmp = ast_get_c_access_expr(ast.expr, expr_types, lvl + 1)
        obj = ExprOp("deref", tmp)
    else:
        raise NotImplementedError("Unknown type")
    return obj
示例#20
0
def simp_cond_sign_bit(_, expr):
    """(a & .. & 0x80000000) ? A:B => (a & ...) <s 0 ? A:B"""
    cond = expr.cond
    if not cond.is_op('&'):
        return expr
    last = cond.args[-1]
    if not last.is_int(1 << (last.size - 1)):
        return expr
    zero = ExprInt(0, expr.cond.size)
    if len(cond.args) == 2:
        args = [cond.args[0], zero]
    else:
        args = [ExprOp('&', *list(cond.args[:-1])), zero]
    cond = ExprOp(TOK_INF_SIGNED, *args)
    return ExprCond(cond, expr.src1, expr.src2)
示例#21
0
文件: ira.py 项目: xxtxiaofeng/miasm
 def call_effects(self, ad, instr):
     call_assignblks = AssignBlock([
         ExprAssign(
             self.ret_reg,
             ExprOp(
                 'call_func_ret',
                 ad,
                 self.sp,
                 self.arch.regs.R3,
                 self.arch.regs.R4,
                 self.arch.regs.R5,
             )),
         ExprAssign(self.sp, ExprOp('call_func_stack', ad, self.sp)),
     ], instr)
     return [call_assignblks], []
示例#22
0
    def call_effects(self, ad, instr):
        """Default modelisation of a function call to @ad. This may be used to:

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

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

        return [AssignBlock(
            [ExprAff(self.ret_reg, ExprOp('call_func_ret', ad, self.sp)),
             ExprAff(self.sp, ExprOp(
                 'call_func_stack', ad, self.sp)),
             ])]
示例#23
0
    def test_ExprOp_strcst(self):
        from miasm2.expression.expression import ExprInt, ExprOp
        from miasm2.ir.translators.translator import Translator
        translator_smt2 = Translator.to_language("smt2")

        args = [ExprInt(i, 32) for i in xrange(9)]

        self.assertEqual(translator_smt2.from_expr(ExprOp('|', *args[:2])),
                         r'(bvor (_ bv0 32) (_ bv1 32))')
        self.assertEqual(translator_smt2.from_expr(ExprOp('-', *args[:2])),
                         r'(bvsub (_ bv0 32) (_ bv1 32))')
        self.assertEqual(translator_smt2.from_expr(ExprOp('+', *args[:3])),
                         r'(bvadd (bvadd (_ bv0 32) (_ bv1 32)) (_ bv2 32))')
        self.assertRaises(NotImplementedError, translator_smt2.from_expr,
                          ExprOp('X', *args[:1]))
示例#24
0
 def call_effects(self, ad, instr):
     call_assignblk = AssignBlock([
         ExprAff(
             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,
             )),
         ExprAff(self.sp, ExprOp('call_func_stack', ad, self.sp)),
     ], instr)
     return [call_assignblk], []
示例#25
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)
示例#26
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)
示例#27
0
文件: ira.py 项目: pmarkowsky/miasm
 def call_effects(self, ad):
     irs = [[
         ExprAff(
             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,
             )),
         ExprAff(self.sp, ExprOp('call_func_stack', ad, self.sp)),
     ]]
     return irs
示例#28
0
def access_simplifier(expr):
    """Expression visitor to simplify a C access represented in Miasm

    @expr: Miasm expression representing the C access

    Example:

    IN: (In c: ['*(&((&((*(ptr_Test)).a))[0]))'])
    [ExprOp('deref', ExprOp('addr', ExprOp('[]', ExprOp('addr',
    ExprOp('field', ExprOp('deref', ExprId('ptr_Test', 64)),
    ExprId('a', 64))), ExprInt(0x0, 64))))]

    OUT: (In c: ['(ptr_Test)->a'])
    [ExprOp('->', ExprId('ptr_Test', 64), ExprId('a', 64))]
    """

    if (expr.is_op("addr") and expr.args[0].is_op("[]")
            and expr.args[0].args[1] == ExprInt(0, 64)):
        return expr.args[0].args[0]
    elif (expr.is_op("[]") and expr.args[0].is_op("addr")
          and expr.args[1] == ExprInt(0, 64)):
        return expr.args[0].args[0]
    elif (expr.is_op("addr") and expr.args[0].is_op("deref")):
        return expr.args[0].args[0]
    elif (expr.is_op("deref") and expr.args[0].is_op("addr")):
        return expr.args[0].args[0]
    elif (expr.is_op("field") and expr.args[0].is_op("deref")):
        return ExprOp("->", expr.args[0].args[0], expr.args[1])
    return expr
示例#29
0
文件: sem.py 项目: manwefm/miasm
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
示例#30
0
文件: sem.py 项目: manwefm/miasm
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