Пример #1
0
def get_mem_access(mem):
    updt = None
    if isinstance(mem, ExprOp):
        if mem.op == 'preinc':
            addr = mem.args[0] + mem.args[1]
        elif mem.op == 'segm':
            base = mem.args[0]
            op, (reg, shift) = mem.args[1].op, mem.args[1].args
            if op == 'SXTW':
                off = reg.signExtend(base.size) << shift.zeroExtend(base.size)
                addr = base + off
            elif op == 'UXTW':
                off = reg.zeroExtend(base.size) << shift.zeroExtend(base.size)
                addr = base + off
            elif op == 'LSL':
                if isinstance(shift, ExprInt) and int(shift) == 0:
                    addr = base + reg.zeroExtend(base.size)
                else:
                    addr = base + \
                        (reg.zeroExtend(base.size)
                         << shift.zeroExtend(base.size))
            else:
                raise NotImplementedError('bad op')
        elif mem.op == "postinc":
            addr, off = mem.args
            updt = ExprAff(addr, addr + off)
        elif mem.op == "preinc_wb":
            base, off = mem.args
            addr = base + off
            updt = ExprAff(base, base + off)
        else:
            raise NotImplementedError('bad op')
    else:
        raise NotImplementedError('bad op')
    return addr, updt
Пример #2
0
def ands(ir, instr, arg1, arg2, arg3):
    e = []
    arg3 = extend_arg(arg2, arg3)
    res = arg2 & arg3

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

    e.append(ExprAff(arg1, res))
    return e, []
Пример #3
0
def ldp(ir, instr, arg1, arg2, arg3):
    e = []
    addr, updt = get_mem_access(arg3)
    e.append(ExprAff(arg1, ExprMem(addr, arg1.size)))
    e.append(
        ExprAff(arg2,
                ExprMem(addr + ExprInt(arg1.size / 8, addr.size), arg2.size)))
    if updt:
        e.append(updt)
    return e, []
Пример #4
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)),
         ])
     ]
Пример #5
0
def movk(ir, instr, arg1, arg2):
    e = []
    if isinstance(arg2, ExprOp):
        assert (arg2.op == 'slice_at' and isinstance(arg2.args[0], ExprInt)
                and isinstance(arg2.args[1], ExprInt))
        value, shift = int(arg2.args[0].arg), int(arg2.args[1])
        e.append(ExprAff(arg1[shift:shift + 16], ExprInt(value, 16)))
    else:
        e.append(ExprAff(arg1[:16], ExprInt(int(arg2), 16)))

    return e, []
Пример #6
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]
Пример #7
0
 def call_effects(self, ad, instr):
     print hex(instr.offset), instr
     stk_before = idc.GetSpd(instr.offset)
     stk_after = idc.GetSpd(instr.offset + instr.l)
     stk_diff = stk_after - stk_before
     print hex(stk_diff)
     call_assignblk = AssignBlock([
         ExprAff(self.ret_reg, ExprOp('call_func_ret', ad)),
         ExprAff(self.sp, self.sp + ExprInt(stk_diff, self.sp.size))
     ], instr)
     return [call_assignblk], []
Пример #8
0
def bics(ir, instr, arg1, arg2, arg3):
    e = []
    tmp1, tmp2 = arg2, (~extend_arg(arg2, arg3))

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

    e.append(ExprAff(arg1, res))

    e += null_flag_co()
    return e, []
Пример #9
0
 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
                        )]
Пример #10
0
def msr(ir, instr, arg1, arg2, arg3, arg4, arg5):

    e = []
    if arg1.is_int(3) and arg2.is_id("c4") and arg3.is_id(
            "c2") and arg4.is_int(0):
        e.append(ExprAff(nf, arg5[31:32]))
        e.append(ExprAff(zf, arg5[30:31]))
        e.append(ExprAff(cf, arg5[29:30]))
        e.append(ExprAff(of, arg5[28:29]))
    else:
        raise NotImplementedError("MSR not implemented")
    return e, []
Пример #11
0
def bfm(ir, instr, arg1, arg2, arg3, arg4):
    e = []
    rim, sim = int(arg3.arg), int(arg4) + 1
    if sim > rim:
        res = arg2[rim:sim]
        e.append(ExprAff(arg1[:sim - rim], res))
    else:
        shift_i = arg2.size - rim
        shift = ExprInt(shift_i, arg2.size)
        res = arg2[:sim]
        e.append(ExprAff(arg1[shift_i:shift_i + sim], res))
    return e, []
Пример #12
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)),
             ])]
Пример #13
0
def ldrs_size(ir, instr, arg1, arg2, size):
    e = []
    addr, updt = get_mem_access(arg2)
    e.append(ExprAff(arg1, ExprMem(addr, size).signExtend(arg1.size)))
    if updt:
        e.append(updt)
    return e, []
Пример #14
0
    def post_add_asmblock_to_ircfg(self, block, ircfg, ir_blocks):
        IntermediateRepresentation.post_add_asmblock_to_ircfg(self, block, ircfg, ir_blocks)
        new_irblocks = []
        for irb in ir_blocks:
            pc_val = None
            lr_val = None
            for assignblk in irb:
                pc_val = assignblk.get(self.arch.regs.PC, pc_val)
                lr_val = assignblk.get(self.arch.regs.RA, lr_val)

            if pc_val is None or lr_val is None:
                new_irblocks.append(irb)
                continue
            if lr_val.is_loc():
                offset = self.loc_db.get_location_offset(lr_val.loc_key)
                if offset is not None:
                    lr_val = ExprInt(offset, 32)
            if not lr_val.is_int():
                continue

            instr = block.lines[-2]
            if int(lr_val) != instr.offset + 8:
                raise ValueError("Wrong arg")

            # CALL
            lbl = block.get_next()
            new_lbl = self.gen_label()
            call_assignblks, extra_irblocks = self.call_effects(pc_val, instr)
            ir_blocks += extra_irblocks
            irs.append(AssignBlock([ExprAff(self.IRDst,
                                            ExprId(lbl, size=self.pc.size))],
                                   instr))
            new_irblocks.append(IRBlock(new_lbl, call_assignblks))
            new_irblocks.append(irb.set_dst(ExprId(new_lbl, size=self.pc.size)))
        return new_irblocks
Пример #15
0
def strh(ir, instr, arg1, arg2):
    e = []
    addr, updt = get_mem_access(arg2)
    e.append(ExprAff(ExprMem(addr, 16), arg1[:16]))
    if updt:
        e.append(updt)
    return e, []
Пример #16
0
def l_str(ir, instr, arg1, arg2):
    e = []
    addr, updt = get_mem_access(arg2)
    e.append(ExprAff(ExprMem(addr, arg1.size), arg1))
    if updt:
        e.append(updt)
    return e, []
Пример #17
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], []
Пример #18
0
    def post_add_bloc(self, block, ir_blocks):
        IntermediateRepresentation.post_add_bloc(self, block, ir_blocks)
        for irb in ir_blocks:
            pc_val = None
            lr_val = None
            for assignblk in irb.irs:
                pc_val = assignblk.get(self.arch.regs.PC, pc_val)
                lr_val = assignblk.get(self.arch.regs.RA, lr_val)

            if pc_val is None or lr_val is None:
                continue
            if not expr_is_int_or_label(lr_val):
                continue
            if expr_is_label(lr_val):
                lr_val = ExprInt32(lr_val.name.offset)

            line = block.lines[-2]
            if lr_val.arg != line.offset + 8:
                raise ValueError("Wrong arg")

            # CALL
            lbl = block.get_next()
            new_lbl = self.gen_label()
            irs = self.call_effects(pc_val, line)
            irs.append(AssignBlock([ExprAff(self.IRDst,
                                            ExprId(lbl, size=self.pc.size))]))
            nblock = IRBlock(new_lbl, irs)
            nblock.lines = [line] * len(irs)
            self.blocks[new_lbl] = nblock
            irb.dst = ExprId(new_lbl, size=self.pc.size)
Пример #19
0
    def _gen_path_constraints(self, translator, expr, expected):
        """Generate path constraint from @expr. Handle special case with
        generated loc_keys
        """
        out = []
        expected = self._ira.loc_db.canonize_to_exprloc(expected)
        expected_is_loc_key = expected.is_loc()
        for consval in possible_values(expr):
            value = self._ira.loc_db.canonize_to_exprloc(consval.value)
            if expected_is_loc_key and value != expected:
                continue
            if not expected_is_loc_key and value.is_loc_key():
                continue

            conds = z3.And(*[
                translator.from_expr(cond.to_constraint())
                for cond in consval.constraints
            ])
            if expected != value:
                conds = z3.And(conds,
                               translator.from_expr(ExprAff(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
Пример #20
0
def m2instruction_to_r2esil(instruction):
    """Convert a miasm2 instruction to a radare2 ESIL"""

    # Get the IR
    try:
        machine = miasm_machine()
        ir = machine.ir()
        iir, eiir = ir.get_ir(instruction)
    except:
        iir, eiir = [], []

    # Remove IRDst
    for i in iir:
        if isinstance(i, ExprAff) and isinstance(i.dst, ExprId) \
           and i.dst.name == "IRDst":
            iir.remove(i)

    # Convert IRs
    result = list()

    if iir:
        result += [m2expr_to_r2esil(ir) for ir in m2_filter_IRDst(iir)]

    for irbloc in eiir:
        for ir_list in irbloc.irs:
            aff = (ExprAff(dst, src) for dst, src in ir_list.iteritems())
            result += (m2expr_to_r2esil(ir) for ir in m2_filter_IRDst(aff))

    if not len(result):
        return None

    return ",".join(result)
Пример #21
0
    def post_add_block(self, block, ir_blocks):
        IntermediateRepresentation.post_add_block(self, block, ir_blocks)
        new_irblocks = []
        for irb in ir_blocks:
            pc_val = None
            lr_val = None
            for assignblk in irb.irs:
                pc_val = assignblk.get(self.arch.regs.PC, pc_val)
                lr_val = assignblk.get(self.arch.regs.RA, lr_val)

            if pc_val is None or lr_val is None:
                new_irblocks.append(irb)
                continue
            if not expr_is_int_or_label(lr_val):
                new_irblocks.append(irb)
                continue
            if expr_is_label(lr_val):
                lr_val = ExprInt(lr_val.name.offset, 32)

            instr = block.lines[-2]
            if lr_val.arg != instr.offset + 8:
                raise ValueError("Wrong arg")

            # CALL
            lbl = block.get_next()
            new_lbl = self.gen_label()
            irs = self.call_effects(pc_val, instr)
            irs.append(
                AssignBlock(
                    [ExprAff(self.IRDst, ExprId(lbl, size=self.pc.size))],
                    instr))
            new_irblocks.append(IRBlock(new_lbl, irs))
            new_irblocks.append(irb.set_dst(ExprId(new_lbl,
                                                   size=self.pc.size)))
        return new_irblocks
Пример #22
0
    def post_add_bloc(self, bloc, ir_blocs):
        ir.post_add_bloc(self, bloc, ir_blocs)
        if not bloc.lines:
            return
        l = bloc.lines[-1]
        sub_call_dst = None
        if not l.is_subcall():
            return
        sub_call_dst = l.args[0]
        if expr_is_label(sub_call_dst):
            sub_call_dst = sub_call_dst.name
        for irb in ir_blocs:
            l = irb.lines[-1]
            sub_call_dst = None
            if not l.is_subcall():
                continue
            sub_call_dst = l.args[0]
            if expr_is_label(sub_call_dst):
                sub_call_dst = sub_call_dst.name
            lbl = bloc.get_next()
            new_lbl = self.gen_label()
            irs = self.call_effects(l.args[0])
            irs.append(
                AssignBlock(
                    [ExprAff(self.IRDst, ExprId(lbl, size=self.pc.size))]))

            nbloc = irbloc(new_lbl, irs)
            nbloc.lines = [l] * len(irs)
            self.blocs[new_lbl] = nbloc
            irb.dst = ExprId(new_lbl, size=self.pc.size)
        return
Пример #23
0
 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
Пример #24
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 = ExprAff(PC, reg_or_imm)
    else:
        # PC <- PC31..28||0000||(target24)23..1||0
        new_PC = ExprAff(
            PC,
            ExprOp("+", ExprOp("&", PC, ExprInt(0xF0000000, 32)), reg_or_imm))

    return [new_PC, ExprAff(ir.IRDst, new_PC)], []
Пример #25
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 += [ExprAff(nf, ExprOp("FLAG_SIGN_SUBWC", arg1, arg2, arg3))]
    return e
Пример #26
0
 def call_effects(self, ad):
     return [
         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)),
         ])
     ]
Пример #27
0
def cset(ir, instr, arg1, arg2):
    e = []
    cond_expr = cond2expr[arg2.name]
    e.append(
        ExprAff(
            arg1,
            ExprCond(cond_expr, ExprInt(1, arg1.size), ExprInt(0, arg1.size))))
    return e, []
Пример #28
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 += [ExprAff(nf, ExprOp("FLAG_SIGN_SUB", arg1, arg2))]
    return e
Пример #29
0
def sbcs(ir, instr, arg1, arg2, arg3):
    arg3 = extend_arg(arg2, arg3)
    e = []
    r = arg2 - (arg3 + (~cf).zeroExtend(arg3.size))
    e.append(ExprAff(arg1, r))
    e += update_flag_arith_subwc_zn(arg2, arg3, ~cf)
    e += update_flag_arith_subwc_co(arg2, arg3, ~cf)
    return e, []
Пример #30
0
def adcs(ir, instr, arg1, arg2, arg3):
    arg3 = extend_arg(arg2, arg3)
    e = []
    r = arg2 + arg3 + cf.zeroExtend(arg3.size)
    e.append(ExprAff(arg1, r))
    e += update_flag_arith_addwc_zn(arg2, arg3, cf)
    e += update_flag_arith_addwc_co(arg2, arg3, cf)
    return e, []