diff options
| author | serpilliere <serpilliere@users.noreply.github.com> | 2018-01-27 11:44:14 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2018-01-27 11:44:14 +0100 |
| commit | 0a2934e0a0744bffa300a6e8954f95defee255be (patch) | |
| tree | 0b744ebf697cdc0fbf167f32374ecc81d7512906 | |
| parent | 06d19487a7875f6d7f0825a550f8f4eef98e3a6b (diff) | |
| parent | 095a87261cbd19188665ff185861e4745cc377f4 (diff) | |
| download | miasm-0a2934e0a0744bffa300a6e8954f95defee255be.tar.gz miasm-0a2934e0a0744bffa300a6e8954f95defee255be.zip | |
Merge pull request #663 from commial/feature-missing-sse
Add a few SSE instructions
| -rw-r--r-- | miasm2/arch/x86/arch.py | 108 | ||||
| -rw-r--r-- | miasm2/arch/x86/regs.py | 3 | ||||
| -rw-r--r-- | miasm2/arch/x86/sem.py | 46 | ||||
| -rw-r--r-- | test/arch/x86/arch.py | 11 |
4 files changed, 155 insertions, 13 deletions
diff --git a/miasm2/arch/x86/arch.py b/miasm2/arch/x86/arch.py index 55dc653b..13c06ae6 100644 --- a/miasm2/arch/x86/arch.py +++ b/miasm2/arch/x86/arch.py @@ -134,7 +134,7 @@ RBRACK = Suppress("]") dbreg = Group(gpregs16.parser | gpregs32.parser | gpregs64.parser) gpreg = (gpregs08.parser | gpregs08_64.parser | gpregs16.parser | gpregs32.parser | gpregs64.parser | gpregs_xmm.parser | - gpregs_mm.parser) + gpregs_mm.parser | gpregs_bnd.parser) def reg2exprid(r): @@ -304,7 +304,8 @@ rmarg = Group(gpregs08.parser | gpregs32.parser | gpregs64.parser | gpregs_mm.parser | - gpregs_xmm.parser + gpregs_xmm.parser | + gpregs_bnd.parser ).setParseAction(getreg) rmarg |= deref_mem @@ -1712,8 +1713,10 @@ def test_addr_size(ptr, size): SIZE2XMMREG = {64:gpregs_mm, 128:gpregs_xmm} +SIZE2BNDREG = {64:gpregs_mm, + 128:gpregs_bnd} -def parse_mem(expr, parent, w8, sx=0, xmm=0, mm=0): +def parse_mem(expr, parent, w8, sx=0, xmm=0, mm=0, bnd=0): dct_expr = {} opmode = parent.v_opmode() if expr.is_mem_segm() and expr.arg.args[0].is_int(): @@ -1780,17 +1783,23 @@ def parse_mem(expr, parent, w8, sx=0, xmm=0, mm=0): out = [dct_expr] return out, segm, True -def expr2modrm(expr, parent, w8, sx=0, xmm=0, mm=0): +def expr2modrm(expr, parent, w8, sx=0, xmm=0, mm=0, bnd=0): dct_expr = {f_isad : False} - if mm or xmm: + if mm or xmm or bnd: if mm and expr.size != 64: return None, None, False elif xmm and expr.size != 128: return None, None, False + elif bnd and expr.size != 128: + return None, None, False if isinstance(expr, ExprId): - selreg = SIZE2XMMREG[expr.size] + if bnd: + size2reg = SIZE2BNDREG + else: + size2reg = SIZE2XMMREG + selreg = size2reg[expr.size] if not expr in selreg.expr: return None, None, False i = selreg.expr.index(expr) @@ -1828,6 +1837,13 @@ def expr2modrm(expr, parent, w8, sx=0, xmm=0, mm=0): return [dct_expr], None, True else: return None, None, False + if bnd: + if expr in gpregs_bnd.expr: + i = gpregs_bnd.expr.index(expr) + dct_expr[i] = 1 + return [dct_expr], None, True + else: + return None, None, False if mm: if expr in gpregs_mm.expr: i = gpregs_mm.expr.index(expr) @@ -1858,9 +1874,9 @@ def expr2modrm(expr, parent, w8, sx=0, xmm=0, mm=0): return None, None, False dct_expr[i] = 1 return [dct_expr], None, True - return parse_mem(expr, parent, w8, sx, xmm, mm) + return parse_mem(expr, parent, w8, sx, xmm, mm, bnd) -def modrm2expr(modrm, parent, w8, sx=0, xmm=0, mm=0): +def modrm2expr(modrm, parent, w8, sx=0, xmm=0, mm=0, bnd=0): o = [] if not modrm[f_isad]: modrm_k = [x[0] for x in modrm.iteritems() if x[1] == 1] @@ -1879,6 +1895,8 @@ def modrm2expr(modrm, parent, w8, sx=0, xmm=0, mm=0): expr = gpregs_xmm.expr[modrm_k] elif mm: expr = gpregs_mm.expr[modrm_k] + elif bnd: + expr = gpregs_bnd.expr[modrm_k] elif opmode == 8 and (parent.v_opmode() == 64 or parent.rex_p.value == 1): expr = gpregs08_64.expr[modrm_k] else: @@ -1907,6 +1925,8 @@ def modrm2expr(modrm, parent, w8, sx=0, xmm=0, mm=0): opmode = 128 elif mm: opmode = 64 + elif bnd: + opmode = 128 expr = ExprMem(expr, size=opmode) return expr @@ -2326,11 +2346,12 @@ class x86_rm_mm(x86_rm_m80): msize = 64 is_mm = True is_xmm = False + is_bnd = False def decode(self, v): p = self.parent xx = self.get_modrm() - expr = modrm2expr(xx, p, 0, 0, self.is_xmm, self.is_mm) + expr = modrm2expr(xx, p, 0, 0, self.is_xmm, self.is_mm, self.is_bnd) if isinstance(expr, ExprMem): if self.msize is None: return False @@ -2356,7 +2377,8 @@ class x86_rm_mm(x86_rm_m80): elif self.is_mm: expr = ExprMem(expr.arg, 64) - v_cand, segm, ok = expr2modrm(expr, p, 0, 0, self.is_xmm, self.is_mm) + v_cand, segm, ok = expr2modrm(expr, p, 0, 0, self.is_xmm, self.is_mm, + self.is_bnd) for x in self.gen_cand(v_cand, p.v_admode()): yield x @@ -2382,6 +2404,11 @@ class x86_rm_xmm_m64(x86_rm_mm): is_mm = False is_xmm = True +class x86_rm_xmm_m128(x86_rm_mm): + msize = 128 + is_mm = False + is_xmm = True + class x86_rm_xmm_reg(x86_rm_mm): msize = None @@ -2393,6 +2420,35 @@ class x86_rm_mm_reg(x86_rm_mm): is_mm = True is_xmm = False + +class x86_rm_bnd(x86_rm_mm): + msize = 128 + is_mm = False + is_xmm = False + is_bnd = True + + +class x86_rm_bnd_reg(x86_rm_mm): + msize = None + is_mm = False + is_xmm = False + is_bnd = True + + +class x86_rm_bnd_m64(x86_rm_mm): + msize = 64 + is_mm = False + is_xmm = False + is_bnd = True + + +class x86_rm_bnd_m128(x86_rm_mm): + msize = 128 + is_mm = False + is_xmm = False + is_bnd = True + + class x86_rm_reg_noarg(object): prio = default_prio + 1 @@ -2511,6 +2567,9 @@ class x86_rm_reg_mm(x86_rm_reg_noarg, m_arg): class x86_rm_reg_xmm(x86_rm_reg_mm): selreg = gpregs_xmm +class x86_rm_reg_bnd(x86_rm_reg_mm): + selreg = gpregs_bnd + class x86_rm_reg(x86_rm_reg_noarg, m_arg): pass @@ -3196,6 +3255,7 @@ drreg = bs(l=3, cls=(x86_rm_dr, ), order =1, fname = "reg") mm_reg = bs(l=3, cls=(x86_rm_reg_mm, ), order =1, fname = "reg") xmm_reg = bs(l=3, cls=(x86_rm_reg_xmm, ), order =1, fname = "reg") +bnd_reg = bs(l=3, cls=(x86_rm_reg_bnd, ), order =1, fname = "reg") fltreg = bs(l=3, cls=(x86_rm_flt, ), order =1, fname = "reg") @@ -3226,8 +3286,15 @@ rm_arg_mm_reg = bs(l=0, cls=(x86_rm_mm_reg,), fname='rmarg') rm_arg_xmm = bs(l=0, cls=(x86_rm_xmm,), fname='rmarg') rm_arg_xmm_m32 = bs(l=0, cls=(x86_rm_xmm_m32,), fname='rmarg') rm_arg_xmm_m64 = bs(l=0, cls=(x86_rm_xmm_m64,), fname='rmarg') +rm_arg_xmm_m128 = bs(l=0, cls=(x86_rm_xmm_m128,), fname='rmarg') rm_arg_xmm_reg = bs(l=0, cls=(x86_rm_xmm_reg,), fname='rmarg') +rm_arg_bnd = bs(l=0, cls=(x86_rm_bnd,), fname='rmarg') +rm_arg_bnd_m64 = bs(l=0, cls=(x86_rm_bnd_m64,), fname='rmarg') +rm_arg_bnd_m128 = bs(l=0, cls=(x86_rm_bnd_m128,), fname='rmarg') +rm_arg_bnd_reg = bs(l=0, cls=(x86_rm_bnd_reg,), fname='rmarg') + + swapargs = bs_swapargs(l=1, fname="swap", mn_mod=range(1 << 1)) @@ -3353,6 +3420,17 @@ addop("and", [bs("100000"), se, w8] + rmmod(d4, rm_arg_w8) + [d_imm]) addop("and", [bs("001000"), swapargs, w8] + rmmod(rmreg, rm_arg_w8), [rm_arg_w8, rmreg]) +addop("bndmov", [bs8(0x0f), bs8(0x1a), pref_66, bs_modeno64] + + rmmod(bnd_reg, rm_arg_bnd_m64), [bnd_reg, rm_arg_bnd_m64]) +addop("bndmov", [bs8(0x0f), bs8(0x1a), pref_66, bs_mode64] + + rmmod(bnd_reg, rm_arg_bnd_m128), [bnd_reg, rm_arg_bnd_m128]) +addop("bndmov", [bs8(0x0f), bs8(0x1b), pref_66, bs_modeno64] + + rmmod(bnd_reg, rm_arg_bnd_m64), [rm_arg_bnd_m64, bnd_reg]) +addop("bndmov", [bs8(0x0f), bs8(0x1b), pref_66, bs_mode64] + + rmmod(bnd_reg, rm_arg_bnd_m128), [rm_arg_bnd_m128, bnd_reg]) + + + addop("bsf", [bs8(0x0f), bs8(0xbc)] + rmmod(rmreg)) addop("bsr", [bs8(0x0f), bs8(0xbd), mod, rmreg, rm, sib_scale, sib_index, sib_base, disp, rm_arg]) @@ -4140,6 +4218,11 @@ addop("cvttsd2si",[bs8(0x0f), bs8(0x2c), pref_f2] addop("cvttss2si",[bs8(0x0f), bs8(0x2c), pref_f3] + rmmod(reg, rm_arg_xmm_m32)) +addop("palignr", [bs8(0x0f), bs8(0x73), bs8(0x0f), no_xmm_pref] + + rmmod(mm_reg, rm_arg_mm_m64) + [u08], [mm_reg, rm_arg_mm_m64, u08]) +addop("palignr", [bs8(0x0f), bs8(0x3a), bs8(0x0f), pref_66] + + rmmod(xmm_reg, rm_arg_xmm_m128) + [u08], [xmm_reg, rm_arg_xmm_m128, u08]) + addop("psrlq", [bs8(0x0f), bs8(0x73), no_xmm_pref] + rmmod(d2, rm_arg_mm) + [u08], [rm_arg_mm, u08]) addop("psrlq", [bs8(0x0f), bs8(0x73), pref_66] + @@ -4251,6 +4334,11 @@ addop("pcmpeqd", [bs8(0x0f), bs8(0x76), no_xmm_pref] + addop("pcmpeqd", [bs8(0x0f), bs8(0x76), pref_66] + rmmod(xmm_reg, rm_arg_xmm)) +addop("pcmpgtb", [bs8(0x0f), bs8(0x64), no_xmm_pref] + + rmmod(mm_reg, rm_arg_mm)) +addop("pcmpgtb", [bs8(0x0f), bs8(0x64), pref_66] + + rmmod(xmm_reg, rm_arg_xmm)) + addop("pcmpgtd", [bs8(0x0f), bs8(0x66), no_xmm_pref] + rmmod(mm_reg, rm_arg_mm)) addop("pcmpgtd", [bs8(0x0f), bs8(0x66), pref_66] + diff --git a/miasm2/arch/x86/regs.py b/miasm2/arch/x86/regs.py index 5db75e37..cb7e0d7b 100644 --- a/miasm2/arch/x86/regs.py +++ b/miasm2/arch/x86/regs.py @@ -40,6 +40,8 @@ regs_xmm_expr = [ExprId(x, 128) for x in regs_xmm_str] regs_mm_str = ["MM%d" % i for i in xrange(16)] regs_mm_expr = [ExprId(x, 64) for x in regs_mm_str] +regs_bnd_str = ["BND%d" % i for i in xrange(4)] +regs_bnd_expr = [ExprId(x, 128) for x in regs_bnd_str] gpregs08 = reg_info(regs08_str, regs08_expr) gpregs08_64 = reg_info(regs08_64_str, regs08_64_expr) @@ -49,6 +51,7 @@ gpregs64 = reg_info(regs64_str, regs64_expr) gpregs_xmm = reg_info(regs_xmm_str, regs_xmm_expr) gpregs_mm = reg_info(regs_mm_str, regs_mm_expr) +gpregs_bnd = reg_info(regs_bnd_str, regs_bnd_expr) r08_eax = reg_info([regs08_str[0]], [regs08_expr[0]]) r16_eax = reg_info([regs16_str[0]], [regs16_expr[0]]) diff --git a/miasm2/arch/x86/sem.py b/miasm2/arch/x86/sem.py index f2b75d03..56aca1c2 100644 --- a/miasm2/arch/x86/sem.py +++ b/miasm2/arch/x86/sem.py @@ -2649,6 +2649,11 @@ def prefetchw(_, instr, src=None): # https://www-ssl.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-instruction-set-reference-manual-325383.pdf return [], [] +def prefetchnta(_, instr, src=None): + # see 4-201 on this documentation + # https://www-ssl.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-instruction-set-reference-manual-325383.pdf + return [], [] + def lfence(_, instr, src=None): # see 3-485 on this documentation @@ -3788,6 +3793,16 @@ def pslldq(_, instr, dst, src): return [m2_expr.ExprAff(dst, dst << m2_expr.ExprInt(8 * count, dst.size))], [] +def psrldq(_, instr, dst, src): + assert src.is_int() + e = [] + count = int(src) + if count > 15: + return [m2_expr.ExprAff(dst, m2_expr.ExprInt(0, dst.size))], [] + else: + return [m2_expr.ExprAff(dst, dst >> m2_expr.ExprInt(8 * count, dst.size))], [] + + def iret(ir, instr): """IRET implementation XXX: only support "no-privilege change" @@ -4129,6 +4144,29 @@ def smsw(ir, instr, dst): return e, [] +def bndmov(ir, instr, dst, src): + # Implemented as a NOP, because BND side effects are not yet supported + return [], [] + +def palignr(ir, instr, dst, src, imm): + # dst.src >> imm * 8 [:dst.size] + + shift = int(imm) * 8 + if shift == 0: + result = src + elif shift == src.size: + result = dst + elif shift > src.size: + result = dst >> m2_expr.ExprInt(shift - src.size, dst.size) + else: + # shift < src.size + result = m2_expr.ExprCompose( + src[shift:], + dst[:shift], + ) + + return [m2_expr.ExprAff(dst, result)], [] + mnemo_func = {'mov': mov, 'xchg': xchg, @@ -4306,6 +4344,7 @@ mnemo_func = {'mov': mov, 'prefetch1': prefetch1, 'prefetch2': prefetch2, 'prefetchw': prefetchw, + 'prefetchnta': prefetchnta, 'lfence': lfence, 'mfence': mfence, 'sfence': sfence, @@ -4483,9 +4522,7 @@ mnemo_func = {'mov': mov, "cvttss2si": cvttss2si, - - - + "bndmov": bndmov, @@ -4565,6 +4602,9 @@ mnemo_func = {'mov': mov, "pslld": pslld, "psllq": psllq, "pslldq": pslldq, + "psrldq": psrldq, + + "palignr": palignr, "pmaxub": pmaxub, "pmaxuw": pmaxuw, diff --git a/test/arch/x86/arch.py b/test/arch/x86/arch.py index 972a2e12..d3b2964c 100644 --- a/test/arch/x86/arch.py +++ b/test/arch/x86/arch.py @@ -2802,6 +2802,12 @@ reg_tests = [ (m32, "00000000 PCMPGTQ XMM0, XMM5", "660f3837C5"), + (m64, "00000000 PCMPGTB XMM8, XMM5", + "66440f64c5"), + + (m64, "00000000 PALIGNR XMM1, XMM2, 0xC", + "660f3a0fca0c"), + (m32, "00000000 PUNPCKHBW MM2, QWORD PTR [EDX]", "0F6812"), @@ -2959,6 +2965,11 @@ reg_tests = [ (m32, "00000000 AESDECLAST XMM1, XMM2", "660f38dfca"), + (m64, "00000000 BNDMOV XMMWORD PTR [RSP + 0x80], BND0", + "660f1b842480000000"), + (m64, "00000000 BNDMOV BND3, XMMWORD PTR [RSP + 0xB0]", + "660f1a9c24b0000000"), + ] |