diff options
Diffstat (limited to 'miasm2/arch')
| -rw-r--r-- | miasm2/arch/aarch64/arch.py | 8 | ||||
| -rw-r--r-- | miasm2/arch/aarch64/regs.py | 3 | ||||
| -rw-r--r-- | miasm2/arch/aarch64/sem.py | 535 | ||||
| -rw-r--r-- | miasm2/arch/arm/jit.py | 10 | ||||
| -rw-r--r-- | miasm2/arch/arm/sem.py | 376 | ||||
| -rw-r--r-- | miasm2/arch/mep/arch.py | 5 | ||||
| -rw-r--r-- | miasm2/arch/x86/sem.py | 484 |
7 files changed, 1018 insertions, 403 deletions
diff --git a/miasm2/arch/aarch64/arch.py b/miasm2/arch/aarch64/arch.py index 529621c4..8cb681f6 100644 --- a/miasm2/arch/aarch64/arch.py +++ b/miasm2/arch/aarch64/arch.py @@ -1839,6 +1839,14 @@ aarch64op("bics", [sf, bs('11'), bs('01010'), shift, bs('1'), rm_sft, imm6, rn, aarch64op("mov", [sf, bs('01'), bs('01010'), bs('00'), bs('0'), rmz, bs('000000'), bs('11111'), rd], [rd, rmz], alias=True) +aarch64op("adc", [sf, bs('00'), bs('11010000'), rm, bs('000000'), rn, rd], [rd, rn, rm]) +aarch64op("adcs", [sf, bs('01'), bs('11010000'), rm, bs('000000'), rn, rd], [rd, rn, rm]) + + +aarch64op("sbc", [sf, bs('10'), bs('11010000'), rm, bs('000000'), rn, rd], [rd, rn, rm]) +aarch64op("sbcs", [sf, bs('11'), bs('11010000'), rm, bs('000000'), rn, rd], [rd, rn, rm]) + + bcond = bs_mod_name(l=4, fname='cond', mn_mod=['EQ', 'NE', 'CS', 'CC', 'MI', 'PL', 'VS', 'VC', diff --git a/miasm2/arch/aarch64/regs.py b/miasm2/arch/aarch64/regs.py index c9da0653..85c8425a 100644 --- a/miasm2/arch/aarch64/regs.py +++ b/miasm2/arch/aarch64/regs.py @@ -1,6 +1,7 @@ #-*- coding:utf-8 -*- -from miasm2.expression.expression import * +from miasm2.expression.expression import ExprId, ExprInt, ExprLoc, ExprMem, \ + ExprSlice, ExprCond, ExprCompose, ExprOp from miasm2.core.cpu import gen_reg, gen_regs exception_flags = ExprId('exception_flags', 32) diff --git a/miasm2/arch/aarch64/sem.py b/miasm2/arch/aarch64/sem.py index 646065f4..c8077ebf 100644 --- a/miasm2/arch/aarch64/sem.py +++ b/miasm2/arch/aarch64/sem.py @@ -1,4 +1,5 @@ -from miasm2.expression import expression as m2_expr +from miasm2.expression.expression import ExprId, ExprInt, ExprLoc, ExprMem, \ + ExprSlice, ExprCond, ExprCompose, ExprOp, ExprAff from miasm2.ir.ir import IntermediateRepresentation, IRBlock, AssignBlock from miasm2.arch.aarch64.arch import mn_aarch64, conds_expr, replace_regs from miasm2.arch.aarch64.regs import * @@ -10,11 +11,20 @@ from miasm2.jitter.csts import EXCEPT_DIV_BY_ZERO, EXCEPT_INT_XX def update_flag_zf(a): - return [m2_expr.ExprAff(zf, m2_expr.ExprCond(a, m2_expr.ExprInt(0, 1), m2_expr.ExprInt(1, 1)))] + return [ExprAff(zf, ExprOp("FLAG_EQ", a))] -def update_flag_nf(a): - return [m2_expr.ExprAff(nf, a.msb())] +def update_flag_zf_eq(a, b): + return [ExprAff(zf, ExprOp("FLAG_EQ_CMP", a, b))] + + +def update_flag_nf(arg): + return [ + ExprAff( + nf, + ExprOp("FLAG_SIGN_SUB", arg, ExprInt(0, arg.size)) + ) + ] def update_flag_zn(a): @@ -24,103 +34,153 @@ def update_flag_zn(a): return e -def update_flag_logic(a): +def check_ops_msb(a, b, c): + if not a or not b or not c or a != b or a != c: + raise ValueError('bad ops size %s %s %s' % (a, b, c)) + + +def update_flag_add_cf(op1, op2): + "Compute cf in @op1 + @op2" + return [ExprAff(cf, ExprOp("FLAG_ADD_CF", op1, op2))] + + +def update_flag_add_of(op1, op2): + "Compute of in @op1 + @op2" + return [ExprAff(of, ExprOp("FLAG_ADD_OF", op1, op2))] + + +def update_flag_sub_cf(op1, op2): + "Compote CF in @op1 - @op2" + return [ExprAff(cf, ExprOp("FLAG_SUB_CF", op1, op2) ^ ExprInt(1, 1))] + + +def update_flag_sub_of(op1, op2): + "Compote OF in @op1 - @op2" + return [ExprAff(of, ExprOp("FLAG_SUB_OF", op1, op2))] + + +def update_flag_arith_add_co(arg1, arg2): e = [] - e += update_flag_zn(a) - # XXX TODO: set cf if ROT imm in argument - # e.append(m2_expr.ExprAff(cf, m2_expr.ExprInt(0, 1))) + e += update_flag_add_cf(arg1, arg2) + e += update_flag_add_of(arg1, arg2) return e -def update_flag_arith(a): +def update_flag_arith_add_zn(arg1, arg2): + """ + Compute zf and nf flags for (arg1 + arg2) + """ e = [] - e += update_flag_zn(a) + e += update_flag_zf_eq(arg1, -arg2) + e += [ExprAff(nf, ExprOp("FLAG_SIGN_SUB", arg1, -arg2))] return e -def check_ops_msb(a, b, c): - if not a or not b or not c or a != b or a != c: - raise ValueError('bad ops size %s %s %s' % (a, b, c)) +def update_flag_arith_sub_co(arg1, arg2): + """ + Compute cf and of flags for (arg1 - arg2) + """ + e = [] + e += update_flag_sub_cf(arg1, arg2) + e += update_flag_sub_of(arg1, arg2) + return e -def arith_flag(a, b, c): - a_s, b_s, c_s = a.size, b.size, c.size - check_ops_msb(a_s, b_s, c_s) - a_s, b_s, c_s = a.msb(), b.msb(), c.msb() - return a_s, b_s, c_s +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 -# checked: ok for adc add because b & c before +cf -def update_flag_add_cf(op1, op2, res): - "Compute cf in @res = @op1 + @op2" - return m2_expr.ExprAff(cf, (((op1 ^ op2) ^ res) ^ ((op1 ^ res) & (~(op1 ^ op2)))).msb()) +def update_flag_zfaddwc_eq(arg1, arg2, arg3): + return [ExprAff(zf, ExprOp("FLAG_EQ_ADDWC", arg1, arg2, arg3))] -def update_flag_add_of(op1, op2, res): - "Compute of in @res = @op1 + @op2" - return m2_expr.ExprAff(of, (((op1 ^ res) & (~(op1 ^ op2)))).msb()) +def update_flag_zfsubwc_eq(arg1, arg2, arg3): + return [ExprAff(zf, ExprOp("FLAG_EQ_SUBWC", arg1, arg2, arg3))] -# checked: ok for sbb add because b & c before +cf -def update_flag_sub_cf(op1, op2, res): - "Compote CF in @res = @op1 - @op2" - return m2_expr.ExprAff(cf, - ((((op1 ^ op2) ^ res) ^ ((op1 ^ res) & (op1 ^ op2))).msb()) ^ m2_expr.ExprInt(1, 1)) +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 += [ExprAff(nf, ExprOp("FLAG_SIGN_ADDWC", arg1, arg2, arg3))] + return e -def update_flag_sub_of(op1, op2, res): - "Compote OF in @res = @op1 - @op2" - return m2_expr.ExprAff(of, (((op1 ^ res) & (op1 ^ op2))).msb()) +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 -# clearing cv flags for bics (see C5.6.25) +def update_flag_addwc_cf(op1, op2, op3): + "Compute cf in @res = @op1 + @op2 + @op3" + return [ExprAff(cf, ExprOp("FLAG_ADDWC_CF", op1, op2, op3))] -def update_flag_bics (): - "Clear CF and OF" - return [ExprAff(cf, ExprInt (0,1)), ExprAff(of, ExprInt (0,1))] -# z = x+y (+cf?) +def update_flag_addwc_of(op1, op2, op3): + "Compute of in @res = @op1 + @op2 + @op3" + return [ExprAff(of, ExprOp("FLAG_ADDWC_OF", op1, op2, op3))] -def update_flag_add(x, y, z): +def update_flag_arith_addwc_co(arg1, arg2, arg3): e = [] - e.append(update_flag_add_cf(x, y, z)) - e.append(update_flag_add_of(x, y, z)) + e += update_flag_addwc_cf(arg1, arg2, arg3) + e += update_flag_addwc_of(arg1, arg2, arg3) return e -# z = x-y (+cf?) -def update_flag_sub(x, y, z): +def update_flag_subwc_cf(op1, op2, op3): + "Compute cf in @res = @op1 + @op2 + @op3" + return [ExprAff(cf, ExprOp("FLAG_SUBWC_CF", op1, op2, op3) ^ ExprInt(1, 1))] + + +def update_flag_subwc_of(op1, op2, op3): + "Compute of in @res = @op1 + @op2 + @op3" + return [ExprAff(of, ExprOp("FLAG_SUBWC_OF", op1, op2, op3))] + + +def update_flag_arith_subwc_co(arg1, arg2, arg3): e = [] - e.append(update_flag_sub_cf(x, y, z)) - e.append(update_flag_sub_of(x, y, z)) + e += update_flag_subwc_cf(arg1, arg2, arg3) + e += update_flag_subwc_of(arg1, arg2, arg3) return e -cond2expr = {'EQ': zf, - 'NE': zf ^ m2_expr.ExprInt(1, 1), - 'CS': cf, - 'CC': cf ^ m2_expr.ExprInt(1, 1), - 'MI': nf, - 'PL': nf ^ m2_expr.ExprInt(1, 1), - 'VS': of, - 'VC': of ^ m2_expr.ExprInt(1, 1), - 'HI': cf & (zf ^ m2_expr.ExprInt(1, 1)), - 'LS': (cf ^ m2_expr.ExprInt(1, 1)) | zf, - 'GE': nf ^ of ^ m2_expr.ExprInt(1, 1), - 'LT': nf ^ of, - 'GT': ((zf ^ m2_expr.ExprInt(1, 1)) & - (nf ^ of ^ m2_expr.ExprInt(1, 1))), - 'LE': zf | (nf ^ of), - 'AL': m2_expr.ExprInt(1, 1), - 'NV': m2_expr.ExprInt(0, 1) +cond2expr = {'EQ': ExprOp("CC_EQ", zf), + 'NE': ExprOp("CC_NE", zf), + 'CS': ExprOp("CC_U>=", cf ^ ExprInt(1, 1)), # inv cf + 'CC': ExprOp("CC_U<", cf ^ ExprInt(1, 1)), # inv cf + 'MI': ExprOp("CC_NEG", nf), + 'PL': ExprOp("CC_POS", nf), + 'VS': ExprOp("CC_sOVR", of), + 'VC': ExprOp("CC_sNOOVR", of), + 'HI': ExprOp("CC_U>", cf ^ ExprInt(1, 1), zf), # inv cf + 'LS': ExprOp("CC_U<=", cf ^ ExprInt(1, 1), zf), # inv cf + 'GE': ExprOp("CC_S>=", nf, of), + 'LT': ExprOp("CC_S<", nf, of), + 'GT': ExprOp("CC_S>", nf, of, zf), + 'LE': ExprOp("CC_S<=", nf, of, zf), + 'AL': ExprInt(1, 1), + 'NV': ExprInt(0, 1) } def extend_arg(dst, arg): - if not isinstance(arg, m2_expr.ExprOp): + if not isinstance(arg, ExprOp): return arg op, (reg, shift) = arg.op, arg.args @@ -156,7 +216,7 @@ def extend_arg(dst, arg): raise NotImplementedError('Unknown shifter operator') out = ExprOp(op, base, (shift.zeroExtend(dst.size) - & m2_expr.ExprInt(dst.size - 1, dst.size))) + & ExprInt(dst.size - 1, dst.size))) return out @@ -169,7 +229,7 @@ ctx = {"PC": PC, "of": of, "cond2expr": cond2expr, "extend_arg": extend_arg, - "m2_expr":m2_expr, + "ExprId":ExprId, "exception_flags": exception_flags, "interrupt_num": interrupt_num, "EXCEPT_DIV_BY_ZERO": EXCEPT_DIV_BY_ZERO, @@ -228,9 +288,14 @@ def bic(arg1, arg2, arg3): def bics(ir, instr, arg1, arg2, arg3): e = [] - arg1 = arg2 & (~extend_arg(arg2, arg3)) - e += update_flag_logic (arg1) - e += update_flag_bics () + 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, [] @@ -243,9 +308,12 @@ def adds(ir, instr, arg1, arg2, arg3): e = [] arg3 = extend_arg(arg2, arg3) res = arg2 + arg3 - e += update_flag_arith(res) - e += update_flag_add(arg2, arg3, res) - e.append(m2_expr.ExprAff(arg1, res)) + + e += update_flag_arith_add_zn(arg2, arg3) + e += update_flag_arith_add_co(arg2, arg3) + + e.append(ExprAff(arg1, res)) + return e, [] @@ -253,18 +321,22 @@ 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)) + + + e += update_flag_arith_sub_zn(arg2, arg3) + e += update_flag_arith_sub_co(arg2, arg3) + + e.append(ExprAff(arg1, res)) return e, [] def cmp(ir, instr, arg1, arg2): e = [] arg2 = extend_arg(arg1, arg2) - res = arg1 - arg2 - e += update_flag_arith(res) - e += update_flag_sub(arg1, arg2, res) + + e += update_flag_arith_sub_zn(arg1, arg2) + e += update_flag_arith_sub_co(arg1, arg2) + return e, [] @@ -272,8 +344,11 @@ def cmn(ir, instr, arg1, arg2): e = [] arg2 = extend_arg(arg1, arg2) res = arg1 + arg2 - e += update_flag_arith(res) - e += update_flag_add(arg1, arg2, res) + + + e += update_flag_arith_add_zn(arg1, arg2) + e += update_flag_arith_add_co(arg1, arg2) + return e, [] @@ -281,32 +356,38 @@ 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)) + + e += [ExprAff(zf, ExprOp('FLAG_EQ_AND', arg2, arg3))] + e += update_flag_nf(res) + + e.append(ExprAff(arg1, res)) return e, [] def tst(ir, instr, arg1, arg2): e = [] arg2 = extend_arg(arg1, arg2) res = arg1 & arg2 - e += update_flag_logic(res) + + e += [ExprAff(zf, ExprOp('FLAG_EQ_AND', arg1, arg2))] + e += update_flag_nf(res) + return e, [] @sbuild.parse def lsl(arg1, arg2, arg3): - arg1 = arg2 << (arg3 & m2_expr.ExprInt(arg3.size - 1, arg3.size)) + arg1 = arg2 << (arg3 & ExprInt(arg3.size - 1, arg3.size)) @sbuild.parse def lsr(arg1, arg2, arg3): - arg1 = arg2 >> (arg3 & m2_expr.ExprInt(arg3.size - 1, arg3.size)) + arg1 = arg2 >> (arg3 & ExprInt(arg3.size - 1, arg3.size)) @sbuild.parse def asr(arg1, arg2, arg3): - arg1 = m2_expr.ExprOp( - 'a>>', arg2, (arg3 & m2_expr.ExprInt(arg3.size - 1, arg3.size))) + arg1 = ExprOp( + 'a>>', arg2, (arg3 & ExprInt(arg3.size - 1, arg3.size))) @sbuild.parse @@ -316,15 +397,15 @@ def mov(arg1, arg2): def movk(ir, instr, arg1, arg2): e = [] - if isinstance(arg2, m2_expr.ExprOp): + if isinstance(arg2, ExprOp): assert(arg2.op == 'slice_at' and - isinstance(arg2.args[0], m2_expr.ExprInt) and - isinstance(arg2.args[1], m2_expr.ExprInt)) + isinstance(arg2.args[0], ExprInt) and + isinstance(arg2.args[1], ExprInt)) value, shift = int(arg2.args[0].arg), int(arg2.args[1]) e.append( - m2_expr.ExprAff(arg1[shift:shift + 16], m2_expr.ExprInt(value, 16))) + ExprAff(arg1[shift:shift + 16], ExprInt(value, 16))) else: - e.append(m2_expr.ExprAff(arg1[:16], m2_expr.ExprInt(int(arg2), 16))) + e.append(ExprAff(arg1[:16], ExprInt(int(arg2), 16))) return e, [] @@ -343,7 +424,7 @@ def movn(arg1, arg2): def bl(arg1): PC = arg1 ir.IRDst = arg1 - LR = m2_expr.ExprInt(instr.offset + instr.l, 64) + LR = ExprInt(instr.offset + instr.l, 64) @sbuild.parse def csel(arg1, arg2, arg3, arg4): @@ -353,7 +434,7 @@ def csel(arg1, arg2, arg3, arg4): def ccmp(ir, instr, arg1, arg2, arg3, arg4): e = [] if(arg2.is_int): - arg2=m2_expr.ExprInt(arg2.arg.arg,arg1.size) + arg2=ExprInt(arg2.arg.arg,arg1.size) default_nf = arg3[0:1] default_zf = arg3[1:2] default_cf = arg3[2:3] @@ -365,71 +446,102 @@ def ccmp(ir, instr, arg1, arg2, arg3, arg4): 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, + e.append(ExprAff(nf, ExprCond(cond_expr, new_nf, default_nf))) - e.append(m2_expr.ExprAff(zf, m2_expr.ExprCond(cond_expr, + e.append(ExprAff(zf, ExprCond(cond_expr, new_zf, default_zf))) - e.append(m2_expr.ExprAff(cf, m2_expr.ExprCond(cond_expr, + e.append(ExprAff(cf, ExprCond(cond_expr, new_cf, default_cf))) - e.append(m2_expr.ExprAff(of, m2_expr.ExprCond(cond_expr, + e.append(ExprAff(of, ExprCond(cond_expr, new_of, default_of))) return e, [] - + 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)))) + e.append( + ExprAff( + arg1, + ExprCond( + cond_expr, + arg2, + arg3 + ExprInt(1, arg3.size) + ) + ) + ) return e, [] def csinv(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))) + e.append( + ExprAff( + arg1, + ExprCond( + cond_expr, + arg2, + ~arg3) + ) + ) return e, [] 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))) + e.append( + ExprAff( + arg1, + ExprCond( + cond_expr, + arg2, + -arg3) + ) + ) return e, [] def cset(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)))) + e.append( + ExprAff( + arg1, + ExprCond( + cond_expr, + ExprInt(1, arg1.size), + ExprInt(0, arg1.size) + ) + ) + ) return e, [] 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)))) + e.append( + ExprAff( + arg1, + ExprCond( + cond_expr, + ExprInt(-1, arg1.size), + ExprInt(0, arg1.size) + ) + ) + ) return e, [] def get_mem_access(mem): updt = None - if isinstance(mem, m2_expr.ExprOp): + if isinstance(mem, ExprOp): if mem.op == 'preinc': addr = mem.args[0] + mem.args[1] elif mem.op == 'segm': @@ -442,7 +554,7 @@ def get_mem_access(mem): off = reg.zeroExtend(base.size) << shift.zeroExtend(base.size) addr = base + off elif op == 'LSL': - if isinstance(shift, m2_expr.ExprInt) and int(shift) == 0: + if isinstance(shift, ExprInt) and int(shift) == 0: addr = base + reg.zeroExtend(base.size) else: addr = base + \ @@ -452,11 +564,11 @@ def get_mem_access(mem): raise NotImplementedError('bad op') elif mem.op == "postinc": addr, off = mem.args - updt = m2_expr.ExprAff(addr, addr + off) + updt = ExprAff(addr, addr + off) elif mem.op == "preinc_wb": base, off = mem.args addr = base + off - updt = m2_expr.ExprAff(base, base + off) + updt = ExprAff(base, base + off) else: raise NotImplementedError('bad op') else: @@ -468,7 +580,7 @@ def get_mem_access(mem): def ldr(ir, instr, arg1, arg2): e = [] addr, updt = get_mem_access(arg2) - e.append(m2_expr.ExprAff(arg1, m2_expr.ExprMem(addr, arg1.size))) + e.append(ExprAff(arg1, ExprMem(addr, arg1.size))) if updt: e.append(updt) return e, [] @@ -478,7 +590,7 @@ 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))) + ExprAff(arg1, ExprMem(addr, size).zeroExtend(arg1.size))) if updt: e.append(updt) return e, [] @@ -496,7 +608,7 @@ def ldrs_size(ir, instr, arg1, arg2, size): e = [] addr, updt = get_mem_access(arg2) e.append( - m2_expr.ExprAff(arg1, m2_expr.ExprMem(addr, size).signExtend(arg1.size))) + ExprAff(arg1, ExprMem(addr, size).signExtend(arg1.size))) if updt: e.append(updt) return e, [] @@ -518,7 +630,7 @@ def ldrsw(ir, instr, arg1, arg2): 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)) + e.append(ExprAff(ExprMem(addr, arg1.size), arg1)) if updt: e.append(updt) return e, [] @@ -527,7 +639,7 @@ def l_str(ir, instr, arg1, arg2): def strb(ir, instr, arg1, arg2): e = [] addr, updt = get_mem_access(arg2) - e.append(m2_expr.ExprAff(m2_expr.ExprMem(addr, 8), arg1[:8])) + e.append(ExprAff(ExprMem(addr, 8), arg1[:8])) if updt: e.append(updt) return e, [] @@ -536,7 +648,7 @@ def strb(ir, instr, arg1, arg2): 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])) + e.append(ExprAff(ExprMem(addr, 16), arg1[:16])) if updt: e.append(updt) return e, [] @@ -545,9 +657,9 @@ def strh(ir, instr, arg1, arg2): def stp(ir, instr, arg1, arg2, arg3): e = [] addr, updt = get_mem_access(arg3) - e.append(m2_expr.ExprAff(m2_expr.ExprMem(addr, arg1.size), arg1)) + e.append(ExprAff(ExprMem(addr, arg1.size), arg1)) e.append( - m2_expr.ExprAff(m2_expr.ExprMem(addr + m2_expr.ExprInt(arg1.size / 8, addr.size), arg2.size), arg2)) + ExprAff(ExprMem(addr + ExprInt(arg1.size / 8, addr.size), arg2.size), arg2)) if updt: e.append(updt) return e, [] @@ -556,9 +668,9 @@ def stp(ir, instr, arg1, arg2, arg3): def ldp(ir, instr, arg1, arg2, arg3): e = [] addr, updt = get_mem_access(arg3) - e.append(m2_expr.ExprAff(arg1, m2_expr.ExprMem(addr, arg1.size))) + e.append(ExprAff(arg1, ExprMem(addr, arg1.size))) e.append( - m2_expr.ExprAff(arg2, m2_expr.ExprMem(addr + m2_expr.ExprInt(arg1.size / 8, addr.size), arg2.size))) + ExprAff(arg2, ExprMem(addr + ExprInt(arg1.size / 8, addr.size), arg2.size))) if updt: e.append(updt) return e, [] @@ -570,9 +682,9 @@ def sbfm(ir, instr, arg1, arg2, arg3, arg4): if sim > rim: res = arg2[rim:sim].signExtend(arg1.size) else: - shift = m2_expr.ExprInt(arg2.size - rim, arg2.size) + shift = ExprInt(arg2.size - rim, arg2.size) res = (arg2[:sim].signExtend(arg1.size) << shift) - e.append(m2_expr.ExprAff(arg1, res)) + e.append(ExprAff(arg1, res)) return e, [] @@ -582,9 +694,9 @@ def ubfm(ir, instr, arg1, arg2, arg3, arg4): if sim > rim: res = arg2[rim:sim].zeroExtend(arg1.size) else: - shift = m2_expr.ExprInt(arg2.size - rim, arg2.size) + shift = ExprInt(arg2.size - rim, arg2.size) res = (arg2[:sim].zeroExtend(arg1.size) << shift) - e.append(m2_expr.ExprAff(arg1, res)) + e.append(ExprAff(arg1, res)) return e, [] def bfm(ir, instr, arg1, arg2, arg3, arg4): @@ -592,12 +704,77 @@ def bfm(ir, instr, arg1, arg2, arg3, arg4): rim, sim = int(arg3.arg), int(arg4) + 1 if sim > rim: res = arg2[rim:sim] - e.append(m2_expr.ExprAff(arg1[:sim-rim], res)) + e.append(ExprAff(arg1[:sim-rim], res)) else: shift_i = arg2.size - rim - shift = m2_expr.ExprInt(shift_i, arg2.size) + shift = ExprInt(shift_i, arg2.size) res = arg2[:sim] - e.append(m2_expr.ExprAff(arg1[shift_i:shift_i+sim], res)) + e.append(ExprAff(arg1[shift_i:shift_i+sim], res)) + return e, [] + + + +def mrs(ir, insr, arg1, arg2, arg3, arg4, arg5): + e = [] + if arg2.is_int(3) and arg3.is_id("c4") and arg4.is_id("c2") and arg5.is_int(0): + out = [] + out.append(ExprInt(0x0, 28)) + out.append(of) + out.append(cf) + out.append(zf) + out.append(nf) + e.append(ExprAff(arg1, ExprCompose(*out).zeroExtend(arg1.size))) + else: + raise NotImplementedError("MSR not implemented") + return e, [] + +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("MRS not implemented") + return e, [] + + + +def adc(ir, instr, arg1, arg2, arg3): + arg3 = extend_arg(arg2, arg3) + e = [] + r = arg2 + arg3 + cf.zeroExtend(arg3.size) + e.append(ExprAff(arg1, r)) + return e, [] + + +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, [] + + +def sbc(ir, instr, arg1, arg2, arg3): + arg3 = extend_arg(arg2, arg3) + e = [] + r = arg2 - (arg3 + (~cf).zeroExtend(arg3.size)) + e.append(ExprAff(arg1, r)) + return e, [] + + +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, [] @@ -614,30 +791,30 @@ def msub(arg1, arg2, arg3, arg4): @sbuild.parse def udiv(arg1, arg2, arg3): if arg3: - arg1 = m2_expr.ExprOp('udiv', arg2, arg3) + arg1 = ExprOp('udiv', arg2, arg3) else: - exception_flags = m2_expr.ExprInt(EXCEPT_DIV_BY_ZERO, + exception_flags = ExprInt(EXCEPT_DIV_BY_ZERO, exception_flags.size) @sbuild.parse def cbz(arg1, arg2): - dst = m2_expr.ExprLoc(ir.get_next_loc_key(instr), 64) if arg1 else arg2 + dst = ExprLoc(ir.get_next_loc_key(instr), 64) if arg1 else arg2 PC = dst ir.IRDst = dst @sbuild.parse def cbnz(arg1, arg2): - dst = arg2 if arg1 else m2_expr.ExprLoc(ir.get_next_loc_key(instr), 64) + dst = arg2 if arg1 else ExprLoc(ir.get_next_loc_key(instr), 64) PC = dst ir.IRDst = dst @sbuild.parse def tbz(arg1, arg2, arg3): - bitmask = m2_expr.ExprInt(1, arg1.size) << arg2 - dst = m2_expr.ExprLoc( + bitmask = ExprInt(1, arg1.size) << arg2 + dst = ExprLoc( ir.get_next_loc_key(instr), 64 ) if arg1 & bitmask else arg3 @@ -647,8 +824,8 @@ def tbz(arg1, arg2, arg3): @sbuild.parse def tbnz(arg1, arg2, arg3): - bitmask = m2_expr.ExprInt(1, arg1.size) << arg2 - dst = arg3 if arg1 & bitmask else m2_expr.ExprLoc( + bitmask = ExprInt(1, arg1.size) << arg2 + dst = arg3 if arg1 & bitmask else ExprLoc( ir.get_next_loc_key(instr), 64 ) @@ -658,14 +835,16 @@ def tbnz(arg1, arg2, arg3): @sbuild.parse def b_ne(arg1): - dst = m2_expr.ExprLoc(ir.get_next_loc_key(instr), 64) if zf else arg1 + cond = cond2expr['NE'] + dst = arg1 if cond else ExprLoc(ir.get_next_loc_key(instr), 64) PC = dst ir.IRDst = dst @sbuild.parse def b_eq(arg1): - dst = arg1 if zf else m2_expr.ExprLoc(ir.get_next_loc_key(instr), 64) + cond = cond2expr['EQ'] + dst = arg1 if cond else ExprLoc(ir.get_next_loc_key(instr), 64) PC = dst ir.IRDst = dst @@ -673,7 +852,7 @@ def b_eq(arg1): @sbuild.parse def b_ge(arg1): cond = cond2expr['GE'] - dst = arg1 if cond else m2_expr.ExprLoc(ir.get_next_loc_key(instr), 64) + dst = arg1 if cond else ExprLoc(ir.get_next_loc_key(instr), 64) PC = dst ir.IRDst = dst @@ -681,7 +860,7 @@ def b_ge(arg1): @sbuild.parse def b_gt(arg1): cond = cond2expr['GT'] - dst = arg1 if cond else m2_expr.ExprLoc(ir.get_next_loc_key(instr), 64) + dst = arg1 if cond else ExprLoc(ir.get_next_loc_key(instr), 64) PC = dst ir.IRDst = dst @@ -689,7 +868,7 @@ def b_gt(arg1): @sbuild.parse def b_cc(arg1): cond = cond2expr['CC'] - dst = arg1 if cond else m2_expr.ExprLoc(ir.get_next_loc_key(instr), 64) + dst = arg1 if cond else ExprLoc(ir.get_next_loc_key(instr), 64) PC = dst ir.IRDst = dst @@ -697,7 +876,7 @@ def b_cc(arg1): @sbuild.parse def b_cs(arg1): cond = cond2expr['CS'] - dst = arg1 if cond else m2_expr.ExprLoc(ir.get_next_loc_key(instr), 64) + dst = arg1 if cond else ExprLoc(ir.get_next_loc_key(instr), 64) PC = dst ir.IRDst = dst @@ -705,7 +884,7 @@ def b_cs(arg1): @sbuild.parse def b_hi(arg1): cond = cond2expr['HI'] - dst = arg1 if cond else m2_expr.ExprLoc(ir.get_next_loc_key(instr), 64) + dst = arg1 if cond else ExprLoc(ir.get_next_loc_key(instr), 64) PC = dst ir.IRDst = dst @@ -713,7 +892,7 @@ def b_hi(arg1): @sbuild.parse def b_le(arg1): cond = cond2expr['LE'] - dst = arg1 if cond else m2_expr.ExprLoc(ir.get_next_loc_key(instr), 64) + dst = arg1 if cond else ExprLoc(ir.get_next_loc_key(instr), 64) PC = dst ir.IRDst = dst @@ -721,7 +900,7 @@ def b_le(arg1): @sbuild.parse def b_ls(arg1): cond = cond2expr['LS'] - dst = arg1 if cond else m2_expr.ExprLoc(ir.get_next_loc_key(instr), 64) + dst = arg1 if cond else ExprLoc(ir.get_next_loc_key(instr), 64) PC = dst ir.IRDst = dst @@ -729,7 +908,7 @@ def b_ls(arg1): @sbuild.parse def b_lt(arg1): cond = cond2expr['LT'] - dst = arg1 if cond else m2_expr.ExprLoc(ir.get_next_loc_key(instr), 64) + dst = arg1 if cond else ExprLoc(ir.get_next_loc_key(instr), 64) PC = dst ir.IRDst = dst @@ -742,7 +921,7 @@ def ret(arg1): @sbuild.parse def adrp(arg1, arg2): - arg1 = (PC & m2_expr.ExprInt(0xfffffffffffff000, 64)) + arg2 + arg1 = (PC & ExprInt(0xfffffffffffff000, 64)) + arg2 @sbuild.parse @@ -765,24 +944,34 @@ def br(arg1): def blr(arg1): PC = arg1 ir.IRDst = arg1 - LR = m2_expr.ExprLoc(ir.get_next_loc_key(instr), 64) + LR = ExprLoc(ir.get_next_loc_key(instr), 64) @sbuild.parse def nop(): """Do nothing""" +def rev(ir, instr, arg1, arg2): + out = [] + for i in xrange(0, arg2.size, 8): + out.append(arg2[i:i+8]) + out.reverse() + e = [] + result = ExprCompose(*out) + e.append(ExprAff(arg1, result)) + return e, [] + @sbuild.parse def extr(arg1, arg2, arg3, arg4): - compose = m2_expr.ExprCompose(arg2, arg3) + compose = ExprCompose(arg2, arg3) arg1 = compose[int(arg4.arg):int(arg4)+arg1.size] @sbuild.parse def svc(arg1): - exception_flags = m2_expr.ExprInt(EXCEPT_INT_XX, exception_flags.size) - interrupt_num = m2_expr.ExprInt(int(arg1), interrupt_num.size) + exception_flags = ExprInt(EXCEPT_INT_XX, exception_flags.size) + interrupt_num = ExprInt(int(arg1), interrupt_num.size) mnemo_func = sbuild.functions mnemo_func.update({ @@ -847,6 +1036,16 @@ mnemo_func.update({ 'ubfm': ubfm, 'extr': extr, + 'rev': rev, + + 'msr': msr, + 'mrs': mrs, + + 'adc': adc, + 'adcs': adcs, + 'sbc': sbc, + 'sbcs': sbcs, + }) @@ -869,15 +1068,15 @@ class ir_aarch64l(IntermediateRepresentation): IntermediateRepresentation.__init__(self, mn_aarch64, "l", loc_db) self.pc = PC self.sp = SP - self.IRDst = m2_expr.ExprId('IRDst', 64) + self.IRDst = ExprId('IRDst', 64) self.addrsize = 64 def get_ir(self, instr): args = instr.args - if len(args) and isinstance(args[-1], m2_expr.ExprOp): + if len(args) and isinstance(args[-1], ExprOp): if (args[-1].op in ['<<', '>>', '<<a', 'a>>', '<<<', '>>>'] and - isinstance(args[-1].args[-1], m2_expr.ExprId)): - args[-1] = m2_expr.ExprOp(args[-1].op, + 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) @@ -891,7 +1090,7 @@ class ir_aarch64l(IntermediateRepresentation): def expraff_fix_regs_for_mode(self, e): dst = self.expr_fix_regs_for_mode(e.dst) src = self.expr_fix_regs_for_mode(e.src) - return m2_expr.ExprAff(dst, src) + return ExprAff(dst, src) def irbloc_fix_regs_for_mode(self, irblock, mode=64): irs = [] @@ -901,7 +1100,7 @@ class ir_aarch64l(IntermediateRepresentation): del(new_assignblk[dst]) # Special case for 64 bits: # If destination is a 32 bit reg, zero extend the 64 bit reg - if (isinstance(dst, m2_expr.ExprId) and + if (isinstance(dst, ExprId) and dst.size == 32 and dst in replace_regs): src = src.zeroExtend(64) @@ -915,14 +1114,14 @@ class ir_aarch64l(IntermediateRepresentation): def mod_pc(self, instr, instr_ir, extra_ir): "Replace PC by the instruction's offset" - cur_offset = m2_expr.ExprInt(instr.offset, 64) + cur_offset = 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) + instr_ir[i] = ExprAff(dst, src) for idx, irblock in enumerate(extra_ir): extra_ir[idx] = irblock.modify_exprs(lambda expr: expr.replace_expr(pc_fixed) \ @@ -953,4 +1152,4 @@ class ir_aarch64b(ir_aarch64l): IntermediateRepresentation.__init__(self, mn_aarch64, "b", loc_db) self.pc = PC self.sp = SP - self.IRDst = m2_expr.ExprId('IRDst', 64) + self.IRDst = ExprId('IRDst', 64) diff --git a/miasm2/arch/arm/jit.py b/miasm2/arch/arm/jit.py index 267bcea6..716a8826 100644 --- a/miasm2/arch/arm/jit.py +++ b/miasm2/arch/arm/jit.py @@ -8,6 +8,7 @@ from miasm2.jitter.codegen import CGen from miasm2.expression.expression import ExprId, ExprAff, ExprCond from miasm2.ir.ir import IRBlock, AssignBlock from miasm2.ir.translators.C import TranslatorC +from miasm2.expression.simplifications import expr_simp_high_to_explicit log = logging.getLogger('jit_arm') hnd = logging.StreamHandler() @@ -45,6 +46,15 @@ class arm_CGen(CGen): irblock_head = self.assignblk_to_irbloc(instr, assignblk_head) irblocks = [irblock_head] + assignblks_extra + + # Simplify high level operators + out = [] + for irblock in irblocks: + new_irblock = irblock.simplify(expr_simp_high_to_explicit)[1] + out.append(new_irblock) + irblocks = out + + for irblock in irblocks: assert irblock.dst is not None irblocks_list.append(irblocks) diff --git a/miasm2/arch/arm/sem.py b/miasm2/arch/arm/sem.py index d9c2d6cd..4e99e720 100644 --- a/miasm2/arch/arm/sem.py +++ b/miasm2/arch/arm/sem.py @@ -14,11 +14,20 @@ EXCEPT_PRIV_INSN = (1 << 17) def update_flag_zf(a): - return [ExprAff(zf, ExprCond(a, ExprInt(0, 1), ExprInt(1, 1)))] + return [ExprAff(zf, ExprOp("FLAG_EQ", a))] -def update_flag_nf(a): - return [ExprAff(nf, a.msb())] +def update_flag_zf_eq(a, b): + return [ExprAff(zf, ExprOp("FLAG_EQ_CMP", a, b))] + + +def update_flag_nf(arg): + return [ + ExprAff( + nf, + ExprOp("FLAG_SIGN_SUB", arg, ExprInt(0, arg.size)) + ) + ] def update_flag_zn(a): @@ -28,73 +37,136 @@ def update_flag_zn(a): return e -def update_flag_logic(a): + +# XXX TODO: set cf if ROT imm in argument + + +def check_ops_msb(a, b, c): + if not a or not b or not c or a != b or a != c: + raise ValueError('bad ops size %s %s %s' % (a, b, c)) + +def update_flag_add_cf(op1, op2): + "Compute cf in @op1 + @op2" + return [ExprAff(cf, ExprOp("FLAG_ADD_CF", op1, op2))] + + +def update_flag_add_of(op1, op2): + "Compute of in @op1 + @op2" + return [ExprAff(of, ExprOp("FLAG_ADD_OF", op1, op2))] + + +def update_flag_sub_cf(op1, op2): + "Compote CF in @op1 - @op2" + return [ExprAff(cf, ExprOp("FLAG_SUB_CF", op1, op2) ^ ExprInt(1, 1))] + + +def update_flag_sub_of(op1, op2): + "Compote OF in @op1 - @op2" + return [ExprAff(of, ExprOp("FLAG_SUB_OF", op1, op2))] + + +def update_flag_arith_add_co(arg1, arg2): e = [] - e += update_flag_zn(a) - # XXX TODO: set cf if ROT imm in argument - #e.append(ExprAff(cf, ExprInt(0, 1))) + e += update_flag_add_cf(arg1, arg2) + e += update_flag_add_of(arg1, arg2) return e -def update_flag_arith(a): +def update_flag_arith_add_zn(arg1, arg2): + """ + Compute zf and nf flags for (arg1 + arg2) + """ e = [] - e += update_flag_zn(a) + e += update_flag_zf_eq(arg1, -arg2) + e += [ExprAff(nf, ExprOp("FLAG_SIGN_SUB", arg1, -arg2))] return e -def check_ops_msb(a, b, c): - if not a or not b or not c or a != b or a != c: - raise ValueError('bad ops size %s %s %s' % (a, b, c)) +def update_flag_arith_sub_co(arg1, arg2): + """ + Compute cf and of flags for (arg1 - arg2) + """ + e = [] + e += update_flag_sub_cf(arg1, arg2) + e += update_flag_sub_of(arg1, arg2) + return e + + +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 -def arith_flag(a, b, c): - a_s, b_s, c_s = a.size, b.size, c.size - check_ops_msb(a_s, b_s, c_s) - a_s, b_s, c_s = a.msb(), b.msb(), c.msb() - return a_s, b_s, c_s -# checked: ok for adc add because b & c before +cf -def update_flag_add_cf(op1, op2, res): - "Compute cf in @res = @op1 + @op2" - return ExprAff(cf, (((op1 ^ op2) ^ res) ^ ((op1 ^ res) & (~(op1 ^ op2)))).msb()) +def update_flag_zfaddwc_eq(arg1, arg2, arg3): + return [ExprAff(zf, ExprOp("FLAG_EQ_ADDWC", arg1, arg2, arg3))] +def update_flag_zfsubwc_eq(arg1, arg2, arg3): + return [ExprAff(zf, ExprOp("FLAG_EQ_SUBWC", arg1, arg2, arg3))] + + +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 += [ExprAff(nf, ExprOp("FLAG_SIGN_ADDWC", arg1, arg2, arg3))] + return e -def update_flag_add_of(op1, op2, res): - "Compute of in @res = @op1 + @op2" - return ExprAff(of, (((op1 ^ res) & (~(op1 ^ op2)))).msb()) +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 -# checked: ok for sbb add because b & c before +cf -def update_flag_sub_cf(op1, op2, res): - "Compote CF in @res = @op1 - @op2" - return ExprAff(cf, - ((((op1 ^ op2) ^ res) ^ ((op1 ^ res) & (op1 ^ op2))).msb()) ^ ExprInt(1, 1)) +def update_flag_addwc_cf(op1, op2, op3): + "Compute cf in @res = @op1 + @op2 + @op3" + return [ExprAff(cf, ExprOp("FLAG_ADDWC_CF", op1, op2, op3))] -def update_flag_sub_of(op1, op2, res): - "Compote OF in @res = @op1 - @op2" - return ExprAff(of, (((op1 ^ res) & (op1 ^ op2))).msb()) -# z = x+y (+cf?) +def update_flag_addwc_of(op1, op2, op3): + "Compute of in @res = @op1 + @op2 + @op3" + return [ExprAff(of, ExprOp("FLAG_ADDWC_OF", op1, op2, op3))] -def update_flag_add(x, y, z): +def update_flag_arith_addwc_co(arg1, arg2, arg3): e = [] - e.append(update_flag_add_cf(x, y, z)) - e.append(update_flag_add_of(x, y, z)) + e += update_flag_addwc_cf(arg1, arg2, arg3) + e += update_flag_addwc_of(arg1, arg2, arg3) return e -# z = x-y (+cf?) -def update_flag_sub(x, y, z): +def update_flag_subwc_cf(op1, op2, op3): + "Compute cf in @res = @op1 + @op2 + @op3" + return [ExprAff(cf, ExprOp("FLAG_SUBWC_CF", op1, op2, op3) ^ ExprInt(1, 1))] + + +def update_flag_subwc_of(op1, op2, op3): + "Compute of in @res = @op1 + @op2 + @op3" + return [ExprAff(of, ExprOp("FLAG_SUBWC_OF", op1, op2, op3))] + + +def update_flag_arith_subwc_co(arg1, arg2, arg3): e = [] - e.append(update_flag_sub_cf(x, y, z)) - e.append(update_flag_sub_of(x, y, z)) + e += update_flag_subwc_cf(arg1, arg2, arg3) + e += update_flag_subwc_of(arg1, arg2, arg3) return e + def get_dst(a): if a == PC: return PC @@ -107,10 +179,11 @@ def adc(ir, instr, a, b, c=None): e = [] if c is None: b, c = a, b + arg1, arg2 = b, c r = b + c + cf.zeroExtend(32) if instr.name == 'ADCS' and a != PC: - e += update_flag_arith(r) - e += update_flag_add(b, c, r) + e += update_flag_arith_addwc_zn(arg1, arg2, cf) + e += update_flag_arith_addwc_co(arg1, arg2, cf) e.append(ExprAff(a, r)) dst = get_dst(a) if dst is not None: @@ -122,10 +195,11 @@ def add(ir, instr, a, b, c=None): e = [] if c is None: b, c = a, b + arg1, arg2 = b, c r = b + c if instr.name == 'ADDS' and a != PC: - e += update_flag_arith(r) - e += update_flag_add(b, c, r) + e += update_flag_arith_add_zn(arg1, arg2) + e += update_flag_arith_add_co(arg1, arg2) e.append(ExprAff(a, r)) dst = get_dst(a) if dst is not None: @@ -139,7 +213,9 @@ def l_and(ir, instr, a, b, c=None): b, c = a, b r = b & c if instr.name == 'ANDS' and a != PC: - e += update_flag_logic(r) + e += [ExprAff(zf, ExprOp('FLAG_EQ_AND', b, c))] + e += update_flag_nf(r) + e.append(ExprAff(a, r)) dst = get_dst(a) if dst is not None: @@ -163,9 +239,10 @@ def subs(ir, instr, a, b, c=None): e = [] if c is None: b, c = a, b + arg1, arg2 = b, c r = b - c - e += update_flag_arith(r) - e += update_flag_sub(b, c, r) + e += update_flag_arith_sub_zn(arg1, arg2) + e += update_flag_arith_sub_co(arg1, arg2) e.append(ExprAff(a, r)) dst = get_dst(a) if dst is not None: @@ -189,8 +266,12 @@ def eors(ir, instr, a, b, c=None): e = [] if c is None: b, c = a, b - r = b ^ c - e += update_flag_logic(r) + arg1, arg2 = b, c + r = arg1 ^ arg2 + + e += [ExprAff(zf, ExprOp('FLAG_EQ_CMP', arg1, arg2))] + e += update_flag_nf(r) + e.append(ExprAff(a, r)) dst = get_dst(a) if dst is not None: @@ -214,9 +295,12 @@ def rsbs(ir, instr, a, b, c=None): e = [] if c is None: b, c = a, b - r = c - b - e += update_flag_arith(r) - e += update_flag_sub(c, b, r) + arg1, arg2 = c, b + r = arg1 - arg2 + + e += update_flag_arith_sub_zn(arg1, arg2) + e += update_flag_arith_sub_co(arg1, arg2) + e.append(ExprAff(a, r)) dst = get_dst(a) if dst is not None: @@ -228,7 +312,8 @@ def sbc(ir, instr, a, b, c=None): e = [] if c is None: b, c = a, b - r = (b + cf.zeroExtend(32)) - (c + ExprInt(1, 32)) + arg1, arg2 = b, c + r = arg1 - (arg2 + (~cf).zeroExtend(32)) e.append(ExprAff(a, r)) dst = get_dst(a) if dst is not None: @@ -240,9 +325,12 @@ def sbcs(ir, instr, a, b, c=None): e = [] if c is None: b, c = a, b - r = (b + cf.zeroExtend(32)) - (c + ExprInt(1, 32)) - e += update_flag_arith(r) - e += update_flag_sub(b, c, r) + arg1, arg2 = b, c + r = arg1 - (arg2 + (~cf).zeroExtend(32)) + + e += update_flag_arith_subwc_zn(arg1, arg2, ~cf) + e += update_flag_arith_subwc_co(arg1, arg2, ~cf) + e.append(ExprAff(a, r)) dst = get_dst(a) if dst is not None: @@ -254,7 +342,8 @@ def rsc(ir, instr, a, b, c=None): e = [] if c is None: b, c = a, b - r = (c + cf.zeroExtend(32)) - (b + ExprInt(1, 32)) + arg1, arg2 = c, b + r = arg1 - (arg2 + (~cf).zeroExtend(32)) e.append(ExprAff(a, r)) dst = get_dst(a) if dst is not None: @@ -266,11 +355,14 @@ def rscs(ir, instr, a, b, c=None): e = [] if c is None: b, c = a, b - r = (c + cf.zeroExtend(32)) - (b + ExprInt(1, 32)) - e.append(ExprAff(a, r)) - e += update_flag_arith(r) - e += update_flag_sub(c, b, r) + arg1, arg2 = c, b + r = arg1 - (arg2 + (~cf).zeroExtend(32)) + + e += update_flag_arith_subwc_zn(arg1, arg2, ~cf) + e += update_flag_arith_subwc_co(arg1, arg2, ~cf) + e.append(ExprAff(a, r)) + dst = get_dst(a) if dst is not None: e.append(ExprAff(ir.IRDst, r)) @@ -279,8 +371,12 @@ def rscs(ir, instr, a, b, c=None): def tst(ir, instr, a, b): e = [] - r = a & b - e += update_flag_logic(r) + arg1, arg2 = a, b + r = arg1 & arg2 + + e += [ExprAff(zf, ExprOp('FLAG_EQ_AND', arg1, arg2))] + e += update_flag_nf(r) + return e, [] @@ -288,8 +384,12 @@ def teq(ir, instr, a, b, c=None): e = [] if c is None: b, c = a, b - r = b ^ c - e += update_flag_logic(r) + arg1, arg2 = b, c + r = arg1 ^ arg2 + + e += [ExprAff(zf, ExprOp('FLAG_EQ_CMP', arg1, arg2))] + e += update_flag_nf(r) + return e, [] @@ -297,9 +397,12 @@ def l_cmp(ir, instr, a, b, c=None): e = [] if c is None: b, c = a, b + arg1, arg2 = b, c r = b - c - e += update_flag_arith(r) - e += update_flag_sub(b, c, r) + + e += update_flag_arith_sub_zn(arg1, arg2) + e += update_flag_arith_sub_co(arg1, arg2) + return e, [] @@ -307,9 +410,12 @@ def cmn(ir, instr, a, b, c=None): e = [] if c is None: b, c = a, b + arg1, arg2 = b, c r = b + c - e += update_flag_arith(r) - e += update_flag_add(b, c, r) + + e += update_flag_arith_add_zn(arg1, arg2) + e += update_flag_arith_add_co(arg1, arg2) + return e, [] @@ -341,8 +447,12 @@ def orrs(ir, instr, a, b, c=None): e = [] if c is None: b, c = a, b + arg1, arg2 = b, c r = b | c - e += update_flag_logic(r) + + e += [ExprAff(zf, ExprOp('FLAG_EQ', r))] + e += update_flag_nf(r) + e.append(ExprAff(a, r)) dst = get_dst(a) if dst is not None: @@ -371,7 +481,9 @@ def movs(ir, instr, a, b): e = [] e.append(ExprAff(a, b)) # XXX TODO check - e += update_flag_logic(b) + e += [ExprAff(zf, ExprOp('FLAG_EQ', b))] + e += update_flag_nf(b) + dst = get_dst(a) if dst is not None: e.append(ExprAff(ir.IRDst, b)) @@ -392,13 +504,42 @@ def mvns(ir, instr, a, b): r = b ^ ExprInt(-1, 32) e.append(ExprAff(a, r)) # XXX TODO check - e += update_flag_logic(r) + e += [ExprAff(zf, ExprOp('FLAG_EQ', r))] + e += update_flag_nf(r) + dst = get_dst(a) if dst is not None: e.append(ExprAff(ir.IRDst, r)) return e, [] + +def mrs(ir, instr, a, b): + e = [] + if b.is_id('CPSR_cxsf'): + out = [] + out.append(ExprInt(0x10, 28)) + out.append(of) + out.append(cf) + out.append(zf) + out.append(nf) + e.append(ExprAff(a, ExprCompose(*out))) + else: + raise NotImplementedError("MSR not implemented") + return e, [] + +def msr(ir, instr, a, b): + e = [] + if a.is_id('CPSR_cf'): + e.append(ExprAff(nf, b[31:32])) + e.append(ExprAff(zf, b[30:31])) + e.append(ExprAff(cf, b[29:30])) + e.append(ExprAff(of, b[28:29])) + else: + raise NotImplementedError("MRS not implemented") + return e, [] + + def neg(ir, instr, a, b): e = [] r = - b @@ -427,8 +568,12 @@ def bics(ir, instr, a, b, c=None): e = [] if c is None: b, c = a, b - r = b & (c ^ ExprInt(-1, 32)) - e += update_flag_logic(r) + tmp1, tmp2 = b, ~c + r = tmp1 & tmp2 + + e += [ExprAff(zf, ExprOp('FLAG_EQ_AND', tmp1, tmp2))] + e += update_flag_nf(r) + e.append(ExprAff(a, r)) dst = get_dst(a) if dst is not None: @@ -836,7 +981,10 @@ def lsrs(ir, instr, a, b, c=None): b, c = a, b r = b >> c e.append(ExprAff(a, r)) - e += update_flag_logic(r) + + e += [ExprAff(zf, ExprOp('FLAG_EQ', r))] + e += update_flag_nf(r) + dst = get_dst(a) if dst is not None: e.append(ExprAff(ir.IRDst, r)) @@ -859,7 +1007,10 @@ def asrs(ir, instr, a, b, c=None): b, c = a, b r = ExprOp("a>>", b, c) e.append(ExprAff(a, r)) - e += update_flag_logic(r) + + e += [ExprAff(zf, ExprOp('FLAG_EQ', r))] + e += update_flag_nf(r) + dst = get_dst(a) if dst is not None: e.append(ExprAff(ir.IRDst, r)) @@ -883,7 +1034,10 @@ def lsls(ir, instr, a, b, c=None): b, c = a, b r = b << c e.append(ExprAff(a, r)) - e += update_flag_logic(r) + + e += [ExprAff(zf, ExprOp('FLAG_EQ', r))] + e += update_flag_nf(r) + dst = get_dst(a) if dst is not None: e.append(ExprAff(ir.IRDst, r)) @@ -894,7 +1048,10 @@ def rors(ir, instr, a, b): e = [] r = ExprOp(">>>", a, b) e.append(ExprAff(a, r)) - e += update_flag_logic(r) + + e += [ExprAff(zf, ExprOp('FLAG_EQ', r))] + e += update_flag_nf(r) + dst = get_dst(a) if dst is not None: e.append(ExprAff(ir.IRDst, r)) @@ -1223,31 +1380,46 @@ cond_dct = { cond_dct_inv = dict((name, num) for num, name in cond_dct.iteritems()) -tab_cond = {COND_EQ: zf, - COND_NE: ExprCond(zf, ExprInt(0, 1), ExprInt(1, 1)), - COND_CS: cf, - COND_CC: ExprCond(cf, ExprInt(0, 1), ExprInt(1, 1)), - COND_MI: nf, - COND_PL: ExprCond(nf, ExprInt(0, 1), ExprInt(1, 1)), - COND_VS: of, - COND_VC: ExprCond(of, ExprInt(0, 1), ExprInt(1, 1)), - COND_HI: cf & ExprCond(zf, ExprInt(0, 1), ExprInt(1, 1)), - # COND_HI: cf, - # COND_HI: ExprOp('==', - # ExprOp('|', cf, zf), - # ExprInt(0, 1)), - COND_LS: ExprCond(cf, ExprInt(0, 1), ExprInt(1, 1)) | zf, - COND_GE: ExprCond(nf - of, ExprInt(0, 1), ExprInt(1, 1)), - COND_LT: nf ^ of, - # COND_GT: ExprOp('|', - # ExprOp('==', zf, ExprInt(0, 1)) & (nf | of), - # ExprOp('==', nf, ExprInt(0, 1)) & ExprOp('==', of, ExprInt(0, 1))), - COND_GT: (ExprCond(zf, ExprInt(0, 1), ExprInt(1, 1)) & - ExprCond(nf - of, ExprInt(0, 1), ExprInt(1, 1))), - COND_LE: zf | (nf ^ of), + +""" +Code Meaning (for cmp or subs) Flags Tested +eq Equal. Z==1 +ne Not equal. Z==0 +cs or hs Unsigned higher or same (or carry set). C==1 +cc or lo Unsigned lower (or carry clear). C==0 +mi Negative. The mnemonic stands for "minus". N==1 +pl Positive or zero. The mnemonic stands for "plus". N==0 +vs Signed overflow. The mnemonic stands for "V set". V==1 +vc No signed overflow. The mnemonic stands for "V clear". V==0 +hi Unsigned higher. (C==1) && (Z==0) +ls Unsigned lower or same. (C==0) || (Z==1) +ge Signed greater than or equal. N==V +lt Signed less than. N!=V +gt Signed greater than. (Z==0) && (N==V) +le Signed less than or equal. (Z==1) || (N!=V) +al (or omitted) Always executed. None tested. +""" + +tab_cond = {COND_EQ: ExprOp("CC_EQ", zf), + COND_NE: ExprOp("CC_NE", zf), + COND_CS: ExprOp("CC_U>=", cf ^ ExprInt(1, 1)), # inv cf + COND_CC: ExprOp("CC_U<", cf ^ ExprInt(1, 1)), # inv cf + COND_MI: ExprOp("CC_NEG", nf), + COND_PL: ExprOp("CC_POS", nf), + COND_VS: ExprOp("CC_sOVR", of), + COND_VC: ExprOp("CC_sNOOVR", of), + COND_HI: ExprOp("CC_U>", cf ^ ExprInt(1, 1), zf), # inv cf + COND_LS: ExprOp("CC_U<=", cf ^ ExprInt(1, 1), zf), # inv cf + COND_GE: ExprOp("CC_S>=", nf, of), + COND_LT: ExprOp("CC_S<", nf, of), + COND_GT: ExprOp("CC_S>", nf, of, zf), + COND_LE: ExprOp("CC_S<=", nf, of, zf), } + + + def is_pc_written(ir, instr_ir): all_pc = ir.mn.pc.values() for ir in instr_ir: @@ -1359,6 +1531,10 @@ mnemo_condm1 = {'adds': add, 'movs': movs, 'bics': bics, 'mvns': mvns, + + 'mrs': mrs, + 'msr': msr, + 'negs': negs, 'muls': muls, diff --git a/miasm2/arch/mep/arch.py b/miasm2/arch/mep/arch.py index 3f844c06..a4c7182a 100644 --- a/miasm2/arch/mep/arch.py +++ b/miasm2/arch/mep/arch.py @@ -939,7 +939,8 @@ class mep_target24_signed(mep_target24): mep_target24.decode(self, v) v = int(self.expr.arg) - self.expr = ExprInt(v, 24).signExtend(32) + self.expr = ExprInt(sign_ext(v, 24, 32), 32) + return True @@ -1160,7 +1161,7 @@ class mep_disp12_align2_signed(mep_disp12_align2): mep_disp12_align2.decode(self, v) v = int(self.expr.arg) - self.expr = ExprInt(v, 12).signExtend(32) + self.expr = ExprInt(sign_ext(v, 12, 32), 32) return True diff --git a/miasm2/arch/x86/sem.py b/miasm2/arch/x86/sem.py index 00bdd6d7..8c140d7b 100644 --- a/miasm2/arch/x86/sem.py +++ b/miasm2/arch/x86/sem.py @@ -59,16 +59,30 @@ OF(A-B) = ((A XOR D) AND (A XOR B)) < 0 # XXX TODO make default check against 0 or not 0 (same eq as in C) +def update_flag_zf_eq(a, b): + return [m2_expr.ExprAff(zf, m2_expr.ExprOp("FLAG_EQ_CMP", a, b))] def update_flag_zf(a): - return [m2_expr.ExprAff( - zf, m2_expr.ExprCond(a, m2_expr.ExprInt(0, zf.size), - m2_expr.ExprInt(1, zf.size)))] + return [ + m2_expr.ExprAff( + zf, + m2_expr.ExprCond( + a, + m2_expr.ExprInt(0, zf.size), + m2_expr.ExprInt(1, zf.size) + ) + ) + ] -def update_flag_nf(a): - return [m2_expr.ExprAff(nf, a.msb())] +def update_flag_nf(arg): + return [ + m2_expr.ExprAff( + nf, + m2_expr.ExprOp("FLAG_SIGN_SUB", arg, m2_expr.ExprInt(0, arg.size)) + ) + ] def update_flag_pf(a): @@ -89,9 +103,15 @@ def update_flag_znp(a): return e -def update_flag_logic(a): +def update_flag_np(result): + e = [] + e += update_flag_nf(result) + e += update_flag_pf(result) + return e + + +def null_flag_co(): e = [] - e += update_flag_znp(a) e.append(m2_expr.ExprAff(of, m2_expr.ExprInt(0, of.size))) e.append(m2_expr.ExprAff(cf, m2_expr.ExprInt(0, cf.size))) return e @@ -103,6 +123,59 @@ def update_flag_arith(a): return e +def update_flag_zfaddwc_eq(arg1, arg2, arg3): + return [m2_expr.ExprAff(zf, m2_expr.ExprOp("FLAG_EQ_ADDWC", arg1, arg2, arg3))] + +def update_flag_zfsubwc_eq(arg1, arg2, arg3): + return [m2_expr.ExprAff(zf, m2_expr.ExprOp("FLAG_EQ_SUBWC", arg1, arg2, arg3))] + + +def update_flag_arith_add_znp(arg1, arg2): + """ + Compute znp flags for (arg1 + arg2) + """ + e = [] + e += update_flag_zf_eq(arg1, -arg2) + e += [m2_expr.ExprAff(nf, m2_expr.ExprOp("FLAG_SIGN_SUB", arg1, -arg2))] + e += update_flag_pf(arg1+arg2) + return e + + +def update_flag_arith_addwc_znp(arg1, arg2, arg3): + """ + Compute znp flags for (arg1 + arg2 + cf) + """ + e = [] + e += update_flag_zfaddwc_eq(arg1, arg2, arg3) + e += [m2_expr.ExprAff(nf, m2_expr.ExprOp("FLAG_SIGN_ADDWC", arg1, arg2, arg3))] + e += update_flag_pf(arg1+arg2+arg3.zeroExtend(arg2.size)) + return e + + + + +def update_flag_arith_sub_znp(arg1, arg2): + """ + Compute znp flags for (arg1 - arg2) + """ + e = [] + e += update_flag_zf_eq(arg1, arg2) + e += [m2_expr.ExprAff(nf, m2_expr.ExprOp("FLAG_SIGN_SUB", arg1, arg2))] + e += update_flag_pf(arg1 - arg2) + return e + + +def update_flag_arith_subwc_znp(arg1, arg2, arg3): + """ + Compute znp flags for (arg1 - (arg2 + cf)) + """ + e = [] + e += update_flag_zfsubwc_eq(arg1, arg2, arg3) + e += [m2_expr.ExprAff(nf, m2_expr.ExprOp("FLAG_SIGN_SUBWC", arg1, arg2, arg3))] + e += update_flag_pf(arg1 - (arg2+arg3.zeroExtend(arg2.size))) + return e + + def check_ops_msb(a, b, c): if not a or not b or not c or a != b or a != c: raise ValueError('bad ops size %s %s %s' % (a, b, c)) @@ -119,45 +192,80 @@ def arith_flag(a, b, c): def update_flag_add_cf(op1, op2, res): "Compute cf in @res = @op1 + @op2" - ret = (((op1 ^ op2) ^ res) ^ ((op1 ^ res) & (~(op1 ^ op2)))).msb() - return m2_expr.ExprAff(cf, ret) + #return [m2_expr.ExprAff(cf, m2_expr.ExprOp("FLAG_SUB_CF", op1, -op2))] + return [m2_expr.ExprAff(cf, m2_expr.ExprOp("FLAG_ADD_CF", op1, op2))] def update_flag_add_of(op1, op2, res): "Compute of in @res = @op1 + @op2" - return m2_expr.ExprAff(of, (((op1 ^ res) & (~(op1 ^ op2)))).msb()) + return [m2_expr.ExprAff(of, m2_expr.ExprOp("FLAG_ADD_OF", op1, op2))] # checked: ok for sbb add because b & c before +cf def update_flag_sub_cf(op1, op2, res): "Compote CF in @res = @op1 - @op2" - ret = (((op1 ^ op2) ^ res) ^ ((op1 ^ res) & (op1 ^ op2))).msb() - return m2_expr.ExprAff(cf, ret) + return [m2_expr.ExprAff(cf, m2_expr.ExprOp("FLAG_SUB_CF", op1, op2))] def update_flag_sub_of(op1, op2, res): "Compote OF in @res = @op1 - @op2" - return m2_expr.ExprAff(of, (((op1 ^ res) & (op1 ^ op2))).msb()) + return [m2_expr.ExprAff(of, m2_expr.ExprOp("FLAG_SUB_OF", op1, op2))] + + +def update_flag_addwc_cf(op1, op2, op3): + "Compute cf in @res = @op1 + @op2 + @op3" + return [m2_expr.ExprAff(cf, m2_expr.ExprOp("FLAG_ADDWC_CF", op1, op2, op3))] + + +def update_flag_addwc_of(op1, op2, op3): + "Compute of in @res = @op1 + @op2 + @op3" + return [m2_expr.ExprAff(of, m2_expr.ExprOp("FLAG_ADDWC_OF", op1, op2, op3))] -# z = x+y (+cf?) -def update_flag_add(x, y, z): +def update_flag_subwc_cf(op1, op2, op3): + "Compute cf in @res = @op1 + @op2 + @op3" + return [m2_expr.ExprAff(cf, m2_expr.ExprOp("FLAG_SUBWC_CF", op1, op2, op3))] + + +def update_flag_subwc_of(op1, op2, op3): + "Compute of in @res = @op1 + @op2 + @op3" + return [m2_expr.ExprAff(of, m2_expr.ExprOp("FLAG_SUBWC_OF", op1, op2, op3))] + + + + +def update_flag_arith_add_co(x, y, z): e = [] - e.append(update_flag_add_cf(x, y, z)) - e.append(update_flag_add_of(x, y, z)) + e += update_flag_add_cf(x, y, z) + e += update_flag_add_of(x, y, z) return e -# z = x-y (+cf?) + +def update_flag_arith_sub_co(x, y, z): + e = [] + e += update_flag_sub_cf(x, y, z) + e += update_flag_sub_of(x, y, z) + return e + + -def update_flag_sub(x, y, z): +def update_flag_arith_addwc_co(arg1, arg2, arg3): e = [] - e.append(update_flag_sub_cf(x, y, z)) - e.append(update_flag_sub_of(x, y, z)) + e += update_flag_addwc_cf(arg1, arg2, arg3) + e += update_flag_addwc_of(arg1, arg2, arg3) return e +def update_flag_arith_subwc_co(arg1, arg2, arg3): + e = [] + e += update_flag_subwc_cf(arg1, arg2, arg3) + e += update_flag_subwc_of(arg1, arg2, arg3) + return e + + + def set_float_cs_eip(instr): e = [] # XXX TODO check float updt @@ -344,20 +452,23 @@ def lea(_, instr, dst, src): def add(_, instr, dst, src): e = [] + result = dst + src - e += update_flag_arith(result) + + e += update_flag_arith_add_znp(dst, src) + e += update_flag_arith_add_co(dst, src, result) e += update_flag_af(dst, src, result) - e += update_flag_add(dst, src, result) e.append(m2_expr.ExprAff(dst, result)) return e, [] def xadd(_, instr, dst, src): e = [] + result = dst + src - e += update_flag_arith(result) + e += update_flag_arith_add_znp(dst, src) + e += update_flag_arith_add_co(src, dst, result) e += update_flag_af(dst, src, result) - e += update_flag_add(src, dst, result) if dst != src: e.append(m2_expr.ExprAff(src, dst)) e.append(m2_expr.ExprAff(dst, result)) @@ -366,21 +477,27 @@ def xadd(_, instr, dst, src): def adc(_, instr, dst, src): e = [] - result = dst + (src + m2_expr.ExprCompose(cf, - m2_expr.ExprInt(0, dst.size - 1))) - e += update_flag_arith(result) - e += update_flag_af(dst, src, result) - e += update_flag_add(dst, src, result) + + arg1 = dst + arg2 = src + result = arg1 + (arg2 + cf.zeroExtend(src.size)) + + e += update_flag_arith_addwc_znp(arg1, arg2, cf) + e += update_flag_arith_addwc_co(arg1, arg2, cf) + e += update_flag_af(arg1, arg2, result) e.append(m2_expr.ExprAff(dst, result)) return e, [] def sub(_, instr, dst, src): e = [] + arg1, arg2 = dst, src result = dst - src - e += update_flag_arith(result) + + e += update_flag_arith_sub_znp(arg1, arg2) + e += update_flag_arith_sub_co(arg1, arg2, result) e += update_flag_af(dst, src, result) - e += update_flag_sub(dst, src, result) + e.append(m2_expr.ExprAff(dst, result)) return e, [] @@ -389,11 +506,13 @@ def sub(_, instr, dst, src): def sbb(_, instr, dst, src): e = [] - result = dst - (src + m2_expr.ExprCompose(cf, - m2_expr.ExprInt(0, dst.size - 1))) - e += update_flag_arith(result) - e += update_flag_af(dst, src, result) - e += update_flag_sub(dst, src, result) + arg1 = dst + arg2 = src + result = arg1 - (arg2 + cf.zeroExtend(src.size)) + + e += update_flag_arith_subwc_znp(arg1, arg2, cf) + e += update_flag_af(arg1, arg2, result) + e += update_flag_arith_subwc_co(arg1, arg2, cf) e.append(m2_expr.ExprAff(dst, result)) return e, [] @@ -401,10 +520,12 @@ def sbb(_, instr, dst, src): def neg(_, instr, src): e = [] dst = m2_expr.ExprInt(0, src.size) - result = dst - src - e += update_flag_arith(result) - e += update_flag_sub(dst, src, result) - e += update_flag_af(dst, src, result) + arg1, arg2 = dst, src + result = arg1 - arg2 + + e += update_flag_arith_sub_znp(arg1, arg2) + e += update_flag_arith_sub_co(arg1, arg2, result) + e += update_flag_af(arg1, arg2, result) e.append(m2_expr.ExprAff(src, result)) return (e, []) @@ -418,9 +539,11 @@ def l_not(_, instr, dst): def l_cmp(_, instr, dst, src): e = [] + arg1, arg2 = dst, src result = dst - src - e += update_flag_arith(result) - e += update_flag_sub(dst, src, result) + + e += update_flag_arith_sub_znp(arg1, arg2) + e += update_flag_arith_sub_co(arg1, arg2, result) e += update_flag_af(dst, src, result) return (e, []) @@ -428,7 +551,9 @@ def l_cmp(_, instr, dst, src): def xor(_, instr, dst, src): e = [] result = dst ^ src - e += update_flag_logic(result) + e += [m2_expr.ExprAff(zf, m2_expr.ExprOp('FLAG_EQ_CMP', dst, src))] + e += update_flag_np(result) + e += null_flag_co() e.append(m2_expr.ExprAff(dst, result)) return (e, []) @@ -443,7 +568,9 @@ def pxor(_, instr, dst, src): def l_or(_, instr, dst, src): e = [] result = dst | src - e += update_flag_logic(result) + e += [m2_expr.ExprAff(zf, m2_expr.ExprOp('FLAG_EQ', dst | src))] + e += update_flag_np(result) + e += null_flag_co() e.append(m2_expr.ExprAff(dst, result)) return (e, []) @@ -451,7 +578,10 @@ def l_or(_, instr, dst, src): def l_and(_, instr, dst, src): e = [] result = dst & src - e += update_flag_logic(result) + e += [m2_expr.ExprAff(zf, m2_expr.ExprOp('FLAG_EQ_AND', dst, src))] + e += update_flag_np(result) + e += null_flag_co() + e.append(m2_expr.ExprAff(dst, result)) return (e, []) @@ -459,7 +589,12 @@ def l_and(_, instr, dst, src): def l_test(_, instr, dst, src): e = [] result = dst & src - e += update_flag_logic(result) + + e += [m2_expr.ExprAff(zf, m2_expr.ExprOp('FLAG_EQ_CMP', result, m2_expr.ExprInt(0, result.size)))] + e += [m2_expr.ExprAff(nf, m2_expr.ExprOp("FLAG_SIGN_SUB", result, m2_expr.ExprInt(0, result.size)))] + e += update_flag_pf(result) + e += null_flag_co() + return (e, []) @@ -717,23 +852,27 @@ def sti(_, instr): def inc(_, instr, dst): e = [] src = m2_expr.ExprInt(1, dst.size) + arg1, arg2 = dst, src result = dst + src - e += update_flag_arith(result) - e += update_flag_af(dst, src, result) - e.append(update_flag_add_of(dst, src, result)) + e += update_flag_arith_add_znp(arg1, arg2) + e += update_flag_af(arg1, arg2, result) + e += update_flag_add_of(arg1, arg2, result) + e.append(m2_expr.ExprAff(dst, result)) return e, [] def dec(_, instr, dst): e = [] - src = m2_expr.ExprInt(-1, dst.size) - result = dst + src - e += update_flag_arith(result) - e += update_flag_af(dst, src, ~result) + src = m2_expr.ExprInt(1, dst.size) + arg1, arg2 = dst, src + result = dst - src + + e += update_flag_arith_sub_znp(arg1, arg2) + e += update_flag_af(arg1, arg2, result) + e += update_flag_sub_of(arg1, arg2, result) - e.append(update_flag_add_of(dst, src, result)) e.append(m2_expr.ExprAff(dst, result)) return e, [] @@ -796,16 +935,22 @@ def popw(ir, instr, src): def sete(_, instr, dst): e = [] e.append( - m2_expr.ExprAff(dst, m2_expr.ExprCond(zf, m2_expr.ExprInt(1, dst.size), - m2_expr.ExprInt(0, dst.size)))) + m2_expr.ExprAff( + dst, + m2_expr.ExprOp("CC_EQ", zf).zeroExtend(dst.size), + ) + ) return e, [] def setnz(_, instr, dst): e = [] e.append( - m2_expr.ExprAff(dst, m2_expr.ExprCond(zf, m2_expr.ExprInt(0, dst.size), - m2_expr.ExprInt(1, dst.size)))) + m2_expr.ExprAff( + dst, + m2_expr.ExprOp("CC_EQ", ~zf).zeroExtend(dst.size), + ) + ) return e, [] @@ -813,17 +958,21 @@ def setl(_, instr, dst): e = [] e.append( m2_expr.ExprAff( - dst, m2_expr.ExprCond(nf - of, m2_expr.ExprInt(1, dst.size), - m2_expr.ExprInt(0, dst.size)))) + dst, + m2_expr.ExprOp("CC_S<", nf, of).zeroExtend(dst.size), + ) + ) return e, [] def setg(_, instr, dst): e = [] - a0 = m2_expr.ExprInt(0, dst.size) - a1 = m2_expr.ExprInt(1, dst.size) - ret = m2_expr.ExprCond(zf, a0, a1) & m2_expr.ExprCond(nf - of, a0, a1) - e.append(m2_expr.ExprAff(dst, ret)) + e.append( + m2_expr.ExprAff( + dst, + m2_expr.ExprOp("CC_S>", nf, of, zf).zeroExtend(dst.size), + ) + ) return e, [] @@ -831,128 +980,172 @@ def setge(_, instr, dst): e = [] e.append( m2_expr.ExprAff( - dst, m2_expr.ExprCond(nf - of, m2_expr.ExprInt(0, dst.size), - m2_expr.ExprInt(1, dst.size)))) + dst, + m2_expr.ExprOp("CC_S>=", nf, of).zeroExtend(dst.size), + ) + ) return e, [] def seta(_, instr, dst): e = [] - e.append(m2_expr.ExprAff(dst, m2_expr.ExprCond(cf | zf, - m2_expr.ExprInt( - 0, dst.size), - m2_expr.ExprInt(1, dst.size)))) - + e.append( + m2_expr.ExprAff( + dst, + m2_expr.ExprOp("CC_U>", cf, zf).zeroExtend(dst.size), + ) + ) return e, [] def setae(_, instr, dst): e = [] e.append( - m2_expr.ExprAff(dst, m2_expr.ExprCond(cf, m2_expr.ExprInt(0, dst.size), - m2_expr.ExprInt(1, dst.size)))) + m2_expr.ExprAff( + dst, + m2_expr.ExprOp("CC_U>=", cf).zeroExtend(dst.size), + ) + ) return e, [] def setb(_, instr, dst): e = [] e.append( - m2_expr.ExprAff(dst, m2_expr.ExprCond(cf, m2_expr.ExprInt(1, dst.size), - m2_expr.ExprInt(0, dst.size)))) + m2_expr.ExprAff( + dst, + m2_expr.ExprOp("CC_U<", cf).zeroExtend(dst.size), + ) + ) return e, [] def setbe(_, instr, dst): e = [] - e.append(m2_expr.ExprAff(dst, m2_expr.ExprCond(cf | zf, - m2_expr.ExprInt( - 1, dst.size), - m2_expr.ExprInt(0, dst.size))) - ) + e.append( + m2_expr.ExprAff( + dst, + m2_expr.ExprOp("CC_U<=", cf, zf).zeroExtend(dst.size), + ) + ) return e, [] def setns(_, instr, dst): e = [] e.append( - m2_expr.ExprAff(dst, m2_expr.ExprCond(nf, m2_expr.ExprInt(0, dst.size), - m2_expr.ExprInt(1, dst.size)))) + m2_expr.ExprAff( + dst, + m2_expr.ExprOp("CC_NEG", ~nf).zeroExtend(dst.size), + ) + ) return e, [] def sets(_, instr, dst): e = [] e.append( - m2_expr.ExprAff(dst, m2_expr.ExprCond(nf, m2_expr.ExprInt(1, dst.size), - m2_expr.ExprInt(0, dst.size)))) + m2_expr.ExprAff( + dst, + m2_expr.ExprOp("CC_NEG", nf).zeroExtend(dst.size), + ) + ) return e, [] def seto(_, instr, dst): e = [] e.append( - m2_expr.ExprAff(dst, m2_expr.ExprCond(of, m2_expr.ExprInt(1, dst.size), - m2_expr.ExprInt(0, dst.size)))) + m2_expr.ExprAff( + dst, + of.zeroExtend(dst.size) + ) + ) return e, [] def setp(_, instr, dst): e = [] e.append( - m2_expr.ExprAff(dst, m2_expr.ExprCond(pf, m2_expr.ExprInt(1, dst.size), - m2_expr.ExprInt(0, dst.size)))) + m2_expr.ExprAff( + dst, + pf.zeroExtend(dst.size) + ) + ) return e, [] def setnp(_, instr, dst): e = [] e.append( - m2_expr.ExprAff(dst, m2_expr.ExprCond(pf, m2_expr.ExprInt(0, dst.size), - m2_expr.ExprInt(1, dst.size)))) + m2_expr.ExprAff( + dst, + m2_expr.ExprCond( + pf, + m2_expr.ExprInt(0, dst.size), + m2_expr.ExprInt(1, dst.size) + ) + ) + ) return e, [] def setle(_, instr, dst): e = [] - a0 = m2_expr.ExprInt(0, dst.size) - a1 = m2_expr.ExprInt(1, dst.size) - ret = m2_expr.ExprCond(zf, a1, a0) | m2_expr.ExprCond(nf ^ of, a1, a0) - e.append(m2_expr.ExprAff(dst, ret)) + e.append( + m2_expr.ExprAff( + dst, + m2_expr.ExprOp("CC_S<=", nf, of, zf).zeroExtend(dst.size), + ) + ) return e, [] def setna(_, instr, dst): e = [] - a0 = m2_expr.ExprInt(0, dst.size) - a1 = m2_expr.ExprInt(1, dst.size) - ret = m2_expr.ExprCond(cf, a1, a0) & m2_expr.ExprCond(zf, a1, a0) - e.append(m2_expr.ExprAff(dst, ret)) + e.append( + m2_expr.ExprAff( + dst, + m2_expr.ExprOp("CC_U<=", cf, zf).zeroExtend(dst.size), + ) + ) return e, [] def setnbe(_, instr, dst): e = [] - e.append(m2_expr.ExprAff(dst, m2_expr.ExprCond(cf | zf, - m2_expr.ExprInt( - 0, dst.size), - m2_expr.ExprInt(1, dst.size))) - ) + e.append( + m2_expr.ExprAff( + dst, + m2_expr.ExprOp("CC_U>", cf, zf).zeroExtend(dst.size), + ) + ) return e, [] def setno(_, instr, dst): e = [] e.append( - m2_expr.ExprAff(dst, m2_expr.ExprCond(of, m2_expr.ExprInt(0, dst.size), - m2_expr.ExprInt(1, dst.size)))) + m2_expr.ExprAff( + dst, + m2_expr.ExprCond( + of, + m2_expr.ExprInt(0, dst.size), + m2_expr.ExprInt(1, dst.size) + ) + ) + ) return e, [] def setnb(_, instr, dst): e = [] e.append( - m2_expr.ExprAff(dst, m2_expr.ExprCond(cf, m2_expr.ExprInt(0, dst.size), - m2_expr.ExprInt(1, dst.size)))) + m2_expr.ExprAff( + dst, + m2_expr.ExprOp("CC_U>=", cf).zeroExtend(dst.size), + ) + ) return e, [] @@ -1358,7 +1551,8 @@ def jmp(ir, instr, dst): def jz(ir, instr, dst): - return gen_jcc(ir, instr, zf, dst, True) + #return gen_jcc(ir, instr, zf, dst, True) + return gen_jcc(ir, instr, m2_expr.ExprOp("CC_EQ", zf), dst, True) def jcxz(ir, instr, dst): @@ -1374,7 +1568,9 @@ def jrcxz(ir, instr, dst): def jnz(ir, instr, dst): - return gen_jcc(ir, instr, zf, dst, False) + #return gen_jcc(ir, instr, zf, dst, False) + return gen_jcc(ir, instr, m2_expr.ExprOp("CC_EQ", zf), dst, False) + def jp(ir, instr, dst): @@ -1386,43 +1582,55 @@ def jnp(ir, instr, dst): def ja(ir, instr, dst): - return gen_jcc(ir, instr, cf | zf, dst, False) + #return gen_jcc(ir, instr, cf | zf, dst, False) + return gen_jcc(ir, instr, m2_expr.ExprOp("CC_U>", cf, zf), dst, True) def jae(ir, instr, dst): - return gen_jcc(ir, instr, cf, dst, False) + #return gen_jcc(ir, instr, cf, dst, False) + return gen_jcc(ir, instr, m2_expr.ExprOp("CC_U>=", cf), dst, True) def jb(ir, instr, dst): - return gen_jcc(ir, instr, cf, dst, True) + #return gen_jcc(ir, instr, cf, dst, True) + return gen_jcc(ir, instr, m2_expr.ExprOp("CC_U<", cf), dst, True) def jbe(ir, instr, dst): - return gen_jcc(ir, instr, cf | zf, dst, True) + #return gen_jcc(ir, instr, cf | zf, dst, True) + return gen_jcc(ir, instr, m2_expr.ExprOp("CC_U<=", cf, zf), dst, True) def jge(ir, instr, dst): - return gen_jcc(ir, instr, nf - of, dst, False) + #return gen_jcc(ir, instr, nf - of, dst, False) + return gen_jcc(ir, instr, m2_expr.ExprOp("CC_S>=", nf, of), dst, True) def jg(ir, instr, dst): - return gen_jcc(ir, instr, zf | (nf - of), dst, False) + #return gen_jcc(ir, instr, zf | (nf - of), dst, False) + return gen_jcc(ir, instr, m2_expr.ExprOp("CC_S>", nf, of, zf), dst, True) def jl(ir, instr, dst): - return gen_jcc(ir, instr, nf - of, dst, True) + #return gen_jcc(ir, instr, nf - of, dst, True) + return gen_jcc(ir, instr, m2_expr.ExprOp("CC_S<", nf, of), dst, True) def jle(ir, instr, dst): - return gen_jcc(ir, instr, zf | (nf - of), dst, True) + #return gen_jcc(ir, instr, zf | (nf - of), dst, True) + return gen_jcc(ir, instr, m2_expr.ExprOp("CC_S<=", nf, of, zf), dst, True) + def js(ir, instr, dst): - return gen_jcc(ir, instr, nf, dst, True) + #return gen_jcc(ir, instr, nf, dst, True) + return gen_jcc(ir, instr, m2_expr.ExprOp("CC_NEG", nf), dst, True) + def jns(ir, instr, dst): - return gen_jcc(ir, instr, nf, dst, False) + #return gen_jcc(ir, instr, nf, dst, False) + return gen_jcc(ir, instr, m2_expr.ExprOp("CC_NEG", nf), dst, False) def jo(ir, instr, dst): @@ -2957,11 +3165,13 @@ def sldt(_, instr, dst): def cmovz(ir, instr, dst, src): - return gen_cmov(ir, instr, zf, dst, src, True) + #return gen_cmov(ir, instr, zf, dst, src, True) + return gen_cmov(ir, instr, m2_expr.ExprOp("CC_EQ", zf), dst, src, True) def cmovnz(ir, instr, dst, src): - return gen_cmov(ir, instr, zf, dst, src, False) + #return gen_cmov(ir, instr, zf, dst, src, False) + return gen_cmov(ir, instr, m2_expr.ExprOp("CC_EQ", zf), dst, src, False) def cmovpe(ir, instr, dst, src): @@ -2973,35 +3183,43 @@ def cmovnp(ir, instr, dst, src): def cmovge(ir, instr, dst, src): - return gen_cmov(ir, instr, nf ^ of, dst, src, False) + #return gen_cmov(ir, instr, nf ^ of, dst, src, False) + return gen_cmov(ir, instr, m2_expr.ExprOp("CC_S>=", nf, of), dst, src, True) def cmovg(ir, instr, dst, src): - return gen_cmov(ir, instr, zf | (nf ^ of), dst, src, False) + #return gen_cmov(ir, instr, zf | (nf ^ of), dst, src, False) + return gen_cmov(ir, instr, m2_expr.ExprOp("CC_S>", nf, of, zf), dst, src, True) def cmovl(ir, instr, dst, src): - return gen_cmov(ir, instr, nf ^ of, dst, src, True) + #return gen_cmov(ir, instr, nf ^ of, dst, src, True) + return gen_cmov(ir, instr, m2_expr.ExprOp("CC_S<", nf, of), dst, src, True) def cmovle(ir, instr, dst, src): - return gen_cmov(ir, instr, zf | (nf ^ of), dst, src, True) + #return gen_cmov(ir, instr, zf | (nf ^ of), dst, src, True) + return gen_cmov(ir, instr, m2_expr.ExprOp("CC_S<=", nf, of, zf), dst, src, True) def cmova(ir, instr, dst, src): - return gen_cmov(ir, instr, cf | zf, dst, src, False) + #return gen_cmov(ir, instr, cf | zf, dst, src, False) + return gen_cmov(ir, instr, m2_expr.ExprOp("CC_U>", cf, zf), dst, src, True) def cmovae(ir, instr, dst, src): - return gen_cmov(ir, instr, cf, dst, src, False) + #return gen_cmov(ir, instr, cf, dst, src, False) + return gen_cmov(ir, instr, m2_expr.ExprOp("CC_U>=", cf), dst, src, True) def cmovbe(ir, instr, dst, src): - return gen_cmov(ir, instr, cf | zf, dst, src, True) + #return gen_cmov(ir, instr, cf | zf, dst, src, True) + return gen_cmov(ir, instr, m2_expr.ExprOp("CC_U<=", cf, zf), dst, src, True) def cmovb(ir, instr, dst, src): - return gen_cmov(ir, instr, cf, dst, src, True) + #return gen_cmov(ir, instr, cf, dst, src, True) + return gen_cmov(ir, instr, m2_expr.ExprOp("CC_U<", cf), dst, src, True) def cmovo(ir, instr, dst, src): @@ -3013,11 +3231,13 @@ def cmovno(ir, instr, dst, src): def cmovs(ir, instr, dst, src): - return gen_cmov(ir, instr, nf, dst, src, True) + #return gen_cmov(ir, instr, nf, dst, src, True) + return gen_cmov(ir, instr, m2_expr.ExprOp("CC_NEG", nf), dst, src, True) def cmovns(ir, instr, dst, src): - return gen_cmov(ir, instr, nf, dst, src, False) + #return gen_cmov(ir, instr, nf, dst, src, False) + return gen_cmov(ir, instr, m2_expr.ExprOp("CC_NEG", nf), dst, src, False) def icebp(_, instr): |