diff options
| -rw-r--r-- | miasm2/arch/x86/arch.py | 7 | ||||
| -rw-r--r-- | miasm2/arch/x86/sem.py | 44 | ||||
| -rw-r--r-- | miasm2/expression/expression.py | 182 | ||||
| -rw-r--r-- | test/arch/x86/arch.py | 15 | ||||
| -rw-r--r-- | test/expression/expr_cmp.py | 107 | ||||
| -rwxr-xr-x | test/test_all.py | 1 |
6 files changed, 351 insertions, 5 deletions
diff --git a/miasm2/arch/x86/arch.py b/miasm2/arch/x86/arch.py index 73c9fc0d..6725f5bc 100644 --- a/miasm2/arch/x86/arch.py +++ b/miasm2/arch/x86/arch.py @@ -4254,6 +4254,8 @@ addop("pcmpgtd", [bs8(0x0f), bs8(0x66), no_xmm_pref] + addop("pcmpgtd", [bs8(0x0f), bs8(0x66), pref_66] + rmmod(xmm_reg, rm_arg_xmm)) +addop("pcmpeqq", [bs8(0x0f), bs8(0x38), bs8(0x29), pref_66] + rmmod(xmm_reg, rm_arg_xmm)) +addop("pcmpgtq", [bs8(0x0f), bs8(0x38), bs8(0x37), pref_66] + rmmod(xmm_reg, rm_arg_xmm)) addop("punpckhbw", [bs8(0x0f), bs8(0x68), no_xmm_pref] + rmmod(mm_reg, rm_arg_mm)) @@ -4355,6 +4357,11 @@ addop("shufps", [bs8(0x0f), bs8(0xc6), no_xmm_pref] + addop("shufpd", [bs8(0x0f), bs8(0xc6), pref_66] + rmmod(xmm_reg, rm_arg_xmm) + [u08]) +addop("aesenc", [bs8(0x0f), bs8(0x38), bs8(0xdc), pref_66] + rmmod(xmm_reg, rm_arg_xmm)) +addop("aesdec", [bs8(0x0f), bs8(0x38), bs8(0xde), pref_66] + rmmod(xmm_reg, rm_arg_xmm)) + +addop("aesenclast", [bs8(0x0f), bs8(0x38), bs8(0xdd), pref_66] + rmmod(xmm_reg, rm_arg_xmm)) +addop("aesdeclast", [bs8(0x0f), bs8(0x38), bs8(0xdf), pref_66] + rmmod(xmm_reg, rm_arg_xmm)) mn_x86.bintree = factor_one_bit(mn_x86.bintree) # mn_x86.bintree = factor_fields_all(mn_x86.bintree) diff --git a/miasm2/arch/x86/sem.py b/miasm2/arch/x86/sem.py index 1fceab30..5d564fb1 100644 --- a/miasm2/arch/x86/sem.py +++ b/miasm2/arch/x86/sem.py @@ -3819,25 +3819,53 @@ def pminud(ir, instr, dst, src): def pcmpeq(_, instr, dst, src, size): e = [] for i in xrange(0, dst.size, size): - test = dst[i:i + size] - src[i:i + size] + test = m2_expr.expr_is_equal(dst[i:i + size], src[i:i + size]) e.append(m2_expr.ExprAff(dst[i:i + size], m2_expr.ExprCond(test, - m2_expr.ExprInt(0, size), - m2_expr.ExprInt(-1, size)))) + m2_expr.ExprInt(-1, size), + m2_expr.ExprInt(0, size)))) + return e, [] + + +def pcmpgt(_, instr, dst, src, size): + e = [] + for i in xrange(0, dst.size, size): + test = m2_expr.expr_is_signed_greater(dst[i:i + size], src[i:i + size]) + e.append(m2_expr.ExprAff(dst[i:i + size], + m2_expr.ExprCond(test, + m2_expr.ExprInt(-1, size), + m2_expr.ExprInt(0, size)))) return e, [] def pcmpeqb(ir, instr, dst, src): return pcmpeq(ir, instr, dst, src, 8) - def pcmpeqw(ir, instr, dst, src): return pcmpeq(ir, instr, dst, src, 16) - def pcmpeqd(ir, instr, dst, src): return pcmpeq(ir, instr, dst, src, 32) +def pcmpeqq(ir, instr, dst, src): + return pcmpeq(ir, instr, dst, src, 64) + + + + +def pcmpgtb(ir, instr, dst, src): + return pcmpgt(ir, instr, dst, src, 8) + +def pcmpgtw(ir, instr, dst, src): + return pcmpgt(ir, instr, dst, src, 16) + +def pcmpgtd(ir, instr, dst, src): + return pcmpgt(ir, instr, dst, src, 32) + +def pcmpgtq(ir, instr, dst, src): + return pcmpgt(ir, instr, dst, src, 64) + + def punpck(_, instr, dst, src, size, off): e = [] @@ -4504,6 +4532,12 @@ mnemo_func = {'mov': mov, "pcmpeqb": pcmpeqb, "pcmpeqw": pcmpeqw, "pcmpeqd": pcmpeqd, + "pcmpeqq": pcmpeqq, + + "pcmpgtb": pcmpgtb, + "pcmpgtw": pcmpgtw, + "pcmpgtd": pcmpgtd, + "pcmpgtq": pcmpgtq, "punpckhbw": punpckhbw, "punpckhwd": punpckhwd, diff --git a/miasm2/expression/expression.py b/miasm2/expression/expression.py index b7b90470..591dc024 100644 --- a/miasm2/expression/expression.py +++ b/miasm2/expression/expression.py @@ -1538,3 +1538,185 @@ def get_expr_mem(expr): ops = set() expr.visit(lambda x: visit_getmem(x, ops)) return ops + + +def _expr_compute_cf(op1, op2): + """ + Get carry flag of @op1 - @op2 + Ref: x86 cf flag + @op1: Expression + @op2: Expression + """ + res = op1 - op2 + cf = (((op1 ^ op2) ^ res) ^ ((op1 ^ res) & (op1 ^ op2))).msb() + return cf + +def _expr_compute_of(op1, op2): + """ + Get overflow flag of @op1 - @op2 + Ref: x86 of flag + @op1: Expression + @op2: Expression + """ + res = op1 - op2 + of = (((op1 ^ res) & (op1 ^ op2))).msb() + return of + +def _expr_compute_zf(op1, op2): + """ + Get zero flag of @op1 - @op2 + @op1: Expression + @op2: Expression + """ + res = op1 - op2 + zf = ExprCond(res, + ExprInt(0, 1), + ExprInt(1, 1)) + return zf + + +def _expr_compute_nf(op1, op2): + """ + Get negative (or sign) flag of @op1 - @op2 + @op1: Expression + @op2: Expression + """ + res = op1 - op2 + nf = res.msb() + return nf + + +def expr_is_equal(op1, op2): + """ + if op1 == op2: + Return ExprInt(1, 1) + else: + Return ExprInt(0, 1) + """ + + zf = _expr_compute_zf(op1, op2) + return zf + + +def expr_is_not_equal(op1, op2): + """ + if op1 != op2: + Return ExprInt(1, 1) + else: + Return ExprInt(0, 1) + """ + + zf = _expr_compute_zf(op1, op2) + return ~zf + + +def expr_is_unsigned_greater(op1, op2): + """ + UNSIGNED cmp + if op1 > op2: + Return ExprInt(1, 1) + else: + Return ExprInt(0, 1) + """ + + cf = _expr_compute_cf(op1, op2) + zf = _expr_compute_zf(op1, op2) + return ~(cf | zf) + + +def expr_is_unsigned_greater_or_equal(op1, op2): + """ + Unsigned cmp + if op1 >= op2: + Return ExprInt(1, 1) + else: + Return ExprInt(0, 1) + """ + + cf = _expr_compute_cf(op1, op2) + return ~cf + + +def expr_is_unsigned_lower(op1, op2): + """ + Unsigned cmp + if op1 < op2: + Return ExprInt(1, 1) + else: + Return ExprInt(0, 1) + """ + + cf = _expr_compute_cf(op1, op2) + return cf + + +def expr_is_unsigned_lower_or_equal(op1, op2): + """ + Unsigned cmp + if op1 <= op2: + Return ExprInt(1, 1) + else: + Return ExprInt(0, 1) + """ + + cf = _expr_compute_cf(op1, op2) + zf = _expr_compute_zf(op1, op2) + return cf | zf + + +def expr_is_signed_greater(op1, op2): + """ + Signed cmp + if op1 > op2: + Return ExprInt(1, 1) + else: + Return ExprInt(0, 1) + """ + + nf = _expr_compute_nf(op1, op2) + of = _expr_compute_of(op1, op2) + zf = _expr_compute_zf(op1, op2) + return ~(zf | (nf ^ of)) + + +def expr_is_signed_greater_or_equal(op1, op2): + """ + Signed cmp + if op1 > op2: + Return ExprInt(1, 1) + else: + Return ExprInt(0, 1) + """ + + nf = _expr_compute_nf(op1, op2) + of = _expr_compute_of(op1, op2) + return ~(nf ^ of) + + +def expr_is_signed_lower(op1, op2): + """ + Signed cmp + if op1 < op2: + Return ExprInt(1, 1) + else: + Return ExprInt(0, 1) + """ + + nf = _expr_compute_nf(op1, op2) + of = _expr_compute_of(op1, op2) + return nf ^ of + + +def expr_is_signed_lower_or_equal(op1, op2): + """ + Signed cmp + if op1 <= op2: + Return ExprInt(1, 1) + else: + Return ExprInt(0, 1) + """ + + nf = _expr_compute_nf(op1, op2) + of = _expr_compute_of(op1, op2) + zf = _expr_compute_zf(op1, op2) + return zf | (nf ^ of) diff --git a/test/arch/x86/arch.py b/test/arch/x86/arch.py index 0472e714..76e5a5eb 100644 --- a/test/arch/x86/arch.py +++ b/test/arch/x86/arch.py @@ -2793,6 +2793,12 @@ reg_tests = [ (m64, "00000000 PCMPGTD XMM3, XMM0", "660f66d8"), + (m32, "00000000 PCMPEQQ XMM0, XMM5", + "660f3829C5"), + (m32, "00000000 PCMPGTQ XMM0, XMM5", + "660f3837C5"), + + (m32, "00000000 PUNPCKHBW MM2, QWORD PTR [EDX]", "0F6812"), (m32, "00000000 PUNPCKHBW XMM2, XMMWORD PTR [EDX]", @@ -2939,6 +2945,15 @@ reg_tests = [ (m64, "00000000 SHUFPD XMM0, XMM6, 0x44", "660fc6c644"), + (m32, "00000000 AESENC XMM1, XMM2", + "660f38dcca"), + (m32, "00000000 AESDEC XMM1, XMM2", + "660f38deca"), + + (m32, "00000000 AESENCLAST XMM1, XMM2", + "660f38ddca"), + (m32, "00000000 AESDECLAST XMM1, XMM2", + "660f38dfca"), ] diff --git a/test/expression/expr_cmp.py b/test/expression/expr_cmp.py new file mode 100644 index 00000000..b238151d --- /dev/null +++ b/test/expression/expr_cmp.py @@ -0,0 +1,107 @@ +# +# Expression comparison regression tests # +# +from pdb import pm +from miasm2.expression.expression import ExprInt, expr_is_unsigned_greater,\ + expr_is_unsigned_greater_or_equal, expr_is_unsigned_lower,\ + expr_is_unsigned_lower_or_equal, expr_is_signed_greater,\ + expr_is_signed_greater_or_equal, expr_is_signed_lower, \ + expr_is_signed_lower_or_equal, expr_is_equal, expr_is_not_equal +from miasm2.expression.simplifications import expr_simp + +int_0 = ExprInt(0, 32) +int_1 = ExprInt(1, 32) +int_m1 = ExprInt(-1, 32) +int_m2 = ExprInt(-2, 32) + +b0 = ExprInt(0, 1) +b1 = ExprInt(1, 1) + +tests = [ + # unsigned + (b1, expr_is_unsigned_greater, int_1, int_0), + (b1, expr_is_unsigned_lower, int_0, int_1), + + (b0, expr_is_unsigned_greater, int_0, int_1), + (b0, expr_is_unsigned_lower, int_1, int_0), + + (b1, expr_is_unsigned_greater_or_equal, int_1, int_0), + (b1, expr_is_unsigned_lower_or_equal, int_0, int_1), + + (b0, expr_is_unsigned_greater_or_equal, int_0, int_1), + (b0, expr_is_unsigned_lower_or_equal, int_1, int_0), + + (b1, expr_is_unsigned_greater_or_equal, int_1, int_1), + (b1, expr_is_unsigned_lower_or_equal, int_1, int_1), + + (b1, expr_is_unsigned_greater, int_m1, int_0), + (b1, expr_is_unsigned_lower, int_0, int_m1), + + (b0, expr_is_unsigned_greater, int_0, int_m1), + (b0, expr_is_unsigned_lower, int_m1, int_0), + + + # signed + (b1, expr_is_signed_greater, int_1, int_0), + (b1, expr_is_signed_lower, int_0, int_1), + + (b0, expr_is_signed_greater, int_0, int_1), + (b0, expr_is_signed_lower, int_1, int_0), + + (b1, expr_is_signed_greater_or_equal, int_1, int_0), + (b1, expr_is_signed_lower_or_equal, int_0, int_1), + + (b0, expr_is_signed_greater_or_equal, int_0, int_1), + (b0, expr_is_signed_lower_or_equal, int_1, int_0), + + (b1, expr_is_signed_greater_or_equal, int_1, int_1), + (b1, expr_is_signed_lower_or_equal, int_1, int_1), + + (b0, expr_is_signed_greater, int_m1, int_0), + (b0, expr_is_signed_lower, int_0, int_m1), + + (b1, expr_is_signed_greater, int_0, int_m1), + (b1, expr_is_signed_lower, int_m1, int_0), + + + # greater lesser, neg + (b1, expr_is_signed_greater, int_1, int_m1), + (b1, expr_is_signed_lower, int_m1, int_1), + + (b0, expr_is_signed_greater, int_m1, int_1), + (b0, expr_is_signed_lower, int_1, int_m1), + + (b1, expr_is_signed_greater_or_equal, int_1, int_m1), + (b1, expr_is_signed_lower_or_equal, int_m1, int_1), + + (b0, expr_is_signed_greater_or_equal, int_m1, int_1), + (b0, expr_is_signed_lower_or_equal, int_1, int_m1), + + (b1, expr_is_signed_greater_or_equal, int_m1, int_m1), + (b1, expr_is_signed_lower_or_equal, int_m1, int_m1), + + + (b1, expr_is_signed_greater, int_m1, int_m2), + (b1, expr_is_signed_lower, int_m2, int_m1), + + (b0, expr_is_signed_greater, int_m2, int_m1), + (b0, expr_is_signed_lower, int_m1, int_m2), + + (b1, expr_is_signed_greater_or_equal, int_m1, int_m2), + (b1, expr_is_signed_lower_or_equal, int_m2, int_m1), + + (b0, expr_is_signed_greater_or_equal, int_m2, int_m1), + (b0, expr_is_signed_lower_or_equal, int_m1, int_m2), + + # eq/neq + (b1, expr_is_equal, int_1, int_1), + (b1, expr_is_not_equal, int_0, int_1), + + (b0, expr_is_equal, int_1, int_0), + (b0, expr_is_not_equal, int_0, int_0), + + +] + +for result, func, arg1, arg2 in tests: + assert result == expr_simp(func(arg1, arg2)) diff --git a/test/test_all.py b/test/test_all.py index 99b0094e..30408ee2 100755 --- a/test/test_all.py +++ b/test/test_all.py @@ -245,6 +245,7 @@ for script in ["modint.py", "expression_helper.py", "expr_pickle.py", "parser.py", + "expr_cmp.py", ]: testset += RegressionTest([script], base_dir="expression") |