diff options
| -rw-r--r-- | miasm2/arch/x86/arch.py | 25 | ||||
| -rw-r--r-- | miasm2/arch/x86/sem.py | 10 | ||||
| -rw-r--r-- | miasm2/ir/symbexec.py | 66 | ||||
| -rw-r--r-- | test/arch/x86/arch.py | 11 | ||||
| -rwxr-xr-x | test/arch/x86/unit/mn_cpuid.py | 21 | ||||
| -rwxr-xr-x | test/test_all.py | 1 |
6 files changed, 96 insertions, 38 deletions
diff --git a/miasm2/arch/x86/arch.py b/miasm2/arch/x86/arch.py index 90d0fcef..edbe9874 100644 --- a/miasm2/arch/x86/arch.py +++ b/miasm2/arch/x86/arch.py @@ -2445,6 +2445,8 @@ class x86_rm_reg_noarg(object): if p.v_opmode() == 64 or p.rex_p.value == 1: if not hasattr(p, 'sx') and (hasattr(p, 'w8') and p.w8.value == 0): r = gpregs08_64 + elif p.rex_r.value == 1: + v |= 8 self.expr = r.expr[v] return True @@ -2526,6 +2528,16 @@ class x86_reg(x86_rm_reg): self.parent.rex_b.value = v +class x86_reg_modrm(x86_rm_reg): + + def getrexsize(self): + return self.parent.rex_r.value + + def setrexsize(self, v): + self.parent.rex_r.value = v + + + class x86_reg_noarg(x86_rm_reg_noarg): def getrexsize(self): @@ -3176,6 +3188,10 @@ mod_mem = bs(l=2, cls=(bs_mem,), fname="mod") rmreg = bs(l=3, cls=(x86_rm_reg, ), order =1, fname = "reg") reg = bs(l=3, cls=(x86_reg, ), order =1, fname = "reg") + +reg_modrm = bs(l=3, cls=(x86_reg_modrm, ), order =1, fname = "reg") + + regnoarg = bs(l=3, default_val="000", order=1, fname="reg") segm = bs(l=3, cls=(x86_rm_segm, ), order =1, fname = "reg") crreg = bs(l=3, cls=(x86_rm_cr, ), order =1, fname = "reg") @@ -3690,7 +3706,7 @@ addop("movq", [bs8(0x0f), bs8(0xd6), pref_66] + rmmod(xmm_reg, rm_arg_xmm_m64), [rm_arg_xmm_m64, xmm_reg]) addop("movmskps", [bs8(0x0f), bs8(0x50), no_xmm_pref] + - rmmod(reg, rm_arg_xmm_reg)) + rmmod(reg_modrm, rm_arg_xmm_reg)) addop("addss", [bs8(0x0f), bs8(0x58), pref_f3] + rmmod(xmm_reg, rm_arg_xmm_m32)) @@ -4194,6 +4210,9 @@ addop("psllw", [bs8(0x0f), bs8(0xf1), no_xmm_pref] + addop("psllw", [bs8(0x0f), bs8(0xf1), pref_66] + rmmod(xmm_reg, rm_arg_xmm), [xmm_reg, rm_arg_xmm]) +addop("pslldq", [bs8(0x0f), bs8(0x73), pref_66] + + rmmod(d7, rm_arg_xmm) + [u08], [rm_arg_xmm, u08]) + addop("pmaxub", [bs8(0x0f), bs8(0xde), no_xmm_pref] + rmmod(mm_reg, rm_arg_mm)) @@ -4331,9 +4350,9 @@ addop("sqrtss", [bs8(0x0f), bs8(0x51), pref_f3] + rmmod(xmm_reg, rm_arg_xmm_m32)) addop("pmovmskb", [bs8(0x0f), bs8(0xd7), no_xmm_pref] + - rmmod(reg, rm_arg_mm_reg)) + rmmod(reg_modrm, rm_arg_mm_reg)) addop("pmovmskb", [bs8(0x0f), bs8(0xd7), pref_66] + - rmmod(reg, rm_arg_xmm_reg)) + rmmod(reg_modrm, rm_arg_xmm_reg)) addop("shufps", [bs8(0x0f), bs8(0xc6), no_xmm_pref] + rmmod(xmm_reg, rm_arg_xmm) + [u08]) diff --git a/miasm2/arch/x86/sem.py b/miasm2/arch/x86/sem.py index ea5830e3..df5a07a0 100644 --- a/miasm2/arch/x86/sem.py +++ b/miasm2/arch/x86/sem.py @@ -3627,6 +3627,15 @@ def pslld(ir, instr, a, b): def psllq(ir, instr, a, b): return ps_rl_ll(ir, instr, a, b, "<<", 64) +def pslldq(ir, instr, a, b): + assert b.is_int() + e = [] + count = int(b) + if count > 15: + return [m2_expr.ExprAff(a, m2_expr.ExprInt(0, a.size))], [] + else: + return [m2_expr.ExprAff(a, a << m2_expr.ExprInt(8*count, a.size))], [] + def iret(ir, instr): """IRET implementation @@ -4361,6 +4370,7 @@ mnemo_func = {'mov': mov, "psllw": psllw, "pslld": pslld, "psllq": psllq, + "pslldq": pslldq, "pmaxub": pmaxub, "pmaxuw": pmaxuw, diff --git a/miasm2/ir/symbexec.py b/miasm2/ir/symbexec.py index fd8413fc..8e04c45b 100644 --- a/miasm2/ir/symbexec.py +++ b/miasm2/ir/symbexec.py @@ -126,8 +126,13 @@ class symbexec(object): ptr, size = expr.arg, expr.size ret = self.find_mem_by_addr(ptr) if not ret: - out = [] overlaps = self.get_mem_overlapping(expr) + if not overlaps: + if self.func_read and ptr.is_int(): + expr = self.func_read(expr) + return expr + + out = [] off_base = 0 for off, mem in overlaps: if off >= 0: @@ -141,48 +146,39 @@ class symbexec(object): new_off_base = off_base + new_size + off * 8 out.append((tmp, off_base, new_off_base)) off_base = new_off_base - if out: - missing_slice = self.rest_slice(out, 0, size) - for slice_start, slice_stop in missing_slice: - ptr = self.expr_simp(ptr + m2_expr.ExprInt(slice_start / 8, ptr.size)) - mem = m2_expr.ExprMem(ptr, slice_stop - slice_start) - out.append((mem, slice_start, slice_stop)) - out.sort(key=lambda x: x[1]) - args = [expr for (expr, _, _) in out] - tmp = m2_expr.ExprSlice(m2_expr.ExprCompose(*args), 0, size) - tmp = self.expr_simp(tmp) - return tmp - - - if self.func_read and isinstance(ptr, m2_expr.ExprInt): - return self.func_read(expr) - else: - return expr + + missing_slice = self.rest_slice(out, 0, size) + for slice_start, slice_stop in missing_slice: + ptr = self.expr_simp(ptr + m2_expr.ExprInt(slice_start / 8, ptr.size)) + mem = m2_expr.ExprMem(ptr, slice_stop - slice_start) + if self.func_read and ptr.is_int(): + mem = self.func_read(mem) + out.append((mem, slice_start, slice_stop)) + out.sort(key=lambda x: x[1]) + args = [expr for (expr, _, _) in out] + ret = self.expr_simp(m2_expr.ExprCompose(*args)[:size]) + return ret + # bigger lookup if size > ret.size: rest = size - ptr = ptr out = [] - ptr_index = 0 while rest: mem = self.find_mem_by_addr(ptr) if mem is None: - value = m2_expr.ExprMem(ptr, 8) - mem = value - diff_size = 8 + mem = m2_expr.ExprMem(ptr, 8) + if self.func_read and ptr.is_int(): + value = self.func_read(mem) + else: + value = mem elif rest >= mem.size: value = self.symbols[mem] - diff_size = mem.size else: - diff_size = rest - value = self.symbols[mem][0:diff_size] - out.append((value, ptr_index, ptr_index + diff_size)) - ptr_index += diff_size - rest -= diff_size + value = self.symbols[mem][:rest] + out.append(value) + rest -= value.size ptr = self.expr_simp(ptr + m2_expr.ExprInt(mem.size / 8, ptr.size)) - out.sort(key=lambda x: x[1]) - args = [expr for (expr, _, _) in out] - ret = self.expr_simp(m2_expr.ExprCompose(*args)) + ret = self.expr_simp(m2_expr.ExprCompose(*out)) return ret # part lookup ret = self.expr_simp(self.symbols[ret][:size]) @@ -406,9 +402,9 @@ class symbexec(object): for new_mem, new_val in diff_mem: self.symbols[new_mem] = new_val src_o = self.expr_simp(src) - self.symbols[dst] = src_o - if dst == src_o: - del self.symbols[dst] + if dst != src_o: + # Avoid X = X + self.symbols[dst] = src_o if isinstance(dst, m2_expr.ExprMem): if self.func_write and isinstance(dst.arg, m2_expr.ExprInt): self.func_write(self, dst, src_o) diff --git a/test/arch/x86/arch.py b/test/arch/x86/arch.py index e6797da2..b0ea7cb4 100644 --- a/test/arch/x86/arch.py +++ b/test/arch/x86/arch.py @@ -2328,6 +2328,8 @@ reg_tests = [ (m64, "00000000 MOVMSKPS EAX, XMM2", "0f50c2"), + (m64, "00000000 MOVMSKPS R8D, XMM2", + "440f50c2"), (m32, "00000000 ADDSS XMM2, DWORD PTR [ECX]", "f30f5811"), @@ -2725,6 +2727,9 @@ reg_tests = [ (m32, "00000000 PSLLW XMM6, 0x5", "660F71F605"), + (m64, "00000000 PSLLDQ XMM2, 0x1", + "660F73Fa01"), + (m32, "00000000 PSLLQ MM2, QWORD PTR [EDX]", "0FF312"), @@ -2919,6 +2924,12 @@ reg_tests = [ (m32, "00000000 PMOVMSKB EAX, XMM7", "660FD7C7"), + (m64, "XXXXXXXX PMOVMSKB R8D, XMM2", + "66440fd7c2"), + (m64, "XXXXXXXX PMOVMSKB EAX, XMM2", + "660fd7c2"), + + (m64, "00000000 SHUFPS XMM0, XMM6, 0x44", "0fc6c644"), (m64, "00000000 SHUFPD XMM0, XMM6, 0x44", diff --git a/test/arch/x86/unit/mn_cpuid.py b/test/arch/x86/unit/mn_cpuid.py new file mode 100755 index 00000000..026de207 --- /dev/null +++ b/test/arch/x86/unit/mn_cpuid.py @@ -0,0 +1,21 @@ +#! /usr/bin/env python2 + +import sys + +from asm_test import Asm_Test_32 + +class Test_CPUID(Asm_Test_32): + """Check for cpuid support (and not for arbitrary returned values)""" + TXT = ''' + main: + XOR EAX, EAX + CPUID + RET + ''' + + def check(self): + assert self.myjit.cpu.EAX == 0xa + + +if __name__ == "__main__": + [test(*sys.argv[1:])() for test in [Test_CPUID]] diff --git a/test/test_all.py b/test/test_all.py index e49ce514..ab9e4b9b 100755 --- a/test/test_all.py +++ b/test/test_all.py @@ -77,6 +77,7 @@ for script in ["x86/sem.py", "x86/unit/mn_pmovmskb.py", "x86/unit/mn_pushpop.py", "x86/unit/mn_seh.py", + "x86/unit/mn_cpuid.py", "arm/arch.py", "arm/sem.py", "aarch64/unit/mn_ubfm.py", |