diff options
Diffstat (limited to 'miasm/arch/x86/arch.py')
| -rw-r--r-- | miasm/arch/x86/arch.py | 4878 |
1 files changed, 0 insertions, 4878 deletions
diff --git a/miasm/arch/x86/arch.py b/miasm/arch/x86/arch.py deleted file mode 100644 index 5464a779..00000000 --- a/miasm/arch/x86/arch.py +++ /dev/null @@ -1,4878 +0,0 @@ -#-*- coding:utf-8 -*- - -from __future__ import print_function -from builtins import range -import re - -from future.utils import viewitems - -from miasm.core import utils -from miasm.expression.expression import * -from pyparsing import * -from miasm.core.cpu import * -from collections import defaultdict -import miasm.arch.x86.regs as regs_module -from miasm.arch.x86.regs import * -from miasm.core.asm_ast import AstNode, AstInt, AstId, AstMem, AstOp -from miasm.ir.ir import color_expr_html -from miasm.core.utils import BRACKET_O, BRACKET_C - - -log = logging.getLogger("x86_arch") -console_handler = logging.StreamHandler() -console_handler.setFormatter(logging.Formatter("[%(levelname)-8s]: %(message)s")) -log.addHandler(console_handler) -log.setLevel(logging.WARN) - -conditional_branch = ["JO", "JNO", "JB", "JAE", - "JZ", "JNZ", "JBE", "JA", - "JS", "JNS", "JPE", "JNP", - #"L", "NL", "NG", "G"] - "JL", "JGE", "JLE", "JG", - "JCXZ", "JECXZ", "JRCXZ"] - -unconditional_branch = ['JMP', 'JMPF'] - -f_isad = "AD" -f_s08 = "S08" -f_u08 = "U08" -f_s16 = "S16" -f_u16 = "U16" -f_s32 = "S32" -f_u32 = "U32" -f_s64 = "S64" -f_u64 = "U64" -f_imm = 'IMM' - -f_imm2size = {f_s08: 8, f_s16: 16, f_s32: 32, f_s64: 64, - f_u08: 8, f_u16: 16, f_u32: 32, f_u64: 64} - - -size2gpregs = {8: gpregs08, 16: gpregs16, - 32: gpregs32, 64: gpregs64} - - -replace_regs64 = { - AL: RAX[:8], CL: RCX[:8], DL: RDX[:8], BL: RBX[:8], - AH: RAX[8:16], CH: RCX[8:16], DH: RDX[8:16], BH: RBX[8:16], - SPL: RSP[0:8], BPL: RBP[0:8], SIL: RSI[0:8], DIL: RDI[0:8], - R8B: R8[0:8], R9B: R9[0:8], R10B: R10[0:8], R11B: R11[0:8], - R12B: R12[0:8], R13B: R13[0:8], R14B: R14[0:8], R15B: R15[0:8], - - AX: RAX[:16], CX: RCX[:16], DX: RDX[:16], BX: RBX[:16], - SP: RSP[:16], BP: RBP[:16], SI: RSI[:16], DI: RDI[:16], - R8W: R8[:16], R9W: R9[:16], R10W: R10[:16], R11W: R11[:16], - R12W: R12[:16], R13W: R13[:16], R14W: R14[:16], R15W: R15[:16], - - EAX: RAX[:32], ECX: RCX[:32], EDX: RDX[:32], EBX: RBX[:32], - ESP: RSP[:32], EBP: RBP[:32], ESI: RSI[:32], EDI: RDI[:32], - R8D: R8[:32], R9D: R9[:32], R10D: R10[:32], R11D: R11[:32], - R12D: R12[:32], R13D: R13[:32], R14D: R14[:32], R15D: R15[:32], - - IP: RIP[:16], EIP: RIP[:32], - - ExprId("ST", 64): float_st0, - ExprId("ST(0)", 64): float_st0, - ExprId("ST(1)", 64): float_st1, - ExprId("ST(2)", 64): float_st2, - ExprId("ST(3)", 64): float_st3, - ExprId("ST(4)", 64): float_st4, - ExprId("ST(5)", 64): float_st5, - ExprId("ST(6)", 64): float_st6, - ExprId("ST(7)", 64): float_st7, - -} - -replace_regs32 = { - AL: EAX[:8], CL: ECX[:8], DL: EDX[:8], BL: EBX[:8], - AH: EAX[8:16], CH: ECX[8:16], DH: EDX[8:16], BH: EBX[8:16], - - AX: EAX[:16], CX: ECX[:16], DX: EDX[:16], BX: EBX[:16], - SP: ESP[:16], BP: EBP[:16], SI: ESI[:16], DI: EDI[:16], - - IP: EIP[:16], - - - ExprId("ST", 64): float_st0, - ExprId("ST(0)", 64): float_st0, - ExprId("ST(1)", 64): float_st1, - ExprId("ST(2)", 64): float_st2, - ExprId("ST(3)", 64): float_st3, - ExprId("ST(4)", 64): float_st4, - ExprId("ST(5)", 64): float_st5, - ExprId("ST(6)", 64): float_st6, - ExprId("ST(7)", 64): float_st7, - -} - -replace_regs16 = { - AL: AX[:8], CL: CX[:8], DL: DX[:8], BL: BX[:8], - AH: AX[8:16], CH: CX[8:16], DH: DX[8:16], BH: BX[8:16], - - AX: AX[:16], CX: CX[:16], DX: DX[:16], BX: BX[:16], - SP: SP[:16], BP: BP[:16], SI: SI[:16], DI: DI[:16], - - - ExprId("ST", 64): float_st0, - ExprId("ST(0)", 64): float_st0, - ExprId("ST(1)", 64): float_st1, - ExprId("ST(2)", 64): float_st2, - ExprId("ST(3)", 64): float_st3, - ExprId("ST(4)", 64): float_st4, - ExprId("ST(5)", 64): float_st5, - ExprId("ST(6)", 64): float_st6, - ExprId("ST(7)", 64): float_st7, - -} - -replace_regs = {16: replace_regs16, - 32: replace_regs32, - 64: replace_regs64} - - -segm2enc = {CS: 1, SS: 2, DS: 3, ES: 4, FS: 5, GS: 6} -enc2segm = dict((value, key) for key, value in viewitems(segm2enc)) - -segm_info = reg_info_dct(enc2segm) - - - -enc2crx = { - 0: cr0, - 1: cr1, - 2: cr2, - 3: cr3, - 4: cr4, - 5: cr5, - 6: cr6, - 7: cr7, -} - -crx_info = reg_info_dct(enc2crx) - - -enc2drx = { - 0: dr0, - 1: dr1, - 2: dr2, - 3: dr3, - 4: dr4, - 5: dr5, - 6: dr6, - 7: dr7, -} - -drx_info = reg_info_dct(enc2drx) - - - -# parser helper ########### -PLUS = Suppress("+") -MULT = Suppress("*") - -COLON = Suppress(":") - - -LBRACK = Suppress("[") -RBRACK = Suppress("]") - - -gpreg = ( - gpregs08.parser | - gpregs08_64.parser | - gpregs16.parser | - gpregs32.parser | - gpregs64.parser | - gpregs_xmm.parser | - gpregs_mm.parser | - gpregs_bnd.parser -) - - -def is_op_segm(expr): - """Returns True if is ExprOp and op == 'segm'""" - return expr.is_op('segm') - -def is_mem_segm(expr): - """Returns True if is ExprMem and ptr is_op_segm""" - return expr.is_mem() and is_op_segm(expr.ptr) - - -def cb_deref_segmoff(tokens): - assert len(tokens) == 2 - return AstOp('segm', tokens[0], tokens[1]) - - -def cb_deref_base_expr(tokens): - tokens = tokens[0] - assert isinstance(tokens, AstNode) - addr = tokens - return addr - - -deref_mem_ad = (LBRACK + base_expr + RBRACK).setParseAction(cb_deref_base_expr) - -deref_ptr = (base_expr + COLON + base_expr).setParseAction(cb_deref_segmoff) - - -PTR = Suppress('PTR') - -FAR = Suppress('FAR') - - -BYTE = Literal('BYTE') -WORD = Literal('WORD') -DWORD = Literal('DWORD') -QWORD = Literal('QWORD') -TBYTE = Literal('TBYTE') -XMMWORD = Literal('XMMWORD') - -MEMPREFIX2SIZE = {'BYTE': 8, 'WORD': 16, 'DWORD': 32, - 'QWORD': 64, 'TBYTE': 80, 'XMMWORD': 128} - -SIZE2MEMPREFIX = dict((value, key) for key, value in viewitems(MEMPREFIX2SIZE)) - -def cb_deref_mem(tokens): - if len(tokens) == 2: - s, ptr = tokens - assert isinstance(ptr, AstNode) - return AstMem(ptr, MEMPREFIX2SIZE[s]) - elif len(tokens) == 3: - s, segm, ptr = tokens - return AstMem(AstOp('segm', segm, ptr), MEMPREFIX2SIZE[s]) - raise ValueError('len(tokens) > 3') - -mem_size = (BYTE | DWORD | QWORD | WORD | TBYTE | XMMWORD) -deref_mem = (mem_size + PTR + Optional((base_expr + COLON))+ deref_mem_ad).setParseAction(cb_deref_mem) - - -rmarg = ( - gpregs08.parser | - gpregs08_64.parser | - gpregs16.parser | - gpregs32.parser | - gpregs64.parser | - gpregs_mm.parser | - gpregs_xmm.parser | - gpregs_bnd.parser -) - -rmarg |= deref_mem - - -mem_far = FAR + deref_mem - - -cl_or_imm = r08_ecx.parser -cl_or_imm |= base_expr - - - -class x86_arg(m_arg): - def asm_ast_to_expr(self, value, loc_db, size_hint=None, fixed_size=None): - if size_hint is None: - size_hint = self.parent.mode - if fixed_size is None: - fixed_size = set() - if isinstance(value, AstId): - if value.name in all_regs_ids_byname: - reg = all_regs_ids_byname[value.name] - fixed_size.add(reg.size) - return reg - if isinstance(value.name, ExprId): - fixed_size.add(value.name.size) - return value.name - if value.name in MEMPREFIX2SIZE: - return None - if value.name in ["FAR"]: - return None - - loc_key = loc_db.get_or_create_name_location(value.name) - return ExprLoc(loc_key, size_hint) - if isinstance(value, AstOp): - # First pass to retrieve fixed_size - if value.op == "segm": - segm = self.asm_ast_to_expr(value.args[0], loc_db) - ptr = self.asm_ast_to_expr(value.args[1], loc_db, None, fixed_size) - return ExprOp('segm', segm, ptr) - args = [self.asm_ast_to_expr(arg, loc_db, None, fixed_size) for arg in value.args] - if len(fixed_size) == 0: - # No fixed size - pass - elif len(fixed_size) == 1: - # One fixed size, regen all - size = list(fixed_size)[0] - args = [self.asm_ast_to_expr(arg, loc_db, size, fixed_size) for arg in value.args] - else: - raise ValueError("Size conflict") - if None in args: - return None - return ExprOp(value.op, *args) - if isinstance(value, AstInt): - if 1 << size_hint < value.value: - size_hint *= 2 - return ExprInt(value.value, size_hint) - if isinstance(value, AstMem): - fixed_size.add(value.size) - ptr = self.asm_ast_to_expr(value.ptr, loc_db, None, set()) - if ptr is None: - return None - return ExprMem(ptr, value.size) - return None - -class r_al(reg_noarg, x86_arg): - reg_info = r08_eax - parser = reg_info.parser - - -class r_ax(reg_noarg, x86_arg): - reg_info = r16_eax - parser = reg_info.parser - - -class r_dx(reg_noarg, x86_arg): - reg_info = r16_edx - parser = reg_info.parser - - -class r_eax(reg_noarg, x86_arg): - reg_info = r32_eax - parser = reg_info.parser - - -class r_rax(reg_noarg, x86_arg): - reg_info = r64_eax - parser = reg_info.parser - - -class r_cl(reg_noarg, x86_arg): - reg_info = r08_ecx - parser = reg_info.parser - - -invmode = {16: 32, 32: 16} - - -def opmode_prefix(mode): - size, opmode, admode = mode - if size in [16, 32]: - if opmode: - return invmode[size] - else: - return size - elif size == 64: - if opmode: - return 16 - else: - return 32 - raise NotImplementedError('not fully functional') - - -def admode_prefix(mode): - size, opmode, admode = mode - if size in [16, 32]: - if admode: - return invmode[size] - else: - return size - elif size == 64: - return 64 - raise NotImplementedError('not fully functional') - - -def v_opmode_info(size, opmode, rex_w, stk): - if size in [16, 32]: - if opmode: - return invmode[size] - else: - return size - elif size == 64: - # Rex has the maximum priority - # Then opmode - # Then stacker - if rex_w == 1: - return 64 - elif opmode == 1: - return 16 - elif stk: - return 64 - else: - return 32 - - -def v_opmode(p): - stk = hasattr(p, 'stk') - return v_opmode_info(p.mode, p.opmode, p.rex_w.value, stk) - - -def v_admode_info(size, admode): - if size in [16, 32]: - if admode: - return invmode[size] - else: - return size - elif size == 64: - if admode == 1: - return 32 - return 64 - - -def v_admode(p): - return v_admode_info(p.mode, p.admode) - - -def offsize(p): - if p.opmode: - return 16 - else: - return p.mode - - -def get_prefix(s): - g = re.search(r'(\S+)(\s+)', s) - if not g: - return None, s - prefix, b = g.groups() - return prefix, s[len(prefix) + len(b):] - - -repeat_mn = ["INS", "OUTS", - "MOVSB", "MOVSW", "MOVSD", "MOVSQ", - "SCASB", "SCASW", "SCASD", "SCASQ", - "LODSB", "LODSW", "LODSD", "LODSQ", - "STOSB", "STOSW", "STOSD", "STOSQ", - "CMPSB", "CMPSW", "CMPSD", "CMPSQ", - ] - - -class group(object): - - def __init__(self): - self.value = None - - -class additional_info(object): - - def __init__(self): - self.except_on_instr = False - self.g1 = group() - self.g2 = group() - self.vopmode = None - self.stk = False - self.v_opmode = None - self.v_admode = None - self.prefixed = b'' - - -class instruction_x86(instruction): - __slots__ = [] - - def __init__(self, *args, **kargs): - super(instruction_x86, self).__init__(*args, **kargs) - - def v_opmode(self): - return self.additional_info.v_opmode - - def v_admode(self): - return self.additional_info.v_admode - - def dstflow(self): - if self.name in conditional_branch + unconditional_branch: - return True - if self.name.startswith('LOOP'): - return True - return self.name in ['CALL'] - - def dstflow2label(self, loc_db): - if self.additional_info.g1.value & 14 and self.name in repeat_mn: - return - expr = self.args[0] - if not expr.is_int(): - return - addr = (int(expr) + int(self.offset)) & int(expr.mask) - loc_key = loc_db.get_or_create_offset_location(addr) - self.args[0] = ExprLoc(loc_key, expr.size) - - def breakflow(self): - if self.name in conditional_branch + unconditional_branch: - return True - if self.name.startswith('LOOP'): - return True - if self.name.startswith('RET'): - return True - if self.name.startswith('INT'): - return True - if self.name.startswith('SYS'): - return True - return self.name in ['CALL', 'HLT', 'IRET', 'IRETD', 'IRETQ', 'ICEBP', 'UD2'] - - def splitflow(self): - if self.name in conditional_branch: - return True - if self.name in unconditional_branch: - return False - if self.name.startswith('LOOP'): - return True - if self.name.startswith('INT'): - return True - if self.name.startswith('SYS'): - return True - return self.name in ['CALL'] - - def setdstflow(self, a): - return - - def is_subcall(self): - return self.name in ['CALL'] - - def getdstflow(self, loc_db): - if self.additional_info.g1.value & 14 and self.name in repeat_mn: - addr = int(self.offset) - loc_key = loc_db.get_or_create_offset_location(addr) - return [ExprLoc(loc_key, self.v_opmode())] - return [self.args[0]] - - def get_symbol_size(self, symbol, loc_db): - return self.mode - - def fixDstOffset(self): - expr = self.args[0] - if self.offset is None: - raise ValueError('symbol not resolved %s' % l) - if not isinstance(expr, ExprInt): - log.warning('dynamic dst %r', expr) - return - self.args[0] = ExprInt(int(expr) - self.offset, self.mode) - - def get_info(self, c): - self.additional_info.g1.value = c.g1.value - self.additional_info.g2.value = c.g2.value - self.additional_info.stk = hasattr(c, 'stk') - self.additional_info.v_opmode = c.v_opmode() - self.additional_info.v_admode = c.v_admode() - self.additional_info.prefix = c.prefix - self.additional_info.prefixed = getattr(c, "prefixed", b"") - - def __str__(self): - return self.to_string() - - def to_string(self, loc_db=None): - o = super(instruction_x86, self).to_string(loc_db) - if self.additional_info.g1.value & 1: - o = "LOCK %s" % o - if self.additional_info.g1.value & 2: - if getattr(self.additional_info.prefixed, 'default', b"") != b"\xF2": - o = "REPNE %s" % o - if self.additional_info.g1.value & 8: - if getattr(self.additional_info.prefixed, 'default', b"") != b"\xF3": - o = "REP %s" % o - elif self.additional_info.g1.value & 4: - if getattr(self.additional_info.prefixed, 'default', b"") != b"\xF3": - o = "REPE %s" % o - return o - - def to_html(self, loc_db=None): - o = super(instruction_x86, self).to_html(loc_db) - if self.additional_info.g1.value & 1: - text = utils.set_html_text_color("LOCK", utils.COLOR_MNEMO) - o = "%s %s" % (text, o) - if self.additional_info.g1.value & 2: - if getattr(self.additional_info.prefixed, 'default', b"") != b"\xF2": - text = utils.set_html_text_color("REPNE", utils.COLOR_MNEMO) - o = "%s %s" % (text, o) - if self.additional_info.g1.value & 8: - if getattr(self.additional_info.prefixed, 'default', b"") != b"\xF3": - text = utils.set_html_text_color("REP", utils.COLOR_MNEMO) - o = "%s %s" % (text, o) - elif self.additional_info.g1.value & 4: - if getattr(self.additional_info.prefixed, 'default', b"") != b"\xF3": - text = utils.set_html_text_color("REPE", utils.COLOR_MNEMO) - o = "%s %s" % (text, o) - return o - - - def get_args_expr(self): - args = [] - for a in self.args: - a = a.replace_expr(replace_regs[self.mode]) - args.append(a) - return args - - @staticmethod - def arg2str(expr, index=None, loc_db=None): - if expr.is_id() or expr.is_int(): - o = str(expr) - elif expr.is_loc(): - if loc_db is not None: - o = loc_db.pretty_str(expr.loc_key) - else: - o = str(expr) - elif ((isinstance(expr, ExprOp) and expr.op == 'far' and - isinstance(expr.args[0], ExprMem)) or - isinstance(expr, ExprMem)): - if isinstance(expr, ExprOp): - prefix, expr = "FAR ", expr.args[0] - else: - prefix = "" - sz = SIZE2MEMPREFIX[expr.size] - segm = "" - if is_mem_segm(expr): - segm = "%s:" % expr.ptr.args[0] - expr = expr.ptr.args[1] - else: - expr = expr.ptr - if isinstance(expr, ExprOp): - s = str(expr).replace('(', '').replace(')', '') - else: - s = str(expr) - o = prefix + sz + ' PTR ' + str(segm) + '[%s]' % s - elif isinstance(expr, ExprOp) and expr.op == 'segm': - o = "%s:%s" % (expr.args[0], expr.args[1]) - else: - raise ValueError('check this %r' % expr) - return "%s" % o - - - @staticmethod - def arg2html(expr, index=None, loc_db=None): - if expr.is_id() or expr.is_int() or expr.is_loc(): - o = color_expr_html(expr, loc_db) - elif ((isinstance(expr, ExprOp) and expr.op == 'far' and - isinstance(expr.args[0], ExprMem)) or - isinstance(expr, ExprMem)): - if isinstance(expr, ExprOp): - prefix, expr = "FAR ", expr.args[0] - else: - prefix = "" - sz = SIZE2MEMPREFIX[expr.size] - sz = '<font color="%s">%s</font>' % (utils.COLOR_MEM, sz) - segm = "" - if is_mem_segm(expr): - segm = "%s:" % expr.ptr.args[0] - expr = expr.ptr.args[1] - else: - expr = expr.ptr - if isinstance(expr, ExprOp): - s = color_expr_html(expr, loc_db)#.replace('(', '').replace(')', '') - else: - s = color_expr_html(expr, loc_db) - o = prefix + sz + ' PTR ' + str(segm) + BRACKET_O + str(s) + BRACKET_C - elif isinstance(expr, ExprOp) and expr.op == 'segm': - o = "%s:%s" % ( - color_expr_html(expr.args[0], loc_db), - color_expr_html(expr.args[1], loc_db) - ) - else: - raise ValueError('check this %r' % expr) - return "%s" % o - - - -class mn_x86(cls_mn): - name = "x86" - prefix_op_size = False - prefix_ad_size = False - regs = regs_module - all_mn = [] - all_mn_mode = defaultdict(list) - all_mn_name = defaultdict(list) - all_mn_inst = defaultdict(list) - bintree = {} - num = 0 - delayslot = 0 - pc = {16: IP, 32: EIP, 64: RIP} - sp = {16: SP, 32: ESP, 64: RSP} - instruction = instruction_x86 - max_instruction_len = 15 - - @classmethod - def getpc(cls, attrib): - return cls.pc[attrib] - - @classmethod - def getsp(cls, attrib): - return cls.sp[attrib] - - def v_opmode(self): - if hasattr(self, 'stk'): - stk = 1 - else: - stk = 0 - return v_opmode_info(self.mode, self.opmode, self.rex_w.value, stk) - - def v_admode(self): - size, opmode, admode = self.mode, self.opmode, self.admode - if size in [16, 32]: - if admode: - return invmode[size] - else: - return size - elif size == 64: - if admode == 1: - return 32 - return 64 - - def additional_info(self): - info = additional_info() - info.g1.value = self.g1.value - info.g2.value = self.g2.value - info.stk = hasattr(self, 'stk') - info.v_opmode = self.v_opmode() - info.prefixed = b"" - if hasattr(self, 'prefixed'): - info.prefixed = self.prefixed.default - return info - - @classmethod - def check_mnemo(cls, fields): - pass - - @classmethod - def getmn(cls, name): - return name.upper() - - @classmethod - def mod_fields(cls, fields): - prefix = [d_g1, d_g2, d_rex_p, d_rex_w, d_rex_r, d_rex_x, d_rex_b, d_vex, d_vex_l, d_vex_p, d_vex_v, d_vex_m] - return prefix + fields - - @classmethod - def gen_modes(cls, subcls, name, bases, dct, fields): - dct['mode'] = None - return [(subcls, name, bases, dct, fields)] - - @classmethod - def fromstring(cls, text, loc_db, mode): - pref = 0 - prefix, new_s = get_prefix(text) - if prefix == "LOCK": - pref |= 1 - text = new_s - elif prefix == "REPNE" or prefix == "REPNZ": - pref |= 2 - text = new_s - elif prefix == "REPE" or prefix == "REPZ": - pref |= 4 - text = new_s - elif prefix == "REP": - pref |= 8 - text = new_s - c = super(mn_x86, cls).fromstring(text, loc_db, mode) - c.additional_info.g1.value = pref - return c - - @classmethod - def pre_dis(cls, v, mode, offset): - offset_o = offset - pre_dis_info = {'opmode': 0, - 'admode': 0, - 'g1': 0, - 'g2': 0, - 'rex_p': 0, - 'rex_w': 0, - 'rex_r': 0, - 'rex_x': 0, - 'rex_b': 0, - 'vex_l': 0, - 'vex_p': 0, - 'vex_v': 0, - 'vex_m': 0, - 'vex' : 0, - 'prefix': b"", - 'prefixed': b"", - } - while True: - c = v.getbytes(offset) - if c == b'\x66': - pre_dis_info['opmode'] = 1 - elif c == b'\x67': - pre_dis_info['admode'] = 1 - elif c == b'\xf0': - pre_dis_info['g1'] = 1 - elif c == b'\xf2': - pre_dis_info['g1'] = 2 - elif c == b'\xf3': - pre_dis_info['g1'] = 12 - - elif c == b'\x2e': - pre_dis_info['g2'] = 1 - elif c == b'\x36': - pre_dis_info['g2'] = 2 - elif c == b'\x3e': - pre_dis_info['g2'] = 3 - elif c == b'\x26': - pre_dis_info['g2'] = 4 - elif c == b'\x64': - pre_dis_info['g2'] = 5 - elif c == b'\x65': - pre_dis_info['g2'] = 6 - - else: - break - pre_dis_info['prefix'] += c - offset += 1 - vex3_prefix = b'\xc4' - vex2_prefix = b'\xc5' - rex_prefixes = b'@ABCDEFGHIJKLMNO' - if mode == 64 and c in rex_prefixes: - while c in rex_prefixes: - # multiple REX prefixes case - use last REX prefix - x = ord(c) - offset += 1 - c = v.getbytes(offset) - pre_dis_info['rex_p'] = 1 - pre_dis_info['rex_w'] = (x >> 3) & 1 - pre_dis_info['rex_r'] = (x >> 2) & 1 - pre_dis_info['rex_x'] = (x >> 1) & 1 - pre_dis_info['rex_b'] = (x >> 0) & 1 - elif mode == 64 and c == vex3_prefix: - offset += 1 - c = ord(v.getbytes(offset)) - pre_dis_info['vex'] = 1 - pre_dis_info['rex_r'] = ((c >> 7) ^ 1) & 1 - pre_dis_info['rex_x'] = ((c >> 6) ^ 1) & 1 - pre_dis_info['rex_b'] = ((c >> 5) ^ 1) & 1 - pre_dis_info['vex_m'] = (c & int('0b11111', 2)) - - offset += 1 - c = ord(v.getbytes(offset)) - pre_dis_info['rex_w'] = (c >> 7) & 1 - pre_dis_info['vex_v'] = ((c >> 3) ^ 15) & 15 - pre_dis_info['vex_l'] = (c >> 2) & 1 - pre_dis_info['vex_p'] = c & int('0b11', 2) - offset += 1 - - if pre_dis_info['vex_p'] == 1: - pre_dis_info['opmode'] = 1 - elif pre_dis_info['vex_p'] == 3: - pre_dis_info['g1'] = 2 - elif pre_dis_info['vex_p'] == 2: - pre_dis_info['g1'] = 12 - - elif mode == 64 and c == vex2_prefix and v.getlen() > 2: - offset += 1 - c = ord(v.getbytes(offset)) - pre_dis_info['vex'] = 1 - pre_dis_info['rex_r'] = ((c >> 7) ^ 1) & 1 - pre_dis_info['rex_x'] = 0 - pre_dis_info['rex_b'] = 0 - pre_dis_info['rex_w'] = 0 - pre_dis_info['vex_l'] = (c >> 2) & 1 - pre_dis_info['vex_p'] = c & int('0b11', 2) - offset += 1 - - if pre_dis_info['vex_p'] == 1: - pre_dis_info['opmode'] = 1 - elif pre_dis_info['vex_p'] == 3: - pre_dis_info['g1'] = 2 - elif pre_dis_info['vex_p'] == 2: - pre_dis_info['g1'] = 12 - - elif pre_dis_info.get('g1', None) == 12 and c in [b'\xa6', b'\xa7', b'\xae', b'\xaf']: - pre_dis_info['g1'] = 4 - return pre_dis_info, v, mode, offset, offset - offset_o - - @classmethod - def get_cls_instance(cls, cc, mode, infos=None): - for opmode in [0, 1]: - for admode in [0, 1]: - c = cc() - c.init_class() - - c.reset_class() - c.add_pre_dis_info() - c.dup_info(infos) - c.mode = mode - c.opmode = opmode - c.admode = admode - - if not hasattr(c, 'stk') and hasattr(c, "fopmode") and c.fopmode.mode == 64: - c.rex_w.value = 1 - yield c - - def post_dis(self): - if self.g2.value: - for a in self.args: - if not isinstance(a.expr, ExprMem): - continue - m = a.expr - a.expr = ExprMem( - ExprOp('segm', enc2segm[self.g2.value], m.ptr), m.size) - return self - - def dup_info(self, infos): - if infos is not None: - self.g1.value = infos.g1.value - self.g2.value = infos.g2.value - - def reset_class(self): - super(mn_x86, self).reset_class() - if hasattr(self, "opmode"): - del(self.opmode) - if hasattr(self, "admode"): - del(self.admode) - - def add_pre_dis_info(self, pre_dis_info=None): - if pre_dis_info is None: - return True - if hasattr(self, "prefixed") and self.prefixed.default == b"\x66": - pre_dis_info['opmode'] = 0 - self.opmode = pre_dis_info['opmode'] - self.admode = pre_dis_info['admode'] - - if hasattr(self, 'no_xmm_pref') and\ - pre_dis_info['prefix'] and\ - pre_dis_info['prefix'][-1] in b'\x66\xf2\xf3': - return False - if (hasattr(self, "prefixed") and - not pre_dis_info['prefix'].endswith(self.prefixed.default)): - return False - if (self.rex_w.value is not None and - self.rex_w.value != pre_dis_info['rex_w']): - return False - else: - self.rex_w.value = pre_dis_info['rex_w'] - self.rex_r.value = pre_dis_info['rex_r'] - self.rex_b.value = pre_dis_info['rex_b'] - self.rex_x.value = pre_dis_info['rex_x'] - self.rex_p.value = pre_dis_info['rex_p'] - - self.vex.value = pre_dis_info['vex'] - self.vex_l.value = pre_dis_info['vex_l'] - self.vex_p.value = pre_dis_info['vex_p'] - self.vex_v.value = pre_dis_info['vex_v'] - self.vex_m.value = pre_dis_info['vex_m'] - - if hasattr(self, 'no_rex') and\ - (self.rex_r.value or self.rex_b.value or - self.rex_x.value or self.rex_p.value): - return False - - if self.vex.value == 0 and (hasattr(self, 'pref_0f') - or hasattr(self, 'pref_0f38') - or hasattr(self, 'pref_0f3a')): - return False - - if hasattr(self, 'no_rep') and b'\xf3' in pre_dis_info['prefix']: - return False - - if self.vex_m.value == 1 and not hasattr(self, 'pref_0f'): - return False - if self.vex_m.value == 2 and not hasattr(self, 'pref_0f38'): - return False - if self.vex_m.value == 3 and not hasattr(self, 'pref_0f3a'): - return False - - self.g1.value = pre_dis_info['g1'] - self.g2.value = pre_dis_info['g2'] - self.prefix = pre_dis_info['prefix'] - return True - - def post_asm(self, v): - return v - - - def gen_prefix(self): - v = b"" - rex = 0x40 - if self.g1.value is None: - self.g1.value = 0 - if self.g2.value is None: - self.g2.value = 0 - - if self.rex_w.value: - rex |= 0x8 - if self.rex_r.value: - rex |= 0x4 - if self.rex_x.value: - rex |= 0x2 - if self.rex_b.value: - rex |= 0x1 - if (rex != 0x40 and not self.vex.value) or self.rex_p.value == 1: - v = utils.int_to_byte(rex) + v - if hasattr(self, 'no_rex'): - return None - - vex_byte1 = 0xc4 - vex_byte2 = 0x00 - vex_byte3 = 0x00 - - m_prefix = [field.fname for field in self.fields_order if 'pref_0f' in field.fname] - if m_prefix: - if m_prefix[0] == 'pref_0f': - vex_byte2 |= 0x01 - elif m_prefix[0] == 'pref_0f38': - vex_byte2 |= 0x02 - elif m_prefix[0] == 'pref_0f3a': - vex_byte2 |= 0x03 - - # TODO: L and p - if m_prefix and m_prefix[0] == 'pref_0f' and not self.rex_w.value and not self.rex_b.value and ((hasattr(self, 'mod') and self.mod.value == 3) or not self.rex_x.value): # VEX2 - print("test") - vex_version = 2 - vex_byte1 = 0x00 - vex_byte2 = 0xc5 - - if not hasattr(self, 'reg') or not self.rex_r.value: - vex_byte3 |= 0x80 - - else: - vex_version = 3 - if not hasattr(self, 'reg') or not self.rex_r.value: - vex_byte2 |= 0x80 - if (hasattr(self, 'mod') and self.mod.value == 3) or not self.rex_x.value: - vex_byte2 |= 0x40 - if not self.rex_b.value: - vex_byte2 |= 0x20 - - if self.rex_w.value: - vex_byte3 |= 0x80 - - if self.vex.value == 1: - vex_byte3 |= ((15 - self.vex_v.value) << 3) - vex = (vex_byte1 << 16) | (vex_byte2 << 8) | vex_byte3 - v = vex.to_bytes(vex_version, 'big') + v - - if hasattr(self, 'prefixed'): - v = self.prefixed.default + v - - if self.g1.value & 1: - v = b"\xf0" + v - if self.g1.value & 2: - if hasattr(self, 'no_xmm_pref'): - return None - v = b"\xf2" + v - if self.g1.value & 12: - if hasattr(self, 'no_xmm_pref'): - return None - v = b"\xf3" + v - if self.g2.value: - v = { - 1: b'\x2e', - 2: b'\x36', - 3: b'\x3e', - 4: b'\x26', - 5: b'\x64', - 6: b'\x65' - }[self.g2.value] + v - # mode prefix - if hasattr(self, "admode") and self.admode: - v = b"\x67" + v - - if hasattr(self, "opmode") and self.opmode: - if hasattr(self, 'no_xmm_pref'): - return None - v = b"\x66" + v - return v - - def encodefields(self, decoded): - v = super(mn_x86, self).encodefields(decoded) - prefix = self.gen_prefix() - if prefix is None: - return None - return prefix + v - - def getnextflow(self, loc_db): - raise NotImplementedError('not fully functional') - - def ir_pre_instruction(self): - return [ExprAssign(mRIP[self.mode], - ExprInt(self.offset + self.l, mRIP[self.mode].size))] - - @classmethod - def filter_asm_candidates(cls, instr, candidates): - - cand_same_mode = [] - cand_diff_mode = [] - out = [] - for c, v in candidates: - if (hasattr(c, 'no_xmm_pref') and - (c.g1.value & 2 or c.g1.value & 4 or c.g1.value & 8 or c.opmode)): - continue - if hasattr(c, "fopmode") and v_opmode(c) != c.fopmode.mode: - continue - if hasattr(c, "fadmode") and v_admode(c) != c.fadmode.mode: - continue - # relative dstflow must not have opmode set - # (assign IP instead of EIP for instance) - if (instr.dstflow() and - instr.name not in ["JCXZ", "JECXZ", "JRCXZ"] and - len(instr.args) == 1 and - isinstance(instr.args[0], ExprInt) and c.opmode): - continue - - out.append((c, v)) - candidates = out - for c, v in candidates: - if v_opmode(c) == instr.mode: - cand_same_mode += v - for c, v in candidates: - if v_opmode(c) != instr.mode: - cand_diff_mode += v - cand_same_mode.sort(key=len) - cand_diff_mode.sort(key=len) - return cand_same_mode + cand_diff_mode - - -class bs_modname_size(bs_divert): - prio = 1 - - def divert(self, i, candidates): - out = [] - for candidate in candidates: - cls, name, bases, dct, fields = candidate - fopmode = opmode_prefix( - (dct['mode'], dct['opmode'], dct['admode'])) - mode = dct['mode'] - size, opmode, admode = dct['mode'], dct['opmode'], dct['admode'] - # no mode64 exinstance in name means no 64bit version of mnemo - if mode == 64: - if mode in self.args['name']: - nfields = fields[:] - f, i = getfieldindexby_name(nfields, 'rex_w') - f = bs("1", l=0, cls=(bs_fbit,), fname="rex_w") - osize = v_opmode_info(size, opmode, 1, 0) - nfields[i] = f - nfields = nfields[:-1] - ndct = dict(dct) - if osize in self.args['name']: - ndct['name'] = self.args['name'][osize] - out.append((cls, ndct['name'], bases, ndct, nfields)) - - nfields = fields[:] - nfields = nfields[:-1] - f, i = getfieldindexby_name(nfields, 'rex_w') - f = bs("0", l=0, cls=(bs_fbit,), fname="rex_w") - osize = v_opmode_info(size, opmode, 0, 0) - nfields[i] = f - ndct = dict(dct) - if osize in self.args['name']: - ndct['name'] = self.args['name'][osize] - out.append((cls, ndct['name'], bases, ndct, nfields)) - else: - l = opmode_prefix((dct['mode'], dct['opmode'], dct['admode'])) - osize = v_opmode_info(size, opmode, None, 0) - nfields = fields[:-1] - ndct = dict(dct) - if osize in self.args['name']: - ndct['name'] = self.args['name'][osize] - out.append((cls, ndct['name'], bases, ndct, nfields)) - return out - - -class bs_modname_jecx(bs_divert): - prio = 1 - - def divert(self, i, candidates): - out = [] - for candidate in candidates: - cls, name, bases, dct, fields = candidate - fopmode = opmode_prefix( - (dct['mode'], dct['opmode'], dct['admode'])) - mode = dct['mode'] - size, opmode, admode = dct['mode'], dct['opmode'], dct['admode'] - - nfields = fields[:] - nfields = nfields[:-1] - args = dict(self.args) - ndct = dict(dct) - if mode == 64: - if admode: - ndct['name'] = "JECXZ" - else: - ndct['name'] = "JRCXZ" - elif mode == 32: - if admode: - ndct['name'] = "JCXZ" - else: - ndct['name'] = "JECXZ" - elif mode == 16: - if admode: - ndct['name'] = "JECXZ" - else: - ndct['name'] = "JCXZ" - else: - raise ValueError('unhandled mode') - out.append((cls, ndct['name'], bases, ndct, nfields)) - return out - - -class bs_modname_mode(bs_divert): - prio = 1 - - def divert(self, i, candidates): - out = [] - for candidate in candidates: - cls, name, bases, dct, fields = candidate - fopmode = opmode_prefix( - (dct['mode'], dct['opmode'], dct['admode'])) - size, opmode, admode = dct['mode'], dct['opmode'], dct['admode'] - - mode = dct['mode'] - l = opmode_prefix((dct['mode'], dct['opmode'], dct['admode'])) - osize = v_opmode_info(size, opmode, None, 0) - nfields = fields[:-1] - args = dict(self.args) - ndct = dict(dct) - if mode == 64 or osize == 32: - ndct['name'] = self.args['name'][mode] - else: - ndct['name'] = self.args['name'][16] - out.append((cls, ndct['name'], bases, ndct, nfields)) - return out - - -class x86_imm(imm_noarg): - parser = base_expr - - def decodeval(self, v): - return swap_uint(self.l, v) - - def encodeval(self, v): - return swap_uint(self.l, v) - - -class x86_imm_fix_08(imm_noarg): - parser = base_expr - intsize = 8 - intmask = (1 << intsize) - 1 - - def decodeval(self, v): - return self.ival - - def encode(self): - v = self.expr2int(self.expr) - if v != self.ival: - return False - self.value = 0 - return True - - -class x86_08(x86_imm): - intsize = 8 - intmask = (1 << intsize) - 1 - - -class x86_16(x86_imm): - intsize = 16 - intmask = (1 << intsize) - 1 - - -class x86_32(x86_imm): - intsize = 32 - intmask = (1 << intsize) - 1 - - -class x86_64(x86_imm): - intsize = 64 - intmask = (1 << intsize) - 1 - - -class x86_08_ne(x86_imm): - intsize = 8 - intmask = (1 << intsize) - 1 - - def encode(self): - return True - - def decode(self, v): - v = swap_uint(self.l, v) - p = self.parent - admode = p.v_admode() - value = sign_ext(v, self.intsize, admode) - self.expr = ExprInt(value, admode) - return True - - -class x86_16_ne(x86_08_ne): - intsize = 16 - intmask = (1 << intsize) - 1 - - -class x86_32_ne(x86_08_ne): - intsize = 32 - intmask = (1 << intsize) - 1 - - -class x86_64_ne(x86_08_ne): - intsize = 64 - intmask = (1 << intsize) - 1 - - -class x86_s08to16(x86_imm): - in_size = 8 - out_size = 16 - - def myexpr(self, x): - return ExprInt(x, 16) - - def int2expr(self, v): - return self.myexpr(v) - - def expr2int(self, e): - if not isinstance(e, ExprInt): - return None - v = int(e) - if v & ~((1 << self.l) - 1) != 0: - return None - return v - - def decode(self, v): - v = v & self.lmask - v = self.decodeval(v) - if self.parent.v_opmode() == 64: - self.expr = ExprInt(sign_ext(v, self.in_size, 64), 64) - else: - if (1 << (self.l - 1)) & v: - v = sign_ext(v, self.l, self.out_size) - self.expr = self.myexpr(v) - return True - - def encode(self): - if not isinstance(self.expr, ExprInt): - return False - v = int(self.expr) - opmode = self.parent.v_opmode() - - out_size = self.out_size - if opmode != self.out_size: - if opmode == 32 and self.out_size == 64: - out_size = opmode - if v == sign_ext( - int(v & ((1 << self.in_size) - 1)), self.in_size, out_size): - pass - else: - # test with rex_w - self.parent.rex_w.value = 1 - opmode = self.parent.v_opmode() - out_size = opmode - if (v != sign_ext( - int(v & ((1 << self.in_size) - 1)), - self.in_size, out_size)): - return False - if v != sign_ext( - int(v & ((1 << self.in_size) - 1)), self.in_size, out_size): - return False - v = self.encodeval(v) - self.value = (v & 0xffffffff) & self.lmask - return True - - def decodeval(self, v): - return swap_uint(self.l, v) - - def encodeval(self, v): - return swap_sint(self.l, v) - - -class x86_s08to32(x86_s08to16): - in_size = 8 - out_size = 32 - - def myexpr(self, x): - return ExprInt(x, 32) - - def decode(self, v): - v = v & self.lmask - v = self.decodeval(v) - if self.parent.rex_w.value == 1: - v = ExprInt(sign_ext(v, self.in_size, 64), 64) - else: - v = ExprInt(sign_ext(v, self.in_size, 32), 32) - - self.expr = v - return True - - -class x86_s08to64(x86_s08to32): - in_size = 8 - out_size = 64 - - def myexpr(self, x): - return ExprInt(x, 64) - - -class x86_s32to64(x86_s08to32): - in_size = 32 - out_size = 64 - - def myexpr(self, x): - return ExprInt(x, 64) - - -class bs_eax(x86_arg): - reg_info = r_eax_all - rindex = 0 - parser = reg_info.parser - - def decode(self, v): - p = self.parent - expr = None - if hasattr(p, 'w8') and p.w8.value == 0: - expr = regs08_expr[self.rindex] - else: - expr = size2gpregs[p.v_opmode()].expr[self.rindex] - self.expr = expr - return True - - def encode(self): - self.value = 0 - p = self.parent - expr = self.expr - osize = p.v_opmode() - if hasattr(p, 'w8'): - if p.w8.value is None: - # XXX TODO: priority in w8 erase? - if expr.size == 8: - p.w8.value = 0 - else: - p.w8.value = 1 - if hasattr(p, 'w8') and p.w8.value == 0: - return expr == regs08_expr[self.rindex] - elif p.mode in [16, 32]: - return expr == size2gpregs[osize].expr[self.rindex] - elif p.mode == 64: - if expr == size2gpregs[64].expr[self.rindex]: - p.rex_w.value = 1 - return True - elif expr == size2gpregs[osize].expr[self.rindex]: - return True - return False - return False - -class bs_seg(x86_arg): - reg_info = r_eax_all - rindex = 0 - parser = reg_info.parser - - def decode(self, v): - self.expr = self.reg_info.expr[0] - return True - - def encode(self): - self.value = 0 - return self.expr == self.reg_info.expr[0] - - -class bs_edx(bs_eax): - reg_info = r_edx_all - rindex = 2 - parser = reg_info.parser - - -class bs_st(bs_eax): - reg_info = r_st_all - rindex = 0 - parser = reg_info.parser - - -class bs_cs(bs_seg): - reg_info = r_cs_all - rindex = 0 - parser = reg_info.parser - - -class bs_ds(bs_seg): - reg_info = r_ds_all - rindex = 0 - parser = reg_info.parser - - -class bs_es(bs_seg): - reg_info = r_es_all - rindex = 0 - parser = reg_info.parser - - -class bs_ss(bs_seg): - reg_info = r_ss_all - rindex = 0 - parser = reg_info.parser - - -class bs_fs(bs_seg): - reg_info = r_fs_all - rindex = 0 - parser = reg_info.parser - - -class bs_gs(bs_seg): - reg_info = r_gs_all - rindex = 0 - parser = reg_info.parser - - -class x86_reg_st(reg_noarg, x86_arg): - reg_info = r_st_all - parser = reg_info.parser - - -class bs_sib_scale(bs_divert): - bsname = "sib_scale" - - def divert(self, i, candidates): - out = [] - done = False - for cls, name, bases, dct, fields in candidates: - if (not (admode_prefix( - (dct['mode'], dct['opmode'], dct['admode'])) != 16 and - 'rm' in dct and dct['rm'] == 0b100 and - 'mod' in dct and dct['mod'] != 0b11)): - ndct = dict(dct) - nfields = fields[:] - nfields[i] = None - ndct[self.args['fname']] = None - out.append((cls, ndct['name'], bases, ndct, nfields)) - continue - - nfields = fields[:] - args = dict(self.args) - ndct = dict(dct) - f = bs(**args) - nfields[i] = f - ndct[self.args['fname']] = None - out.append((cls, ndct['name'], bases, ndct, nfields)) - return out - - -class bs_sib_index(bs_sib_scale): - pass - - -class bs_sib_base(bs_sib_scale): - pass - - -class bs_disp(bs_divert): - - def divert(self, i, candidates): - out = [] - done = False - for cls, name, bases, dct, fields in candidates: - ndct = dict(dct) - nfields = fields[:] - if (admode_prefix( - (dct['mode'], dct['opmode'], dct['admode'])) == 16): - if 'mod' in dct and dct['mod'] == 0b00 and \ - 'rm' in dct and dct['rm'] == 0b110: - nfields[i] = bs( - l=16, cls=(x86_16_ne,), fname=self.args['fname']) - ndct[self.args['fname']] = True - out.append((cls, ndct['name'], bases, ndct, nfields)) - continue - elif 'mod' in dct and dct['mod'] == 0b01: - nfields[i] = bs( - l=8, cls=(x86_08_ne,), fname=self.args['fname']) - ndct[self.args['fname']] = True - out.append((cls, ndct['name'], bases, ndct, nfields)) - continue - elif 'mod' in dct and dct['mod'] == 0b10: - nfields[i] = bs( - l=16, cls=(x86_16_ne,), fname=self.args['fname']) - ndct[self.args['fname']] = True - out.append((cls, ndct['name'], bases, ndct, nfields)) - continue - else: - if 'mod' in dct and dct['mod'] == 0b00 and \ - 'rm' in dct and dct['rm'] == 0b101: - nfields[i] = bs( - l=32, cls=(x86_32_ne,), fname=self.args['fname']) - ndct[self.args['fname']] = True - out.append((cls, ndct['name'], bases, ndct, nfields)) - continue - elif 'mod' in dct and dct['mod'] == 0b01: - nfields[i] = bs( - l=8, cls=(x86_08_ne,), fname=self.args['fname']) - ndct[self.args['fname']] = True - out.append((cls, ndct['name'], bases, ndct, nfields)) - continue - elif 'mod' in dct and dct['mod'] == 0b10: - nfields[i] = bs( - l=32, cls=(x86_32_ne,), fname=self.args['fname']) - ndct[self.args['fname']] = True - out.append((cls, ndct['name'], bases, ndct, nfields)) - continue - - nfields[i] = None - ndct[self.args['fname']] = None - out.append((cls, ndct['name'], bases, ndct, nfields)) - return out - - -def getmodrm(c): - return (c >> 6) & 3, (c >> 3) & 7, c & 7 - - -def setmodrm(mod, re, rm): - return ((mod & 3) << 6) | ((re & 7) << 3) | (rm & 7) - - -def sib(c): - return modrm(c) - -db_afs_64 = [] -sib_64_s08_ebp = [] - - -def gen_modrm_form(): - global db_afs_64, sib_64_s08_ebp - ebp = 5 - - sib_s08_ebp = [{f_isad: True} for i in range(0x100)] - sib_u32_ebp = [{f_isad: True} for i in range(0x100)] - sib_u32 = [{f_isad: True} for i in range(0x100)] - - sib_u64 = [] - for rex_x in range(2): - o = [] - for rex_b in range(2): - x = [{f_isad: True} for i in range(0x100)] - o.append(x) - sib_u64.append(o) - - sib_u64_ebp = [] - for rex_x in range(2): - o = [] - for rex_b in range(2): - x = [{f_isad: True} for i in range(0x100)] - o.append(x) - sib_u64_ebp.append(o) - - sib_64_s08_ebp = [] - for rex_x in range(2): - o = [] - for rex_b in range(2): - x = [{f_isad: True} for i in range(0x100)] - o.append(x) - sib_64_s08_ebp.append(o) - - for sib_rez in [sib_s08_ebp, - sib_u32_ebp, - sib_u32, - sib_64_s08_ebp, - sib_u64_ebp, - sib_u64, - ]: - for index in range(0x100): - ss, i, b = getmodrm(index) - - if b == 0b101: - if sib_rez == sib_s08_ebp: - sib_rez[index][f_imm] = f_s08 - sib_rez[index][ebp] = 1 - elif sib_rez == sib_u32_ebp: - sib_rez[index][f_imm] = f_u32 - sib_rez[index][ebp] = 1 - elif sib_rez == sib_u32: - sib_rez[index][f_imm] = f_u32 - elif sib_rez == sib_u64_ebp: - for rex_b in range(2): - for rex_x in range(2): - sib_rez[rex_x][rex_b][index][f_imm] = f_u32 - sib_rez[rex_x][rex_b][index][ebp + 8 * rex_b] = 1 - elif sib_rez == sib_u64: - for rex_b in range(2): - for rex_x in range(2): - sib_rez[rex_x][rex_b][index][f_imm] = f_u32 - elif sib_rez == sib_64_s08_ebp: - for rex_b in range(2): - for rex_x in range(2): - sib_rez[rex_x][rex_b][index][f_imm] = f_s08 - sib_rez[rex_x][rex_b][index][ebp + 8 * rex_b] = 1 - - else: - if sib_rez == sib_s08_ebp: - sib_rez[index][b] = 1 - sib_rez[index][f_imm] = f_s08 - elif sib_rez == sib_u32_ebp: - sib_rez[index][b] = 1 - sib_rez[index][f_imm] = f_u32 - elif sib_rez == sib_u32: - sib_rez[index][b] = 1 - elif sib_rez == sib_u64_ebp: - for rex_b in range(2): - for rex_x in range(2): - sib_rez[rex_x][rex_b][index][b + 8 * rex_b] = 1 - sib_rez[rex_x][rex_b][index][f_imm] = f_u32 - elif sib_rez == sib_u64: - for rex_b in range(2): - for rex_x in range(2): - sib_rez[rex_x][rex_b][index][b + 8 * rex_b] = 1 - elif sib_rez == sib_64_s08_ebp: - for rex_b in range(2): - for rex_x in range(2): - sib_rez[rex_x][rex_b][index][f_imm] = f_s08 - sib_rez[rex_x][rex_b][index][b + 8 * rex_b] = 1 - - if i == 0b100 and sib_rez in [sib_s08_ebp, sib_u32_ebp, sib_u32]: - continue - - if sib_rez in [sib_s08_ebp, sib_u32_ebp, sib_u32]: - tmp = i - if not tmp in sib_rez[index]: - sib_rez[index][tmp] = 0 # 1 << ss - sib_rez[index][tmp] += 1 << ss - else: - for rex_b in range(2): - for rex_x in range(2): - tmp = i + 8 * rex_x - if i == 0b100 and rex_x == 0: - continue - if not tmp in sib_rez[rex_x][rex_b][index]: - sib_rez[rex_x][rex_b][index][tmp] = 0 # 1 << ss - sib_rez[rex_x][rex_b][index][tmp] += 1 << ss - - # 32bit - db_afs_32 = [None for i in range(0x100)] - for i in range(0x100): - index = i - mod, re, rm = getmodrm(i) - - if mod == 0b00: - if rm == 0b100: - db_afs_32[index] = sib_u32 - elif rm == 0b101: - db_afs_32[index] = {f_isad: True, f_imm: f_u32} - else: - db_afs_32[index] = {f_isad: True, rm: 1} - elif mod == 0b01: - if rm == 0b100: - db_afs_32[index] = sib_s08_ebp - continue - tmp = {f_isad: True, rm: 1, f_imm: f_s08} - db_afs_32[index] = tmp - - elif mod == 0b10: - if rm == 0b100: - db_afs_32[index] = sib_u32_ebp - else: - db_afs_32[index] = {f_isad: True, rm: 1, f_imm: f_u32} - elif mod == 0b11: - db_afs_32[index] = {f_isad: False, rm: 1} - - # 64bit - db_afs_64 = [None for i in range(0x400)] - for i in range(0x400): - index = i - rex_x = (index >> 9) & 1 - rex_b = (index >> 8) & 1 - mod, re, rm = getmodrm(i & 0xff) - - if mod == 0b00: - if rm == 0b100: - db_afs_64[i] = sib_u64[rex_x][rex_b] - elif rm == 0b101: - db_afs_64[i] = {f_isad: True, f_imm: f_u32, 16: 1} - else: - db_afs_64[i] = {f_isad: True, rm + 8 * rex_b: 1} - elif mod == 0b01: - if rm == 0b100: - db_afs_64[i] = sib_64_s08_ebp[rex_x][rex_b] - continue - tmp = {f_isad: True, rm + 8 * rex_b: 1, f_imm: f_s08} - db_afs_64[i] = tmp - - elif mod == 0b10: - if rm == 0b100: - db_afs_64[i] = sib_u64_ebp[rex_x][rex_b] - else: - db_afs_64[i] = {f_isad: True, rm + 8 * rex_b: 1, f_imm: f_u32} - elif mod == 0b11: - db_afs_64[i] = {f_isad: False, rm + 8 * rex_b: 1} - - # 16bit - db_afs_16 = [None for i in range(0x100)] - _si = 6 - _di = 7 - _bx = 3 - _bp = 5 - for i in range(0x100): - index = i - mod, re, rm = getmodrm(i) - - if mod == 0b00: - if rm == 0b100: - db_afs_16[index] = {f_isad: True, _si: 1} - elif rm == 0b101: - db_afs_16[index] = {f_isad: True, _di: 1} - elif rm == 0b110: - db_afs_16[index] = { - f_isad: True, f_imm: f_u16} # {f_isad:True,_bp:1} - elif rm == 0b111: - db_afs_16[index] = {f_isad: True, _bx: 1} - else: - db_afs_16[index] = {f_isad: True, - [_si, _di][rm % 2]: 1, - [_bx, _bp][(rm >> 1) % 2]: 1} - elif mod in [0b01, 0b10]: - if mod == 0b01: - my_imm = f_s08 - else: - my_imm = f_u16 - - if rm == 0b100: - db_afs_16[index] = {f_isad: True, _si: 1, f_imm: my_imm} - elif rm == 0b101: - db_afs_16[index] = {f_isad: True, _di: 1, f_imm: my_imm} - elif rm == 0b110: - db_afs_16[index] = {f_isad: True, _bp: 1, f_imm: my_imm} - elif rm == 0b111: - db_afs_16[index] = {f_isad: True, _bx: 1, f_imm: my_imm} - else: - db_afs_16[index] = {f_isad: True, - [_si, _di][rm % 2]: 1, - [_bx, _bp][(rm >> 1) % 2]: 1, - f_imm: my_imm} - - elif mod == 0b11: - db_afs_16[index] = {f_isad: False, rm: 1} - - byte2modrm = {} - byte2modrm[16] = db_afs_16 - byte2modrm[32] = db_afs_32 - byte2modrm[64] = db_afs_64 - - modrm2byte = {16: defaultdict(list), - 32: defaultdict(list), - 64: defaultdict(list), - } - for size, db_afs in viewitems(byte2modrm): - for i, modrm in enumerate(db_afs): - if not isinstance(modrm, list): - # We only need sort for determinism - modrm = tuple(sorted(viewitems(modrm), key=str)) - modrm2byte[size][modrm].append(i) - continue - for j, modrm_f in enumerate(modrm): - # We only need sort for determinism - modrm_f = tuple(sorted(viewitems(modrm_f), key=str)) - modrm2byte[size][modrm_f].append((i, j)) - - return byte2modrm, modrm2byte - -byte2modrm, modrm2byte = gen_modrm_form() - - -# ret is modr; ret is displacement -def exprfindmod(e, o=None): - if o is None: - o = {} - if isinstance(e, ExprInt): - return e - if isinstance(e, ExprId): - i = size2gpregs[e.size].expr.index(e) - o[i] = 1 - return None - elif isinstance(e, ExprOp): - out = None - if e.op == '+': - for a in e.args: - r = exprfindmod(a, o) - if out and r: - raise ValueError('multiple displacement!') - out = r - return out - elif e.op == "*": - mul = int(e.args[1]) - a = e.args[0] - i = size2gpregs[a.size].expr.index(a) - o[i] = mul - else: - raise ValueError('bad op') - return None - -def test_addr_size(ptr, size): - if isinstance(ptr, ExprInt): - return int(ptr) < (1 << size) - else: - return ptr.size == 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, bnd=0): - dct_expr = {} - opmode = parent.v_opmode() - if is_mem_segm(expr) and expr.ptr.args[0].is_int(): - return None, None, False - - if is_mem_segm(expr): - segm = expr.ptr.args[0] - ptr = expr.ptr.args[1] - else: - segm = None - ptr = expr.ptr - - dct_expr[f_isad] = True - ad_size = ptr.size - admode = parent.v_admode() - if not test_addr_size(ptr, admode): - return None, None, False - - if (w8 == 1 and expr.size != opmode and not sx and - not (hasattr(parent, 'sd') or hasattr(parent, 'wd'))): - return None, None, False - - if hasattr(parent, 'wd'): - if expr.size == 16: - parent.wd.value = 1 - elif expr.size == 32: - pass - else: - return None, None, False - - if (not isinstance(ptr, ExprInt) and - parent.mode == 64 and - ptr.size == 32 and - parent.admode != 1): - return None, None, False - dct_expr = {f_isad: True} - disp = exprfindmod(ptr, dct_expr) - out = [] - if disp is None: - # add 0 disp - disp = ExprInt(0, 32) - if disp is not None: - for signed, encoding, cast_size in [(True, f_s08, 8), - (True, f_s16, 16), - (True, f_s32, 32), - (False, f_u08, 8), - (False, f_u16, 16), - (False, f_u32, 32)]: - value = ExprInt(int(disp), cast_size) - if admode < value.size: - if signed: - if int(disp) != sign_ext(int(value), admode, disp.size): - continue - else: - if int(disp) != int(value): - continue - else: - if int(disp) != sign_ext(int(value), value.size, admode): - continue - x1 = dict(dct_expr) - x1[f_imm] = (encoding, value) - out.append(x1) - else: - out = [dct_expr] - return out, segm, True - -def expr2modrm(expr, parent, w8, sx=0, xmm=0, mm=0, bnd=0): - dct_expr = {f_isad : False} - - 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): - 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) - dct_expr[i] = 1 - return [dct_expr], None, True - else: - return parse_mem(expr, parent, w8, sx, xmm, mm) - - elif expr.size == 64 and expr not in gpregs_mm.expr: - if hasattr(parent, 'sd'): - parent.sd.value = 1 - elif hasattr(parent, 'wd'): - pass - elif hasattr(parent, 'stk'): - pass - else: - parent.rex_w.value = 1 - opmode = parent.v_opmode() - if sx == 1: - opmode = 16 - if sx == 2: - opmode = 32 - if expr.size == 8 and w8 != 0: - return None, None, False - - if w8 == 0 and expr.size != 8: - return None, None, False - - if not isinstance(expr, ExprMem): - dct_expr[f_isad] = False - if xmm: - if expr in gpregs_xmm.expr: - i = gpregs_xmm.expr.index(expr) - dct_expr[i] = 1 - 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) - dct_expr[i] = 1 - return [dct_expr], None, True - else: - return None, None, False - if w8 == 0: - if parent.mode == 64 and expr in gpregs08_64.expr: - r = gpregs08_64 - parent.rex_p.value = 1 - else: - parent.rex_p.value = 0 - parent.rex_x.value = 0 - r = size2gpregs[8] - if not expr in r.expr: - return None, None, False - i = r.expr.index(expr) - dct_expr[i] = 1 - return [dct_expr], None, True - if opmode != expr.size: - return None, None, False - if not expr in size2gpregs[opmode].expr: - return None, None, False - i = size2gpregs[opmode].expr.index(expr) - if i > 7: - if parent.mode != 64: - return None, None, False - dct_expr[i] = 1 - return [dct_expr], None, True - return parse_mem(expr, parent, w8, sx, xmm, mm, bnd) - -def modrm2expr(modrm, parent, w8, sx=0, xmm=0, mm=0, bnd=0): - o = [] - if not modrm[f_isad]: - modrm_k = [key for key, value in viewitems(modrm) if value == 1] - if len(modrm_k) != 1: - raise ValueError('strange reg encoding %r' % modrm) - modrm_k = modrm_k[0] - if w8 == 0: - opmode = 8 - elif sx == 1: - opmode = 16 - elif sx == 2: - opmode = 32 - else: - opmode = parent.v_opmode() - if xmm: - 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: - expr = size2gpregs[opmode].expr[modrm_k] - return expr - admode = parent.v_admode() - opmode = parent.v_opmode() - for modrm_k, scale in viewitems(modrm): - if isinstance(modrm_k, int): - expr = size2gpregs[admode].expr[modrm_k] - if scale != 1: - expr = ExprInt(scale, admode) * expr - o.append(expr) - if f_imm in modrm: - if parent.disp.value is None: - return None - o.append(ExprInt(int(parent.disp.expr), admode)) - if len(o) == 1: - expr = o[0] - else: - expr = ExprOp('+', *o) - if w8 == 0: - opmode = 8 - elif sx == 1: - opmode = 16 - elif sx == 2: - opmode = 32 - if xmm: - opmode = 128 - elif mm: - opmode = 64 - elif bnd: - opmode = 128 - - expr = ExprMem(expr, size=opmode) - return expr - - -class x86_rm_arg(x86_arg): - parser = rmarg - - def fromstring(self, text, loc_db, parser_result=None): - start, stop = super(x86_rm_arg, self).fromstring(text, loc_db, parser_result) - p = self.parent - if start is None: - return None, None - return start, stop - - def get_modrm(self): - p = self.parent - admode = p.v_admode() - - if not admode in [16, 32, 64]: - raise ValueError('strange admode %r', admode) - v = setmodrm(p.mod.value, 0, p.rm.value) - v |= p.rex_b.value << 8 - v |= p.rex_x.value << 9 - if p.mode == 64: - # XXXx to check - admode = 64 - - xx = byte2modrm[admode][v] - if isinstance(xx, list): - if not p.sib_scale: - return False - v = setmodrm(p.sib_scale.value, - p.sib_index.value, - p.sib_base.value) - xx = xx[v] - return xx - - def decode(self, v): - p = self.parent - xx = self.get_modrm() - self.expr = modrm2expr(xx, p, 1) - return self.expr is not None - - def gen_cand(self, v_cand, admode): - if not admode in modrm2byte: - # XXX TODO: 64bit - return - if not v_cand: - return - - p = self.parent - o_rex_x = p.rex_x.value - o_rex_b = p.rex_b.value - # add candidate without 0 imm - new_v_cand = [] - moddd = False - for v in v_cand: - new_v_cand.append(v) - if f_imm in v and int(v[f_imm][1]) == 0: - v = dict(v) - del(v[f_imm]) - new_v_cand.append(v) - moddd = True - - v_cand = new_v_cand - - out_c = [] - for v in v_cand: - disp = None - # patch value in modrm - if f_imm in v: - size, disp = v[f_imm] - disp = int(disp) - - v[f_imm] = size - vo = v - # We only need sort for determinism - v = tuple(sorted(viewitems(v), key=str)) - admode = 64 if p.mode == 64 else admode - if not v in modrm2byte[admode]: - continue - xx = modrm2byte[admode][v] - - # default case - for x in xx: - if type(x) == tuple: - modrm, sib = x - else: - modrm = x - sib = None - - # 16 bit cannot have sib - if sib is not None and admode == 16: - continue - rex = modrm >> 8 # 0# XXX HACK REM temporary REX modrm>>8 - if rex and admode != 64: - continue - - p.rex_x.value = (rex >> 1) & 1 - p.rex_b.value = rex & 1 - - if o_rex_x is not None and p.rex_x.value != o_rex_x: - continue - if o_rex_b is not None and p.rex_b.value != o_rex_b: - continue - - mod, re, rm = getmodrm(modrm) - # check re on parent - if hasattr(p, 'reg') and re != p.reg.value: - continue - - if sib is not None: - s_scale, s_index, s_base = getmodrm(sib) - else: - s_scale, s_index, s_base = None, None, None - - p.mod.value = mod - p.rm.value = rm - p.sib_scale.value = s_scale - p.sib_index.value = s_index - p.sib_base.value = s_base - p.disp.value = disp - if disp is not None: - p.disp.l = f_imm2size[vo[f_imm]] - - yield True - - return - - def encode(self): - if isinstance(self.expr, ExprInt): - return - p = self.parent - admode = p.v_admode() - mode = self.expr.size - v_cand, segm, ok = expr2modrm(self.expr, p, 1) - if segm: - p.g2.value = segm2enc[segm] - for x in self.gen_cand(v_cand, admode): - yield x - -class x86_rm_mem(x86_rm_arg): - def fromstring(self, text, loc_db, parser_result=None): - self.expr = None - start, stop = super(x86_rm_mem, self).fromstring(text, loc_db, parser_result) - if not isinstance(self.expr, ExprMem): - return None, None - return start, stop - - -class x86_rm_mem_far(x86_rm_arg): - parser = mem_far - def fromstring(self, text, loc_db, parser_result=None): - self.expr = None - start, stop = super(x86_rm_mem_far, self).fromstring(text, loc_db, parser_result) - if not isinstance(self.expr, ExprMem): - return None, None - self.expr = ExprOp('far', self.expr) - return start, stop - - def decode(self, v): - ret = super(x86_rm_mem_far, self).decode(v) - if not ret: - return ret - if isinstance(self.expr, m2_expr.ExprMem): - self.expr = ExprOp('far', self.expr) - return True - - def encode(self): - if not (isinstance(self.expr, m2_expr.ExprOp) and - self.expr.op == 'far'): - return - - expr = self.expr.args[0] - if isinstance(expr, ExprInt): - return - p = self.parent - admode = p.v_admode() - mode = expr.size - v_cand, segm, ok = expr2modrm(expr, p, 1) - if segm: - p.g2.value = segm2enc[segm] - for x in self.gen_cand(v_cand, admode): - yield x - -class x86_rm_w8(x86_rm_arg): - - def decode(self, v): - p = self.parent - xx = self.get_modrm() - self.expr = modrm2expr(xx, p, p.w8.value) - return self.expr is not None - - def encode(self): - if isinstance(self.expr, ExprInt): - return - p = self.parent - if p.w8.value is None: - if self.expr.size == 8: - p.w8.value = 0 - else: - p.w8.value = 1 - - v_cand, segm, ok = expr2modrm(self.expr, p, p.w8.value) - if segm: - p.g2.value = segm2enc[segm] - for x in self.gen_cand(v_cand, p.v_admode()): - yield x - - -class x86_rm_sx(x86_rm_arg): - - def decode(self, v): - p = self.parent - xx = self.get_modrm() - self.expr = modrm2expr(xx, p, p.w8.value, 1) - return self.expr is not None - - def encode(self): - if isinstance(self.expr, ExprInt): - return - p = self.parent - if p.w8.value is None: - if self.expr.size == 8: - p.w8.value = 0 - else: - p.w8.value = 1 - v_cand, segm, ok = expr2modrm(self.expr, p, p.w8.value, 1) - if segm: - p.g2.value = segm2enc[segm] - for x in self.gen_cand(v_cand, p.v_admode()): - yield x - - -class x86_rm_sxd(x86_rm_arg): - - def decode(self, v): - p = self.parent - xx = self.get_modrm() - self.expr = modrm2expr(xx, p, 1, 2) - return self.expr is not None - - def encode(self): - if isinstance(self.expr, ExprInt): - return - p = self.parent - v_cand, segm, ok = expr2modrm(self.expr, p, 1, 2) - if segm: - p.g2.value = segm2enc[segm] - for x in self.gen_cand(v_cand, p.v_admode()): - yield x - - -class x86_rm_sd(x86_rm_arg): - out_size = 64 - def get_s_value(self): - return self.parent.sd.value - def set_s_value(self, value): - self.parent.sd.value = value - - def decode(self, v): - p = self.parent - xx = self.get_modrm() - expr = modrm2expr(xx, p, 1) - if not isinstance(expr, ExprMem): - return False - if self.get_s_value() == 0: - expr = ExprMem(expr.ptr, 32) - else: - expr = ExprMem(expr.ptr, self.out_size) - self.expr = expr - return self.expr is not None - - def encode(self): - if isinstance(self.expr, ExprInt): - return - p = self.parent - if not self.expr.size in [32, 64]: - return - self.set_s_value(0) - v_cand, segm, ok = expr2modrm(self.expr, p, 1) - for x in self.gen_cand(v_cand, p.v_admode()): - yield x - - -class x86_rm_wd(x86_rm_sd): - out_size = 16 - def get_s_value(self): - return self.parent.wd.value - def set_s_value(self, value): - self.parent.wd.value = value - - def encode(self): - if isinstance(self.expr, ExprInt): - return - p = self.parent - p.wd.value = 0 - v_cand, segm, ok = expr2modrm(self.expr, p, 1) - for x in self.gen_cand(v_cand, p.v_admode()): - yield x - - -class x86_rm_08(x86_rm_arg): - msize = 8 - - def decode(self, v): - p = self.parent - xx = self.get_modrm() - expr = modrm2expr(xx, p, 0) - if not isinstance(expr, ExprMem): - self.expr = expr - return True - self.expr = ExprMem(expr.ptr, self.msize) - return self.expr is not None - - def encode(self): - if isinstance(self.expr, ExprInt): - return - p = self.parent - v_cand, segm, ok = expr2modrm(self.expr, p, 0, 0, 0, 0) - for x in self.gen_cand(v_cand, p.v_admode()): - yield x - -class x86_rm_reg_m08(x86_rm_arg): - msize = 8 - - def decode(self, v): - ret = x86_rm_arg.decode(self, v) - if not ret: - return ret - if not isinstance(self.expr, ExprMem): - return True - self.expr = ExprMem(self.expr.ptr, self.msize) - return self.expr is not None - - def encode(self): - if isinstance(self.expr, ExprInt): - return - p = self.parent - if isinstance(self.expr, ExprMem): - expr = ExprMem(self.expr.ptr, 32) - else: - expr = self.expr - v_cand, segm, ok = expr2modrm(expr, p, 1, 0, 0, 0) - for x in self.gen_cand(v_cand, p.v_admode()): - yield x - -class x86_rm_reg_m16(x86_rm_reg_m08): - msize = 16 - -class x86_rm_m64(x86_rm_arg): - msize = 64 - - def decode(self, v): - p = self.parent - xx = self.get_modrm() - expr = modrm2expr(xx, p, 1) - if not isinstance(expr, ExprMem): - return False - self.expr = ExprMem(expr.ptr, self.msize) - return self.expr is not None - - def encode(self): - if isinstance(self.expr, ExprInt): - return - p = self.parent - v_cand, segm, ok = expr2modrm(self.expr, p, 0, 0, 0, 1) - for x in self.gen_cand(v_cand, p.v_admode()): - yield x - - -class x86_rm_m80(x86_rm_m64): - msize = 80 - - def encode(self): - if isinstance(self.expr, ExprInt): - return - if not isinstance(self.expr, ExprMem) or self.expr.size != self.msize: - return - p = self.parent - mode = p.mode - if mode == 64: - mode = 32 - self.expr = ExprMem(self.expr.ptr, mode) - v_cand, segm, ok = expr2modrm(self.expr, p, 1) - for x in self.gen_cand(v_cand, p.v_admode()): - yield x - - -class x86_rm_m08(x86_rm_arg): - msize = 8 - - def decode(self, v): - p = self.parent - xx = self.get_modrm() - self.expr = modrm2expr(xx, p, 0) - return self.expr is not None - - def encode(self): - if self.expr.size != 8: - return - p = self.parent - mode = p.mode - v_cand, segm, ok = expr2modrm(self.expr, p, 0) - for x in self.gen_cand(v_cand, p.v_admode()): - yield x - - -class x86_rm_m16(x86_rm_m80): - msize = 16 - - -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, self.is_bnd) - if isinstance(expr, ExprMem): - if self.msize is None: - return False - if expr.size != self.msize: - expr = ExprMem(expr.ptr, self.msize) - self.expr = expr - return True - - - def encode(self): - expr = self.expr - if isinstance(expr, ExprInt): - return - if isinstance(expr, ExprMem) and expr.size != self.msize: - return - p = self.parent - mode = p.mode - if mode == 64: - mode = 32 - if isinstance(expr, ExprMem): - if self.is_xmm: - expr = ExprMem(expr.ptr, 128) - elif self.is_mm: - expr = ExprMem(expr.ptr, 64) - - 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 - - -class x86_rm_mm_m64(x86_rm_mm): - msize = 64 - is_mm = True - is_xmm = False - -class x86_rm_xmm(x86_rm_mm): - msize = 128 - is_mm = False - is_xmm = True - - -class x86_rm_xmm_m32(x86_rm_mm): - msize = 32 - is_mm = False - is_xmm = True - -class x86_rm_xmm_m64(x86_rm_mm): - msize = 64 - 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 - is_mm = False - is_xmm = True - -class x86_rm_mm_reg(x86_rm_mm): - msize = None - 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 - - parser = gpreg - - def fromstring(self, text, loc_db, parser_result=None): - if not hasattr(self.parent, 'sx') and hasattr(self.parent, "w8"): - self.parent.w8.value = 1 - if parser_result: - result, start, stop = parser_result[self.parser] - if result == [None]: - return None, None - self.expr = result - if self.expr.size == 8: - if hasattr(self.parent, 'sx') or not hasattr(self.parent, 'w8'): - return None, None - self.parent.w8.value = 0 - return start, stop - try: - result, start, stop = next(self.parser.scanString(text)) - except StopIteration: - return None, None - expr = self.asm_ast_to_expr(result[0], loc_db) - if expr is None: - return None, None - - self.expr = expr - if self.expr.size == 0: - if hasattr(self.parent, 'sx') or not hasattr(self.parent, 'w8'): - return None, None - self.parent.w8.value = 0 - - return start, stop - - def getrexsize(self): - return self.parent.rex_r.value - - def setrexsize(self, v): - self.parent.rex_r.value = v - - def decode(self, v): - v = v & self.lmask - p = self.parent - opmode = p.v_opmode() - if not hasattr(p, 'sx') and (hasattr(p, 'w8') and p.w8.value == 0): - opmode = 8 - r = size2gpregs[opmode] - if p.mode == 64 and self.getrexsize(): - v |= 0x8 - 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 - - def encode(self): - if not isinstance(self.expr, ExprId): - return False - if self.expr in gpregs64.expr and not hasattr(self.parent, 'stk'): - self.parent.rex_w.value = 1 - opmode = self.parent.v_opmode() - if not hasattr(self.parent, 'sx') and hasattr(self.parent, 'w8'): - self.parent.w8.value = 1 - if self.expr.size == 8: - if hasattr(self.parent, 'sx') or not hasattr(self.parent, 'w8'): - return False - self.parent.w8.value = 0 - opmode = 8 - r = size2gpregs[opmode] - if self.expr in r.expr: - i = r.expr.index(self.expr) - elif (opmode == 8 and self.parent.mode == 64 and - self.expr in gpregs08_64.expr): - i = gpregs08_64.expr.index(self.expr) - self.parent.rex_p.value = 1 - else: - log.debug("cannot encode reg %r", self.expr) - return False - if self.parent.v_opmode() == 64: - if i > 7: - self.setrexsize(1) - i -= 8 - elif self.parent.mode == 64 and i > 7: - i -= 8 - self.setrexsize(1) - self.value = i - return True - - -class x86_rm_reg_mm(x86_rm_reg_noarg, x86_arg): - selreg = gpregs_mm - def decode(self, v): - if self.parent.mode == 64 and self.getrexsize(): - v |= 0x8 - self.expr = self.selreg.expr[v] - return True - - def encode(self): - if not isinstance(self.expr, ExprId): - return False - if self.expr not in self.selreg.expr: - return False - i = self.selreg.expr.index(self.expr) - if self.parent.mode == 64 and i > 7: - i -= 8 - self.setrexsize(1) - self.value = i - return True - -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, x86_arg): - pass - - -class x86_reg(x86_rm_reg): - - def getrexsize(self): - return self.parent.rex_b.value - - def setrexsize(self, v): - self.parent.rex_b.value = v - -class x86_vex_reg(x86_rm_reg): - # self.lmask = 15 - - def decode(self, v): - p = self.parent - - self.expr = size2gpregs[v_opmode(p)].expr[p.vex_v.value] - - return self.expr is not None - - def encode(self): - opmode = self.parent.mode - size = self.expr.size - - if opmode == 64 and size == 64: - self.parent.rex_w.value = 1 - else: - self.parent.rex_w.value = 0 - - r = size2gpregs[size] - if self.expr in r.expr: - i = r.expr.index(self.expr) - - self.parent.vex_v.value = i - self.parent.vex.value = 1 - return True - - -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): - return self.parent.rex_b.value - - def setrexsize(self, v): - self.parent.rex_b.value = v - - -class x86_rm_segm(reg_noarg, x86_arg): - prio = default_prio + 1 - reg_info = segmreg - parser = reg_info.parser - - -class x86_rm_cr(reg_noarg, x86_arg): - prio = default_prio + 1 - reg_info = crregs - parser = reg_info.parser - - -class x86_rm_dr(reg_noarg, x86_arg): - prio = default_prio + 1 - reg_info = drregs - parser = reg_info.parser - - -class x86_rm_flt(reg_noarg, x86_arg): - prio = default_prio + 1 - reg_info = fltregs - parser = reg_info.parser - - -class bs_fbit(bsi): - - def decode(self, v): - # value already decoded in pre_dis_info - return True - - -class bs_cl1(bsi, x86_arg): - parser = cl_or_imm - - def decode(self, v): - if v == 1: - self.expr = regs08_expr[1] - else: - self.expr = ExprInt(1, 8) - return True - - def encode(self): - if self.expr == regs08_expr[1]: - self.value = 1 - elif isinstance(self.expr, ExprInt) and int(self.expr) == 1: - self.value = 0 - else: - return False - return True - - -def sib_cond(cls, mode, v): - if admode_prefix((mode, v["opmode"], v["admode"])) == 16: - return None - if v['mod'] == 0b11: - return None - elif v['rm'] == 0b100: - return cls.ll - else: - return None - return v['rm'] == 0b100 - - -class bs_cond_scale(bs_cond): - # cond must return field len - ll = 2 - - @classmethod - def flen(cls, mode, v): - return sib_cond(cls, mode, v) - - def encode(self): - if self.value is None: - self.value = 0 - self.l = 0 - return True - return super(bs_cond_scale, self).encode() - - def decode(self, v): - self.value = v - return True - - -class bs_cond_index(bs_cond_scale): - ll = 3 - - @classmethod - def flen(cls, mode, v): - return sib_cond(cls, mode, v) - - -class bs_cond_disp(bs_cond): - # cond must return field len - - @classmethod - def flen(cls, mode, v): - if admode_prefix((mode, v['opmode'], v['admode'])) == 16: - if v['mod'] == 0b00: - if v['rm'] == 0b110: - return 16 - else: - return None - elif v['mod'] == 0b01: - return 8 - elif v['mod'] == 0b10: - return 16 - return None - # 32, 64 - if 'sib_base' in v and v['sib_base'] == 0b101: - if v['mod'] == 0b00: - return 32 - elif v['mod'] == 0b01: - return 8 - elif v['mod'] == 0b10: - return 32 - else: - return None - - if v['mod'] == 0b00: - if v['rm'] == 0b101: - return 32 - else: - return None - elif v['mod'] == 0b01: - return 8 - elif v['mod'] == 0b10: - return 32 - else: - return None - - def encode(self): - if self.value is None: - self.value = 0 - self.l = 0 - return True - self.value = swap_uint(self.l, self.value) - return True - - def decode(self, v): - admode = self.parent.v_admode() - v = swap_uint(self.l, v) - self.value = v - v = sign_ext(v, self.l, admode) - v = ExprInt(v, admode) - self.expr = v - return True - - -class bs_cond_imm(bs_cond_scale, x86_arg): - parser = base_expr - max_size = 32 - - def fromstring(self, text, loc_db, parser_result=None): - if parser_result: - expr, start, stop = parser_result[self.parser] - else: - try: - expr, start, stop = next(self.parser.scanString(text)) - except StopIteration: - expr = None - self.expr = expr - - if len(self.parent.args) > 1: - l = self.parent.args[0].expr.size - else: - l = self.parent.v_opmode() - if isinstance(self.expr, ExprInt): - v = int(self.expr) - mask = ((1 << l) - 1) - self.expr = ExprInt(v & mask, l) - - if self.expr is None: - log.debug('cannot fromstring int %r', text) - return None, None - return start, stop - - @classmethod - def flen(cls, mode, v): - if 'w8' not in v or v['w8'] == 1: - if 'se' in v and v['se'] == 1: - return 8 - else: - osize = v_opmode_info(mode, v['opmode'], v['rex_w'], 0) - osize = min(osize, cls.max_size) - return osize - return 8 - - def getmaxlen(self): - return 32 - - def encode(self): - if not isinstance(self.expr, ExprInt): - return - arg0_expr = self.parent.args[0].expr - self.parent.rex_w.value = 0 - # special case for push - if len(self.parent.args) == 1: - v = int(self.expr) - l = self.parent.v_opmode() - l = min(l, self.max_size) - - self.l = l - mask = ((1 << self.l) - 1) - if v != sign_ext(v & mask, self.l, l): - return - self.value = swap_uint(self.l, v & ((1 << self.l) - 1)) - yield True - return - - # assume 2 args; use first arg to guess op size - if arg0_expr.size == 64: - self.parent.rex_w.value = 1 - - l = self.parent.v_opmode() - v = int(self.expr) - if arg0_expr.size == 8: - if not hasattr(self.parent, 'w8'): - return - self.parent.w8.value = 0 - l = 8 - if hasattr(self.parent, 'se'): - self.parent.se.value = 0 - elif hasattr(self.parent, 'se'): - if hasattr(self.parent, 'w8'): - self.parent.w8.value = 1 - # try to generate signed extended version - if v == sign_ext(v & 0xFF, 8, arg0_expr.size): - self.parent.se.value = 1 - self.l = 8 - self.value = v & 0xFF - yield True - self.parent.se.value = 0 - else: - if hasattr(self.parent, 'w8'): - self.parent.w8.value = 1 - if l == 64: - self.l = self.getmaxlen() - else: - self.l = l - - mask = ((1 << self.l) - 1) - if v != sign_ext(v & mask, self.l, l): - return - self.value = swap_uint(self.l, v & ((1 << self.l) - 1)) - yield True - - def decode(self, v): - opmode = self.parent.v_opmode() - v = swap_uint(self.l, v) - self.value = v - l_out = opmode - if hasattr(self.parent, 'w8') and self.parent.w8.value == 0: - l_out = 8 - v = sign_ext(v, self.l, l_out) - self.expr = ExprInt(v, l_out) - return True - - -class bs_cond_imm64(bs_cond_imm): - max_size = 64 - - def getmaxlen(self): - return 64 - - @classmethod - def flen(cls, mode, v): - if 'w8' not in v or v['w8'] == 1: - if 'se' in v and v['se'] == 1: - return 8 - else: - osize = v_opmode_info(mode, v['opmode'], v['rex_w'], 0) - return osize - else: - return 8 - - -class bs_rel_off(bs_cond_imm): - parser = base_expr - - def fromstring(self, text, loc_db, parser_result=None): - if parser_result: - expr, start, stop = parser_result[self.parser] - else: - try: - expr, start, stop = next(self.parser.scanString(text)) - except StopIteration: - expr = None - self.expr = expr - l = self.parent.mode - if isinstance(self.expr, ExprInt): - v = int(self.expr) - mask = ((1 << l) - 1) - self.expr = ExprInt(v & mask, l) - return start, stop - - @classmethod - def flen(cls, mode, v): - osize = v_opmode_info(mode, v['opmode'], v['rex_w'], 0) - if osize == 16: - return 16 - else: - return 32 - - def encode(self): - if not isinstance(self.expr, ExprInt): - return - arg0_expr = self.parent.args[0].expr - if self.l == 0: - l = self.parent.v_opmode() - self.l = l - l = offsize(self.parent) - prefix = self.parent.gen_prefix() - parent_len = len(prefix) * 8 + self.parent.l + self.l - assert(parent_len % 8 == 0) - - v = int(self.expr) - parent_len // 8 - if prefix is None: - return - mask = ((1 << self.l) - 1) - if self.l > l: - return - if v != sign_ext(v & mask, self.l, l): - return - self.value = swap_uint(self.l, v & ((1 << self.l) - 1)) - yield True - - def decode(self, v): - v = swap_uint(self.l, v) - size = offsize(self.parent) - v = sign_ext(v, self.l, size) - v += self.parent.l - self.expr = ExprInt(v, size) - return True - -class bs_s08(bs_rel_off): - parser = base_expr - - @classmethod - def flen(cls, mode, v): - return 8 - - def encode(self): - if not isinstance(self.expr, ExprInt): - return - arg0_expr = self.parent.args[0].expr - if self.l != 0: - l = self.l - else: - l = self.parent.v_opmode() - self.l = l - l = offsize(self.parent) - v = int(self.expr) - mask = ((1 << self.l) - 1) - if self.l > l: - return - if v != sign_ext(v & mask, self.l, l): - return - self.value = swap_uint(self.l, v & ((1 << self.l) - 1)) - yield True - - def decode(self, v): - v = swap_uint(self.l, v) - size = offsize(self.parent) - v = sign_ext(v, self.l, size) - self.expr = ExprInt(v, size) - return True - - -class bs_rel_off08(bs_rel_off): - - @classmethod - def flen(cls, mode, v): - return 8 - - -class bs_moff(bsi): - - @classmethod - def flen(cls, mode, v): - osize = v_opmode_info(mode, v['opmode'], v['rex_w'], 0) - if osize == 16: - return 16 - else: - return 32 - - def encode(self): - if not hasattr(self.parent, "mseg"): - return - m = self.parent.mseg.expr - if not (isinstance(m, ExprOp) and m.op == 'segm'): - return - if not isinstance(m.args[1], ExprInt): - return - l = self.parent.v_opmode() - if l == 16: - self.l = 16 - else: - self.l = 32 - v = int(m.args[1]) - mask = ((1 << self.l) - 1) - if v != sign_ext(v & mask, self.l, l): - return - self.value = swap_uint(self.l, v & ((1 << self.l) - 1)) - yield True - - def decode(self, v): - opmode = self.parent.v_opmode() - if opmode == 64: - return False - v = swap_uint(self.l, v) - self.value = v - v = sign_ext(v, self.l, opmode) - self.expr = ExprInt(v, opmode) - return True - - -class bs_movoff(x86_arg): - parser = deref_mem - - def fromstring(self, text, loc_db, parser_result=None): - if parser_result: - e, start, stop = parser_result[self.parser] - if e is None: - return None, None - if not isinstance(e, ExprMem): - return None, None - self.expr = e - if self.expr is None: - return None, None - return start, stop - try: - v, start, stop = next(self.parser.scanString(text)) - except StopIteration: - return None, None - if not isinstance(e, ExprMem): - return None, None - self.expr = v[0] - if self.expr is None: - log.debug('cannot fromstring int %r', text) - return None, None - return start, stop - - @classmethod - def flen(cls, mode, v): - if mode == 64: - if v['admode']: - return 32 - else: - return 64 - asize = v_admode_info(mode, v['admode']) - return asize - - def encode(self): - p = self.parent - if not isinstance(self.expr, ExprMem) or not isinstance(self.expr.ptr, ExprInt): - return - self.l = p.v_admode() - v = int(self.expr.ptr) - mask = ((1 << self.l) - 1) - if v != mask & v: - return - self.value = swap_uint(self.l, v & ((1 << self.l) - 1)) - yield True - - def decode(self, v): - if self.parent.mode == 64: - if self.parent.admode == 1: - l = 32 - else: - l = 64 - else: - l = self.parent.v_admode() - v = swap_uint(self.l, v) - self.value = v - v = sign_ext(v, self.l, l) - v = ExprInt(v, l) - size = self.parent.v_opmode() - if self.parent.w8.value == 0: - size = 8 - self.expr = ExprMem(v, size) - return True - - -class bs_msegoff(x86_arg): - parser = deref_ptr - - def fromstring(self, text, loc_db, parser_result=None): - if parser_result: - e, start, stop = parser_result[self.parser] - if e is None: - return None, None - self.expr = e - if self.expr is None: - return None, None - return start, stop - try: - v, start, stop = next(self.parser.scanString(text)) - except StopIteration: - return None, None - self.expr = v[0] - if self.expr is None: - log.debug('cannot fromstring int %r', text) - return None, None - return start, stop - - def encode(self): - if not (isinstance(self.expr, ExprOp) and self.expr.op == 'segm'): - return - if not isinstance(self.expr.args[0], ExprInt): - return - if not isinstance(self.expr.args[1], ExprInt): - return - l = self.parent.v_opmode() - v = int(self.expr.args[0]) - mask = ((1 << self.l) - 1) - if v != sign_ext(v & mask, self.l, l): - return - self.value = swap_uint(self.l, v & ((1 << self.l) - 1)) - yield True - - def decode(self, v): - opmode = self.parent.v_opmode() - v = swap_uint(self.l, v) - self.value = v - v = ExprInt(v, 16) - self.expr = ExprOp('segm', v, self.parent.off.expr) - return True - - -d_rex_p = bs(l=0, cls=(bs_fbit,), fname="rex_p") -d_rex_w = bs(l=0, cls=(bs_fbit,), fname="rex_w") -d_rex_r = bs(l=0, cls=(bs_fbit,), fname="rex_r") -d_rex_x = bs(l=0, cls=(bs_fbit,), fname="rex_x") -d_rex_b = bs(l=0, cls=(bs_fbit,), fname="rex_b") - -d_vex = bs(l=0, cls=(bs_fbit,), fname="vex") -d_vex_l = bs(l=0, cls=(bs_fbit,), fname="vex_l") -d_vex_p = bs(l=0, cls=(bs_fbit,), fname="vex_p") -d_vex_v = bs(l=0, cls=(bs_fbit,), fname="vex_v") -d_vex_m = bs(l=0, cls=(bs_fbit,), fname="vex_m") - -pref_0f = bs(l=0, fname="pref_0f") -pref_0f38 = bs(l=0, fname="pref_0f38") -pref_0f3a = bs(l=0, fname="pref_0f3a") - -d_g1 = bs(l=0, cls=(bs_fbit,), fname="g1") -d_g2 = bs(l=0, cls=(bs_fbit,), fname="g2") - - -d_cl1 = bs(l=1, cls=(bs_cl1,), fname="cl1") - - -w8 = bs(l=1, fname="w8") -se = bs(l=1, fname="se") - -sx = bs(l=0, fname="sx") -sxd = bs(l=0, fname="sx") - - -xmmreg = bs(l=0, fname="xmmreg") -mmreg = bs(l=0, fname="mmreg") - -pref_f2 = bs(l=0, fname="prefixed", default=b"\xf2") -pref_f3 = bs(l=0, fname="prefixed", default=b"\xf3") -pref_66 = bs(l=0, fname="prefixed", default=b"\x66") -no_xmm_pref = bs(l=0, fname="no_xmm_pref") - -no_rex = bs(l=0, fname="no_rex") -no_rep = bs(l=0, fname="no_rep") - -sib_scale = bs(l=2, cls=(bs_cond_scale,), fname = "sib_scale") -sib_index = bs(l=3, cls=(bs_cond_index,), fname = "sib_index") -sib_base = bs(l=3, cls=(bs_cond_index,), fname = "sib_base") - -disp = bs(l=0, cls=(bs_cond_disp,), fname = "disp") - -s08 = bs(l=8, cls=(bs_s08, )) - -u08 = bs(l=8, cls=(x86_08, x86_arg)) -u07 = bs(l=7, cls=(x86_08, x86_arg)) -u16 = bs(l=16, cls=(x86_16, x86_arg)) -u32 = bs(l=32, cls=(x86_32, x86_arg)) -s3264 = bs(l=32, cls=(x86_s32to64, x86_arg)) - -u08_3 = bs(l=0, cls=(x86_imm_fix_08, x86_arg), ival = 3) - -d0 = bs("000", fname='reg') -d1 = bs("001", fname='reg') -d2 = bs("010", fname='reg') -d3 = bs("011", fname='reg') -d4 = bs("100", fname='reg') -d5 = bs("101", fname='reg') -d6 = bs("110", fname='reg') -d7 = bs("111", fname='reg') - -sd = bs(l=1, fname="sd") -wd = bs(l=1, fname="wd") - -stk = bs(l=0, fname="stk") - - -class field_size(object): - prio = default_prio - - def __init__(self, d=None): - if d is None: - d = {} - self.d = d - - def get(self, opm, adm=None): - return self.d[opm] - -class bs_mem(object): - def encode(self): - return self.value != 0b11 - - def decode(self, v): - self.value = v - return v != 0b11 - -class bs_reg(object): - def encode(self): - return self.value == 0b11 - - def decode(self, v): - self.value = v - return v == 0b11 - -d_imm64 = bs(l=0, fname="imm64") - -d_eax = bs(l=0, cls=(bs_eax, ), fname='eax') -d_edx = bs(l=0, cls=(bs_edx, ), fname='edx') -d_st = bs(l=0, cls=(x86_reg_st, ), fname='st') -d_imm = bs(l=0, cls=(bs_cond_imm,), fname="imm") -d_imm64 = bs(l=0, cls=(bs_cond_imm64,), fname="imm") -d_ax = bs(l=0, cls=(r_ax, ), fname='ax') -d_dx = bs(l=0, cls=(r_dx, ), fname='dx') -d_cl = bs(l=0, cls=(r_cl, ), fname='cl') - -d_cs = bs(l=0, cls=(bs_cs, ), fname='cs') -d_ds = bs(l=0, cls=(bs_ds, ), fname='ds') -d_es = bs(l=0, cls=(bs_es, ), fname='es') -d_ss = bs(l=0, cls=(bs_ss, ), fname='ss') -d_fs = bs(l=0, cls=(bs_fs, ), fname='fs') -d_gs = bs(l=0, cls=(bs_gs, ), fname='gs') - -# Offset must be decoded in last position to have final instruction len -rel_off = bs(l=0, cls=(bs_rel_off,), fname="off", order=-1) -# Offset must be decoded in last position to have final instruction len -rel_off08 = bs(l=8, cls=(bs_rel_off08,), fname="off", order=-1) -moff = bs(l=0, cls=(bs_moff,), fname="off") -msegoff = bs(l=16, cls=(bs_msegoff,), fname="mseg") -movoff = bs(l=0, cls=(bs_movoff,), fname="off") -mod = bs(l=2, fname="mod") -mod_mem = bs(l=2, cls=(bs_mem,), fname="mod") -mod_reg = bs(l=2, cls=(bs_reg,), 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") - -vex_reg = bs(l=0, cls=(x86_vex_reg, ), order =1, fname = "vex_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") -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") - -rm = bs(l=3, fname="rm") - -rm_arg = bs(l=0, cls=(x86_rm_arg,), fname='rmarg') -rm_arg_w8 = bs(l=0, cls=(x86_rm_w8,), fname='rmarg') -rm_arg_sx = bs(l=0, cls=(x86_rm_sx,), fname='rmarg') -rm_arg_sxd = bs(l=0, cls=(x86_rm_sxd,), fname='rmarg') -rm_arg_sd = bs(l=0, cls=(x86_rm_sd,), fname='rmarg') -rm_arg_wd = bs(l=0, cls=(x86_rm_wd,), fname='rmarg') -rm_arg_08 = bs(l=0, cls=(x86_rm_08,), fname='rmarg') -rm_arg_reg_m08 = bs(l=0, cls=(x86_rm_reg_m08,), fname='rmarg') -rm_arg_reg_m16 = bs(l=0, cls=(x86_rm_reg_m16,), fname='rmarg') -rm_arg_m08 = bs(l=0, cls=(x86_rm_m08,), fname='rmarg') -rm_arg_m64 = bs(l=0, cls=(x86_rm_m64,), fname='rmarg') -rm_arg_m80 = bs(l=0, cls=(x86_rm_m80,), fname='rmarg') -rm_arg_m16 = bs(l=0, cls=(x86_rm_m16,), fname='rmarg') - -rm_mem = bs(l=0, cls=(x86_rm_mem,), fname='rmarg') -rm_mem_far = bs(l=0, cls=(x86_rm_mem_far,), fname='rmarg') - -rm_arg_mm = bs(l=0, cls=(x86_rm_mm,), fname='rmarg') -rm_arg_mm_m64 = bs(l=0, cls=(x86_rm_mm_m64,), fname='rmarg') -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=list(range(1 << 1))) - - -class bs_op_mode(bsi): - - def decode(self, v): - opmode = self.parent.v_opmode() - return opmode == self.mode - - -class bs_ad_mode(bsi): - - def decode(self, v): - admode = self.parent.v_admode() - return admode == self.mode - - -class bs_op_mode_no64(bsi): - - def encode(self): - if self.parent.mode == 64: - return False - return super(bs_op_mode_no64, self).encode() - - def decode(self, v): - if self.parent.mode == 64: - return False - opmode = self.parent.v_opmode() - return opmode == self.mode - - -class bs_op_mode64(bsi): - def encode(self): - if self.parent.mode != 64: - return False - return super(bs_op_mode64, self).encode() - - def decode(self, v): - if self.parent.mode != 64: - return False - return True - -class bs_op_modeno64(bsi): - def encode(self): - if self.parent.mode == 64: - return False - return super(bs_op_modeno64, self).encode() - - def decode(self, v): - if self.parent.mode == 64: - return False - return True - - - -bs_opmode16 = bs(l=0, cls=(bs_op_mode,), mode = 16, fname="fopmode") -bs_opmode32 = bs(l=0, cls=(bs_op_mode,), mode = 32, fname="fopmode") -bs_opmode64 = bs(l=0, cls=(bs_op_mode,), mode = 64, fname="fopmode") - - -bs_admode16 = bs(l=0, cls=(bs_ad_mode,), mode = 16, fname="fadmode") -bs_admode32 = bs(l=0, cls=(bs_ad_mode,), mode = 32, fname="fadmode") -bs_admode64 = bs(l=0, cls=(bs_ad_mode,), mode = 64, fname="fadmode") - -bs_opmode16_no64 = bs(l=0, cls=(bs_op_mode_no64,), mode = 16, fname="fopmode") -bs_opmode32_no64 = bs(l=0, cls=(bs_op_mode_no64,), mode = 32, fname="fopmode") - -bs_mode64 = bs(l=0, cls=(bs_op_mode64,)) -bs_modeno64 = bs(l=0, cls=(bs_op_modeno64,)) - - -cond_list = ["O", "NO", "B", "AE", - "Z", "NZ", "BE", "A", - "S", "NS", "PE", "NP", - #"L", "NL", "NG", "G"] - "L", "GE", "LE", "G"] -cond = bs_mod_name(l=4, fname='cond', mn_mod=cond_list) - - -def rmmod(r, rm_arg_x=rm_arg, modrm=mod): - return [modrm, r, rm, sib_scale, sib_index, sib_base, disp, rm_arg_x] - -# -# mode | reg | rm # -# - -# -# scale | index | base # -# - -# -# Prefix | REX prefix | Opcode | mod/rm | sib | displacement | immediate # -# - - -def addop(name, fields, args=None, alias=False): - dct = {"fields": fields} - dct["alias"] = alias - if args is not None: - dct['args'] = args - type(name, (mn_x86,), dct) -""" -class ia32_aaa(mn_x86): - fields = [bs8(0x37)] -""" -addop("aaa", [bs8(0x37)]) -addop("aas", [bs8(0x3F)]) -addop("aad", [bs8(0xd5), u08]) -addop("aam", [bs8(0xd4), u08]) - -addop("adc", [bs("0001010"), w8, d_eax, d_imm]) -addop("adc", [bs("100000"), se, w8] + rmmod(d2, rm_arg_w8) + [d_imm]) -addop("adc", [bs("000100"), swapargs, w8] + - rmmod(rmreg, rm_arg_w8), [rm_arg_w8, rmreg]) - -addop("add", [bs("0000010"), w8, d_eax, d_imm]) -addop("add", [bs("100000"), se, w8] + rmmod(d0, rm_arg_w8) + [d_imm]) -addop("add", [bs("000000"), swapargs, w8] + - rmmod(rmreg, rm_arg_w8), [rm_arg_w8, rmreg]) - -addop("and", [bs("0010010"), w8, d_eax, d_imm]) -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), no_rep] + rmmod(rmreg)) -addop("bsr", [bs8(0x0f), bs8(0xbd), mod, - rmreg, rm, sib_scale, sib_index, sib_base, disp, rm_arg]) - -addop("bswap", [bs8(0x0f), bs('11001'), reg]) - -addop("bt", [bs8(0x0f), bs8(0xa3)] + rmmod(rmreg), [rm_arg, rmreg]) -addop("bt", [bs8(0x0f), bs8(0xba)] + rmmod(d4) + [u08]) -addop("btc", [bs8(0x0f), bs8(0xbb)] + rmmod(rmreg), [rm_arg, rmreg]) -addop("btc", [bs8(0x0f), bs8(0xba)] + rmmod(d7) + [u08]) - - -addop("btr", [bs8(0x0f), bs8(0xb3)] + rmmod(rmreg), [rm_arg, rmreg]) -addop("btr", [bs8(0x0f), bs8(0xba)] + rmmod(d6) + [u08]) -addop("bts", [bs8(0x0f), bs8(0xab)] + rmmod(rmreg), [rm_arg, rmreg]) -addop("bts", [bs8(0x0f), bs8(0xba)] + rmmod(d5) + [u08]) - -addop("call", [bs8(0xe8), rel_off]) -addop("call", [bs8(0xff), stk] + rmmod(d2)) -addop("call", [bs8(0xff), stk] + rmmod(d3, rm_arg_x=rm_mem_far, modrm=mod_mem)) -addop("call", [bs8(0x9a), bs_modeno64, moff, msegoff]) - - -addop("cbw", [bs8(0x98), bs_opmode16]) -addop("cwde", [bs8(0x98), bs_opmode32]) -addop("cdqe", [bs8(0x98), bs_opmode64]) - -addop("clc", [bs8(0xf8)]) -addop("cld", [bs8(0xfc)]) -addop("cli", [bs8(0xfa)]) -addop("clts", [bs8(0x0f), bs8(0x06)]) -addop("cmc", [bs8(0xf5)]) - -addop("cmov", [bs8(0x0f), bs('0100'), cond] + rmmod(rmreg)) - -addop("cmp", [bs("0011110"), w8, d_eax, d_imm]) -addop("cmp", [bs("100000"), se, w8] + rmmod(d7, rm_arg_w8) + [d_imm]) -addop("cmp", [bs("001110"), swapargs, w8] + - rmmod(rmreg, rm_arg_w8), [rm_arg_w8, rmreg]) - - -addop("cmpsb", [bs8(0xa6)]) -addop("cmpsw", [bs8(0xa7), bs_opmode16]) -addop("cmpsd", [bs8(0xa7), bs_opmode32]) -addop("cmpsq", [bs8(0xa7), bs_opmode64]) - -addop("cmpxchg", [bs8(0x0f), bs('1011000'), w8] - + rmmod(rmreg, rm_arg_w8), [rm_arg_w8, rmreg]) -addop("cmpxchg8b", [bs8(0x0f), bs8(0xc7), bs_opmode16] + rmmod(d1, rm_arg_m64)) -addop("cmpxchg8b", [bs8(0x0f), bs8(0xc7), bs_opmode32] + rmmod(d1, rm_arg_m64)) -addop("cmpxchg16b", [bs8(0x0f), bs8(0xc7), bs_opmode64] + rmmod(d1, rm_arg_xmm_m128)) - -# XXX TODO CMPXCHG8/16 - -addop("comiss", [bs8(0x0f), bs8(0x2f), no_xmm_pref] + - rmmod(xmm_reg, rm_arg_xmm_m32), [xmm_reg, rm_arg_xmm_m32]) -addop("comisd", [bs8(0x0f), bs8(0x2f), pref_66] + - rmmod(xmm_reg, rm_arg_xmm_m64), [xmm_reg, rm_arg_xmm_m64]) - -addop("cpuid", [bs8(0x0f), bs8(0xa2)]) - -addop("cwd", [bs8(0x99), bs_opmode16]) -addop("cdq", [bs8(0x99), bs_opmode32]) -addop("cqo", [bs8(0x99), bs_opmode64]) - - -addop("daa", [bs8(0x27)]) -addop("das", [bs8(0x2f)]) -addop("dec", [bs('1111111'), w8] + rmmod(d1, rm_arg_w8)) -addop("dec", [bs('01001'), reg, bs_modeno64]) -addop("div", [bs('1111011'), w8] + rmmod(d6, rm_arg_w8)) -addop("enter", [bs8(0xc8), u16, u08]) - -# float ##### -addop("fwait", [bs8(0x9b)]) - -addop("f2xm1", [bs8(0xd9), bs8(0xf0)]) -addop("fabs", [bs8(0xd9), bs8(0xe1)]) - -addop("fadd", [bs("11011"), sd, bs("00")] + rmmod(d0, rm_arg_sd)) -addop("fadd", [bs("11011"), swapargs, bs("00"), - bs("11000"), d_st, fltreg], [d_st, fltreg]) -addop("faddp", [bs8(0xde), bs("11000"), fltreg, d_st]) -addop("fiadd", [bs("11011"), wd, bs("10")] + rmmod(d0, rm_arg_wd)) - -addop("fbld", [bs8(0xdf)] + rmmod(d4, rm_arg_m80)) -addop("fbldp", [bs8(0xdf)] + rmmod(d6, rm_arg_m80)) -addop("fchs", [bs8(0xd9), bs8(0xe0)]) -# addop("fclex", [bs8(0x9b), bs8(0xdb), bs8(0xe2)]) -addop("fnclex", [bs8(0xdb), bs8(0xe2)]) - -addop("fcmovb", [bs8(0xda), bs("11000"), d_st, fltreg]) -addop("fcmove", [bs8(0xda), bs("11001"), d_st, fltreg]) -addop("fcmovbe", [bs8(0xda), bs("11010"), d_st, fltreg]) -addop("fcmovu", [bs8(0xda), bs("11011"), d_st, fltreg]) -addop("fcmovnb", [bs8(0xdb), bs("11000"), d_st, fltreg]) -addop("fcmovne", [bs8(0xdb), bs("11001"), d_st, fltreg]) -addop("fcmovnbe", [bs8(0xdb), bs("11010"), d_st, fltreg]) -addop("fcmovnu", [bs8(0xdb), bs("11011"), d_st, fltreg]) - -addop("fcom", [bs("11011"), sd, bs("00")] + rmmod(d2, rm_arg_sd)) -addop("fcom", [bs("11011"), swapargs, bs("00"), - bs("11010"), d_st, fltreg], [d_st, fltreg]) -addop("fcomp", [bs("11011"), sd, bs("00")] + rmmod(d3, rm_arg_sd)) -addop("fcomp", - [bs("11011"), swapargs, bs("00"), bs("11011"), - d_st, fltreg], [d_st, fltreg]) -addop("fcompp", [bs8(0xde), bs8(0xd9)]) - -addop("fcomi", [bs8(0xdb), bs("11110"), d_st, fltreg]) -addop("fcomip", [bs8(0xdf), bs("11110"), d_st, fltreg]) -addop("fucomi", [bs8(0xdb), bs("11101"), d_st, fltreg]) -addop("fucomip", [bs8(0xdf), bs("11101"), d_st, fltreg]) - -addop("fcos", [bs8(0xd9), bs8(0xff)]) -addop("fdecstp", [bs8(0xd9), bs8(0xf6)]) - - -addop("fdiv", [bs("11011"), sd, bs("00")] + rmmod(d6, rm_arg_sd)) -addop("fdiv", [bs8(0xd8), bs("11110"), d_st, fltreg]) -addop("fdiv", [bs8(0xdc), bs("11111"), fltreg, d_st]) -addop("fdivp", [bs8(0xde), bs("11111"), fltreg, d_st]) -addop("fidiv", [bs("11011"), wd, bs("10")] + rmmod(d6, rm_arg_wd)) - -addop("fdivr", [bs("11011"), sd, bs("00")] + rmmod(d7, rm_arg_sd)) -addop("fdivr", [bs8(0xd8), bs("11111"), d_st, fltreg]) -addop("fdivr", [bs8(0xdc), bs("11110"), fltreg, d_st]) -addop("fdivrp", [bs8(0xde), bs("11110"), fltreg, d_st]) -addop("fidivr", [bs("11011"), wd, bs("10")] + rmmod(d7, rm_arg_wd)) - -addop("ffree", [bs8(0xdd), bs("11000"), fltreg]) -addop("ficom", [bs("11011"), wd, bs("10")] + rmmod(d2, rm_arg_wd)) -addop("ficomp", [bs("11011"), wd, bs("10")] + rmmod(d3, rm_arg_wd)) -addop("fild", [bs("11011"), wd, bs("11")] + rmmod(d0, rm_arg_wd)) -addop("fild", [bs8(0xdf)] + rmmod(d5, rm_arg_m64)) - -addop("fincstp", [bs8(0xd9), bs8(0xf7)]) - -addop("blsi", [pref_0f38, bs8(0xf3), vex_reg] + rmmod(bs("011"), rm_arg), [vex_reg, rm_arg]) -addop("andn", [pref_0f38, bs8(0xf2), vex_reg] + rmmod(rmreg, rm_arg), [rmreg, vex_reg, rm_arg]) -addop("bextr", [pref_0f38, bs8(0xf7), vex_reg] + rmmod(rmreg, rm_arg), [rmreg, rm_arg, vex_reg]) -addop("blsmsk", [pref_0f38, bs8(0xf3), vex_reg] + rmmod(bs("010"), rm_arg), [vex_reg, rm_arg]) -addop("blsr", [pref_0f38, bs8(0xf3), vex_reg] + rmmod(bs("001"), rm_arg), [vex_reg, rm_arg]) -addop("bzhi", [pref_0f38, bs8(0xf5), vex_reg] + rmmod(rmreg, rm_arg), [rmreg, rm_arg, vex_reg]) -addop("tzcnt", [bs8(0x0f), bs8(0xbc), pref_f3] + rmmod(rmreg, rm_arg), [rmreg, rm_arg]) - -# addop("finit", [bs8(0x9b), bs8(0xdb), bs8(0xe3)]) -addop("fninit", [bs8(0xdb), bs8(0xe3)]) - -addop("fist", [bs("11011"), wd, bs("11")] + rmmod(d2, rm_arg_wd)) -addop("fistp", [bs("11011"), wd, bs("11")] + rmmod(d3, rm_arg_wd)) -addop("fistp", [bs8(0xdf)] + rmmod(d7, rm_arg_m64)) - -addop("fisttp", [bs("11011"), wd, bs("11")] + rmmod(d1, rm_arg_wd)) -addop("fisttp", [bs8(0xdd)] + rmmod(d1, rm_arg_m64)) - -addop("fld", [bs("11011"), sd, bs("01")] + rmmod(d0, rm_arg_sd)) -addop("fld", [bs8(0xdb)] + rmmod(d5, rm_arg_m80)) -addop("fld", [bs8(0xd9), bs("11000"), fltreg]) - -addop("fld1", [bs8(0xd9), bs8(0xe8)]) -addop("fldl2t", [bs8(0xd9), bs8(0xe9)]) -addop("fldl2e", [bs8(0xd9), bs8(0xea)]) -addop("fldpi", [bs8(0xd9), bs8(0xeb)]) -addop("fldlg2", [bs8(0xd9), bs8(0xec)]) -addop("fldln2", [bs8(0xd9), bs8(0xed)]) -addop("fldz", [bs8(0xd9), bs8(0xee)]) - -addop("fldcw", [bs8(0xd9)] + rmmod(d5, rm_arg_m16)) -addop("fldenv", [bs8(0xd9)] + rmmod(d4, rm_arg_m80)) # XXX TODO: m14? - -addop("fmul", [bs("11011"), sd, bs("00")] + rmmod(d1, rm_arg_sd)) -addop("fmul", [bs("11011"), swapargs, bs("00"), - bs("11001"), d_st, fltreg], [d_st, fltreg]) -addop("fmulp", [bs8(0xde), bs("11001"), fltreg, d_st]) -addop("fimul", [bs("11011"), wd, bs("10")] + rmmod(d1, rm_arg_wd)) - -addop("fnop", [bs8(0xd9), bs8(0xd0)]) -addop("fpatan", [bs8(0xd9), bs8(0xf3)]) -addop("fprem", [bs8(0xd9), bs8(0xf8)]) -addop("fprem1", [bs8(0xd9), bs8(0xf5)]) -addop("fptan", [bs8(0xd9), bs8(0xf2)]) -addop("frndint", [bs8(0xd9), bs8(0xfc)]) -addop("frstor", [bs8(0xdd)] + rmmod(d4, rm_arg_m80)) # XXX TODO: m94 ? -# addop("fsave", [bs8(0x9b), bs8(0xdd)] + rmmod(d6, rm_arg_m80)) # XXX -# TODO: m94 ? -addop("fnsave", [bs8(0xdd)] + rmmod(d6, rm_arg_m80)) # XXX TODO: m94 ? - -addop("fscale", [bs8(0xd9), bs8(0xfd)]) -addop("fsin", [bs8(0xd9), bs8(0xfe)]) -addop("fsincos", [bs8(0xd9), bs8(0xfb)]) -addop("fsqrt", [bs8(0xd9), bs8(0xfa)]) - -addop("fst", [bs("11011"), sd, bs("01")] + rmmod(d2, rm_arg_sd)) -addop("fst", [bs8(0xdd), bs("11010"), fltreg]) -addop("fstp", [bs("11011"), sd, bs("01")] + rmmod(d3, rm_arg_sd)) -addop("fstp", [bs8(0xdb)] + rmmod(d7, rm_arg_m80)) -addop("fstp", [bs8(0xdd), bs("11011"), fltreg]) - -# addop("fstcw", [bs8(0x9b), bs8(0xd9)] + rmmod(d7, rm_arg_m16)) -addop("fnstcw", [bs8(0xd9)] + rmmod(d7, rm_arg_m16)) -# addop("fstenv", [bs8(0x9b), bs8(0xd9)] + rmmod(d6, rm_arg_m80)) # XXX -# TODO: m14? -addop("fnstenv", [bs8(0xd9)] + rmmod(d6, rm_arg_m80)) # XXX TODO: m14? -# addop("fstsw", [bs8(0x9b), bs8(0xdd)] + rmmod(d7, rm_arg_m16)) -addop("fnstsw", [bs8(0xdd)] + rmmod(d7, rm_arg_m16)) -# addop("fstsw", [bs8(0x9b), bs8(0xdf), bs8(0xe0), d_ax]) -addop("fnstsw", [bs8(0xdf), bs8(0xe0), d_ax]) - -addop("fsub", [bs("11011"), sd, bs("00")] + rmmod(d4, rm_arg_sd)) -addop("fsub", [bs8(0xd8), bs("11100"), d_st, fltreg]) -addop("fsub", [bs8(0xdc), bs("11101"), fltreg, d_st]) -addop("fsubp", [bs8(0xde), bs("11101"), fltreg, d_st]) -addop("fisub", [bs("11011"), wd, bs("10")] + rmmod(d4, rm_arg_wd)) - -addop("fsubr", [bs("11011"), sd, bs("00")] + rmmod(d5, rm_arg_sd)) -addop("fsubr", [bs8(0xd8), bs("11101"), d_st, fltreg]) -addop("fsubr", [bs8(0xdc), bs("11100"), fltreg, d_st]) -addop("fsubrp", [bs8(0xde), bs("11100"), fltreg, d_st]) -addop("fisubr", [bs("11011"), wd, bs("10")] + rmmod(d5, rm_arg_wd)) -addop("ftst", [bs8(0xd9), bs8(0xe4)]) - - -addop("fucom", [bs8(0xdd), bs("11100"), fltreg]) -addop("fucomp", [bs8(0xdd), bs("11101"), fltreg]) -addop("fucompp", [bs8(0xda), bs8(0xe9)]) - -addop("fxam", [bs8(0xd9), bs8(0xe5)]) -addop("fxch", [bs8(0xd9), bs("11001"), fltreg]) -addop("fxrstor", [bs8(0x0f), bs8(0xae)] - + rmmod(d1, rm_arg_m80)) # XXX TODO m512 -addop("fxsave", [bs8(0x0f), bs8(0xae)] - + rmmod(d0, rm_arg_m80)) # XXX TODO m512 -addop("stmxcsr", [bs8(0x0f), bs8(0xae)] + rmmod(d3)) -addop("ldmxcsr", [bs8(0x0f), bs8(0xae)] + rmmod(d2)) - -addop("fxtract", [bs8(0xd9), bs8(0xf4)]) -addop("fyl2x", [bs8(0xd9), bs8(0xf1)]) -addop("fyl2xp1", [bs8(0xd9), bs8(0xf9)]) - -addop("hlt", [bs8(0xf4)]) -addop("icebp", [bs8(0xf1)]) - -addop("idiv", [bs('1111011'), w8] + rmmod(d7, rm_arg_w8)) - -addop("imul", [bs('1111011'), w8] + rmmod(d5, rm_arg_w8)) -addop("imul", [bs8(0x0f), bs8(0xaf)] + rmmod(rmreg)) - -addop("imul", [bs("011010"), se, bs('1')] + rmmod(rmreg) + [d_imm]) - -addop("in", [bs("1110010"), w8, d_eax, u08]) -addop("in", [bs("1110110"), w8, d_eax, d_edx]) - -addop("inc", [bs('1111111'), w8] + rmmod(d0, rm_arg_w8)) -addop("inc", [bs('01000'), reg, bs_modeno64]) - -addop("insb", [bs8(0x6c)]) -addop("insw", [bs8(0x6d), bs_opmode16]) -addop("insd", [bs8(0x6d), bs_opmode32]) -addop("insd", [bs8(0x6d), bs_opmode64]) - -addop("int", [bs8(0xcc), u08_3]) -addop("int", [bs8(0xcd), u08]) -addop("into", [bs8(0xce)]) -addop("invd", [bs8(0x0f), bs8(0x08)]) -addop("invlpg", [bs8(0x0f), bs8(0x01)] + rmmod(d7)) - -addop("iret", [bs8(0xcf), bs_opmode16]) -addop("iretd", [bs8(0xcf), bs_opmode32]) -addop("iretq", [bs8(0xcf), bs_opmode64]) - -addop("j", [bs('0111'), cond, rel_off08]) - -addop("jcxz", [bs8(0xe3), rel_off08, bs_admode16]) -addop("jecxz", [bs8(0xe3), rel_off08, bs_admode32]) -addop("jrcxz", [bs8(0xe3), rel_off08, bs_admode64]) - -addop("j", [bs8(0x0f), bs('1000'), cond, rel_off]) -addop("jmp", [bs8(0xeb), rel_off08]) -addop("jmp", [bs8(0xe9), rel_off]) -# TODO XXX replace stk force64? -addop("jmp", [bs8(0xff), stk] + rmmod(d4)) -addop("jmp", [bs8(0xea), bs_modeno64, moff, msegoff]) - -addop("jmp", [bs8(0xff)] + rmmod(d5, rm_arg_x=rm_mem_far, modrm=mod_mem)) - -addop("lahf", [bs8(0x9f)]) -addop("lar", [bs8(0x0f), bs8(0x02)] + rmmod(rmreg)) - -addop("lea", [bs8(0x8d)] + rmmod(rmreg, rm_arg_x=rm_mem, modrm=mod_mem)) -addop("les", [bs8(0xc4)] + rmmod(rmreg, rm_arg_x=rm_mem, modrm=mod_mem)) -addop("lds", [bs8(0xc5)] + rmmod(rmreg, rm_arg_x=rm_mem, modrm=mod_mem)) -addop("lss", [bs8(0x0f), bs8(0xb2)] + rmmod(rmreg, rm_arg_x=rm_mem, modrm=mod_mem)) -addop("lfs", [bs8(0x0f), bs8(0xb4)] + rmmod(rmreg, rm_arg_x=rm_mem, modrm=mod_mem)) -addop("lgs", [bs8(0x0f), bs8(0xb5)] + rmmod(rmreg, rm_arg_x=rm_mem, modrm=mod_mem)) - -addop("lgdt", [bs8(0x0f), bs8(0x01)] + rmmod(d2, modrm=mod_mem)) -addop("lidt", [bs8(0x0f), bs8(0x01)] + rmmod(d3, modrm=mod_mem)) - -addop("lfence", [bs8(0x0f), bs8(0xae), bs8(0xe8), no_xmm_pref]) -addop("mfence", [bs8(0x0f), bs8(0xae), bs8(0xf0)]) -addop("sfence", [bs8(0x0f), bs8(0xae), bs8(0xf8)]) - -addop("leave", [bs8(0xc9), stk]) - -addop("lodsb", [bs8(0xac)]) -addop("lodsw", [bs8(0xad), bs_opmode16]) -addop("lodsd", [bs8(0xad), bs_opmode32]) -addop("lodsq", [bs8(0xad), bs_opmode64]) - -addop("loop", [bs8(0xe2), rel_off08]) -addop("loope", [bs8(0xe1), rel_off08]) -addop("loopne", [bs8(0xe0), rel_off08]) -addop("lsl", [bs8(0x0f), bs8(0x03)] + rmmod(rmreg)) -addop("monitor", [bs8(0x0f), bs8(0x01), bs8(0xc8)]) - -addop("mov", [bs("100010"), swapargs, w8] + - rmmod(rmreg, rm_arg_w8), [rm_arg_w8, rmreg]) -addop("mov", [bs("100011"), swapargs, bs('0')] + rmmod(segm), [rm_arg, segm]) -addop("mov", [bs("101000"), swapargs, w8, d_eax, movoff], [d_eax, movoff]) -addop("mov", [bs("1011"), w8, reg, d_imm64]) -addop("mov", [bs("1100011"), w8] + rmmod(d0, rm_arg_w8) + [d_imm]) -addop("mov", [bs8(0x0f), bs("001000"), swapargs, bs('0')] - + rmmod(crreg), [rm_arg, crreg]) -addop("mov", [bs8(0x0f), bs("001000"), swapargs, bs('1')] - + rmmod(drreg), [rm_arg, drreg]) -addop("movsb", [bs8(0xa4)]) -addop("movsw", [bs8(0xa5), bs_opmode16]) -addop("movsd", [bs8(0xa5), bs_opmode32]) -addop("movsq", [bs8(0xa5), bs_opmode64]) - -addop("movsx", [bs8(0x0f), bs("1011111"), w8, sx] + rmmod(rmreg, rm_arg_sx)) -addop("movsxd", [bs8(0x63), sxd, bs_mode64] + rmmod(rmreg, rm_arg_sxd)) - -addop("movups", [bs8(0x0f), bs("0001000"), swapargs, no_xmm_pref] + - rmmod(xmm_reg, rm_arg_xmm), [xmm_reg, rm_arg_xmm]) -addop("movsd", [bs8(0x0f), bs("0001000"), swapargs, pref_f2] - + rmmod(xmm_reg, rm_arg_xmm_m64), [xmm_reg, rm_arg_xmm_m64]) -addop("movss", [bs8(0x0f), bs("0001000"), swapargs, pref_f3] + - rmmod(xmm_reg, rm_arg_xmm_m32), [xmm_reg, rm_arg_xmm_m32]) -addop("movupd", [bs8(0x0f), bs8(0x10), pref_66] + rmmod(xmm_reg, rm_arg_xmm), [xmm_reg, rm_arg_xmm]) -addop("movupd", [bs8(0x0f), bs8(0x11), pref_66] + rmmod(xmm_reg, rm_arg_xmm), [rm_arg_xmm, xmm_reg]) - - -addop("movd", [bs8(0x0f), bs('011'), swapargs, bs('1110'), no_xmm_pref] + - rmmod(mm_reg, rm_arg), [mm_reg, rm_arg]) -addop("movd", [bs8(0x0f), bs('011'), swapargs, bs('1110'), pref_66, bs_opmode32] + - rmmod(xmm_reg, rm_arg), [xmm_reg, rm_arg]) -addop("movq", [bs8(0x0f), bs('011'), swapargs, bs('1110'), pref_66, bs_opmode64] + - rmmod(xmm_reg, rm_arg), [xmm_reg, rm_arg]) - -addop("movq", [bs8(0x0f), bs('011'), swapargs, bs('1111'), no_xmm_pref] + - rmmod(mm_reg, rm_arg_mm_m64), [mm_reg, rm_arg_mm_m64]) - -addop("movq", [bs8(0x0f), bs8(0x7e), pref_f3] + - rmmod(xmm_reg, rm_arg_xmm_m64), [xmm_reg, rm_arg_xmm_m64]) -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_modrm, rm_arg_xmm_reg)) -addop("movmskpd", [bs8(0x0f), bs8(0x50), pref_66] + - rmmod(reg_modrm, rm_arg_xmm_reg)) - -addop("movnti", [bs8(0x0f), bs8(0xc3)] + rmmod(rmreg), [rm_arg, rmreg]) - -addop("addss", [bs8(0x0f), bs8(0x58), pref_f3] + rmmod(xmm_reg, rm_arg_xmm_m32)) -addop("addsd", [bs8(0x0f), bs8(0x58), pref_f2] + rmmod(xmm_reg, rm_arg_xmm_m64)) - -addop("subss", [bs8(0x0f), bs8(0x5c), pref_f3] + rmmod(xmm_reg, rm_arg_xmm_m32)) -addop("subsd", [bs8(0x0f), bs8(0x5c), pref_f2] + rmmod(xmm_reg, rm_arg_xmm_m64)) - -addop("mulss", [bs8(0x0f), bs8(0x59), pref_f3] + rmmod(xmm_reg, rm_arg_xmm_m32)) -addop("mulsd", [bs8(0x0f), bs8(0x59), pref_f2] + rmmod(xmm_reg, rm_arg_xmm_m64)) - -addop("divss", [bs8(0x0f), bs8(0x5e), pref_f3] + rmmod(xmm_reg, rm_arg_xmm_m32)) -addop("divsd", [bs8(0x0f), bs8(0x5e), pref_f2] + rmmod(xmm_reg, rm_arg_xmm_m64)) - -addop("roundss", [bs8(0x0f), bs8(0x3a), bs8(0x0a), pref_66] + - rmmod(xmm_reg, rm_arg_xmm_m32) + [u08]) -addop("roundsd", [bs8(0x0f), bs8(0x3a), bs8(0x0b), pref_66] + - rmmod(xmm_reg, rm_arg_xmm_m64) + [u08]) - -addop("pminsw", [bs8(0x0f), bs8(0xea), no_xmm_pref] + rmmod(mm_reg, rm_arg_mm)) -addop("pminsw", [bs8(0x0f), bs8(0xea), pref_66] + rmmod(xmm_reg, rm_arg_xmm)) - -addop("ucomiss", [bs8(0x0f), bs8(0x2e), no_xmm_pref] + rmmod(xmm_reg, rm_arg_xmm_m32)) -addop("ucomisd", [bs8(0x0f), bs8(0x2e), pref_66] + rmmod(xmm_reg, rm_arg_xmm_m64)) - - -addop("movzx", [bs8(0x0f), bs("1011011"), w8, sx] + rmmod(rmreg, rm_arg_sx)) -addop("mul", [bs('1111011'), w8] + rmmod(d4, rm_arg_w8)) - -addop("neg", [bs('1111011'), w8] + rmmod(d3, rm_arg_w8)) -addop("nop", [bs8(0x0f), bs8(0x1f)] + rmmod(d0, rm_arg)) # XXX TODO m512 -addop("nop", [bs8(0x0f), bs8(0x1f)] + rmmod(d1, rm_arg)) # XXX TODO m512 -addop("nop", [bs8(0x0f), bs8(0x1f)] + rmmod(d2, rm_arg)) # XXX TODO m512 -addop("nop", [bs8(0x0f), bs8(0x1f)] + rmmod(d3, rm_arg)) # XXX TODO m512 -addop("nop", [bs8(0x0f), bs8(0x1f)] + rmmod(d4, rm_arg)) # XXX TODO m512 -addop("nop", [bs8(0x0f), bs8(0x1f)] + rmmod(d5, rm_arg)) # XXX TODO m512 -addop("nop", [bs8(0x0f), bs8(0x1f)] + rmmod(d6, rm_arg)) # XXX TODO m512 -addop("nop", [bs8(0x0f), bs8(0x1f)] + rmmod(d7, rm_arg)) # XXX TODO m512 -addop("not", [bs('1111011'), w8] + rmmod(d2, rm_arg_w8)) -addop("or", [bs("0000110"), w8, d_eax, d_imm]) -addop("or", [bs("100000"), se, w8] + rmmod(d1, rm_arg_w8) + [d_imm]) -addop("or", [bs("000010"), swapargs, w8] + - rmmod(rmreg, rm_arg_w8), [rm_arg_w8, rmreg]) -addop("out", [bs("1110011"), w8, u08, d_eax]) -addop("out", [bs("1110111"), w8, d_edx, d_eax]) - -addop("outsb", [bs8(0x6e)]) -addop("outsw", [bs8(0x6f), bs_opmode16]) -addop("outsd", [bs8(0x6f), bs_opmode32]) -addop("outsd", [bs8(0x6f), bs_opmode64]) - -addop("setalc", [bs8(0xD6)]) - -# addop("pause", [bs8(0xf3), bs8(0x90)]) - -addop("popw", [bs8(0x8f), stk, bs_opmode16] + rmmod(d0)) -addop("popw", [bs("01011"), stk, reg, bs_opmode16]) -addop("popw", [bs8(0x1f), stk, d_ds, bs_opmode16]) -addop("popw", [bs8(0x07), stk, d_es, bs_opmode16]) -addop("popw", [bs8(0x17), stk, d_ss, bs_opmode16]) -addop("popw", [bs8(0x0f), stk, bs8(0xa1), d_fs, bs_opmode16]) -addop("popw", [bs8(0x0f), stk, bs8(0xa9), d_gs, bs_opmode16]) - -addop("pop", [bs8(0x8f), stk, bs_opmode32] + rmmod(d0)) -addop("pop", [bs("01011"), stk, reg, bs_opmode32]) -addop("pop", [bs8(0x1f), stk, d_ds, bs_opmode32]) -addop("pop", [bs8(0x07), stk, d_es, bs_opmode32]) -addop("pop", [bs8(0x17), stk, d_ss, bs_opmode32]) -addop("pop", [bs8(0x0f), stk, bs8(0xa1), d_fs, bs_opmode32]) -addop("pop", [bs8(0x0f), stk, bs8(0xa9), d_gs, bs_opmode32]) - -addop("pop", [bs8(0x8f), stk, bs_opmode64] + rmmod(d0)) -addop("pop", [bs("01011"), stk, reg, bs_opmode64]) -addop("pop", [bs8(0x1f), stk, d_ds, bs_opmode64]) -addop("pop", [bs8(0x07), stk, d_es, bs_opmode64]) -addop("pop", [bs8(0x17), stk, d_ss, bs_opmode64]) -addop("pop", [bs8(0x0f), stk, bs8(0xa1), d_fs, bs_opmode64]) -addop("pop", [bs8(0x0f), stk, bs8(0xa9), d_gs, bs_opmode64]) - - -addop("popa", [bs8(0x61), stk, bs_opmode16]) -addop("popad", [bs8(0x61), stk, bs_opmode32]) - -addop("popfw", [bs8(0x9d), stk, bs_opmode16]) -addop("popfd", [bs8(0x9d), stk, bs_opmode32]) -addop("popfq", [bs8(0x9d), stk, bs_opmode64]) - -addop("prefetch0", [bs8(0x0f), bs8(0x18)] + rmmod(d1, rm_arg_m08)) -addop("prefetch1", [bs8(0x0f), bs8(0x18)] + rmmod(d2, rm_arg_m08)) -addop("prefetch2", [bs8(0x0f), bs8(0x18)] + rmmod(d3, rm_arg_m08)) -addop("prefetchnta", [bs8(0x0f), bs8(0x18)] + rmmod(d0, rm_arg_m08)) -addop("prefetchw", [bs8(0x0f), bs8(0x0d)] + rmmod(d1, rm_arg_m08)) - -addop("pushw", [bs8(0xff), stk, bs_opmode16] + rmmod(d6)) -addop("pushw", [bs("01010"), stk, reg, bs_opmode16]) -addop("pushw", [bs8(0x6a), s08, stk, bs_opmode16]) -addop("pushw", [bs8(0x68), d_imm, stk, bs_opmode16]) -addop("pushw", [bs8(0x0e), stk, d_cs, bs_opmode16]) -addop("pushw", [bs8(0x16), stk, d_ss, bs_opmode16]) -addop("pushw", [bs8(0x1e), stk, d_ds, bs_opmode16]) -addop("pushw", [bs8(0x06), stk, d_es, bs_opmode16]) -addop("pushw", [bs8(0x0f), stk, bs8(0xa0), d_fs, bs_opmode16]) -addop("pushw", [bs8(0x0f), stk, bs8(0xa8), d_gs, bs_opmode16]) - -addop("push", [bs8(0xff), stk, bs_opmode32] + rmmod(d6)) -addop("push", [bs("01010"), stk, reg, bs_opmode32]) -addop("push", [bs8(0x6a), s08, stk, bs_opmode32]) -addop("push", [bs8(0x68), d_imm, stk, bs_opmode32]) -addop("push", [bs8(0x0e), stk, d_cs, bs_opmode32]) -addop("push", [bs8(0x16), stk, d_ss, bs_opmode32]) -addop("push", [bs8(0x1e), stk, d_ds, bs_opmode32]) -addop("push", [bs8(0x06), stk, d_es, bs_opmode32]) -addop("push", [bs8(0x0f), stk, bs8(0xa0), d_fs, bs_opmode32]) -addop("push", [bs8(0x0f), stk, bs8(0xa8), d_gs, bs_opmode32]) - -addop("push", [bs8(0xff), stk, bs_opmode64] + rmmod(d6)) -addop("push", [bs("01010"), stk, reg, bs_opmode64]) -addop("push", [bs8(0x6a), s08, stk, bs_opmode64]) -addop("push", [bs8(0x68), d_imm, stk, bs_opmode64]) -addop("push", [bs8(0x0e), stk, d_cs, bs_opmode64]) -addop("push", [bs8(0x16), stk, d_ss, bs_opmode64]) -addop("push", [bs8(0x1e), stk, d_ds, bs_opmode64]) -addop("push", [bs8(0x06), stk, d_es, bs_opmode64]) -addop("push", [bs8(0x0f), stk, bs8(0xa0), d_fs, bs_opmode64]) -addop("push", [bs8(0x0f), stk, bs8(0xa8), d_gs, bs_opmode64]) - -addop("pusha", [bs8(0x60), stk, bs_opmode16_no64]) -addop("pushad", [bs8(0x60), stk, bs_opmode32_no64]) - - -addop("pushfw", [bs8(0x9c), stk, bs_opmode16]) -addop("pushfd", [bs8(0x9c), stk, bs_opmode32]) -addop("pushfq", [bs8(0x9c), stk, bs_opmode64]) - -addop("rcl", [bs('110100'), d_cl1, w8] + - rmmod(d2, rm_arg_w8), [rm_arg_w8, d_cl1]) -addop("rcl", [bs('1100000'), w8] + rmmod(d2, rm_arg_w8) + [u08]) -addop("rcr", [bs('110100'), d_cl1, w8] + - rmmod(d3, rm_arg_w8), [rm_arg_w8, d_cl1]) -addop("rcr", [bs('1100000'), w8] + rmmod(d3, rm_arg_w8) + [u08]) -addop("rol", [bs('110100'), d_cl1, w8] - + rmmod(d0, rm_arg_w8), [rm_arg_w8, d_cl1]) -addop("rol", [bs('1100000'), w8] + rmmod(d0, rm_arg_w8) + [u08]) -addop("ror", [bs('110100'), d_cl1, w8] - + rmmod(d1, rm_arg_w8), [rm_arg_w8, d_cl1]) -addop("ror", [bs('1100000'), w8] + rmmod(d1, rm_arg_w8) + [u08]) - -addop("rdmsr", [bs8(0x0f), bs8(0x32)]) -addop("rdpmc", [bs8(0x0f), bs8(0x33)]) -addop("rdtsc", [bs8(0x0f), bs8(0x31)]) -addop("ret", [bs8(0xc3), stk]) -addop("ret", [bs8(0xc2), stk, u16]) -addop("retf", [bs8(0xcb), stk]) -addop("retf", [bs8(0xca), stk, u16]) - -addop("rsm", [bs8(0x0f), bs8(0xaa)]) -addop("sahf", [bs8(0x9e)]) - -# XXX tipo in doc: /4 instead of /6 -addop("sal", [bs('110100'), d_cl1, w8] + - rmmod(d6, rm_arg_w8), [rm_arg_w8, d_cl1]) -addop("sal", [bs('1100000'), w8] + rmmod(d6, rm_arg_w8) + [u08]) -addop("sar", [bs('110100'), d_cl1, w8] + - rmmod(d7, rm_arg_w8), [rm_arg_w8, d_cl1]) -addop("sar", [bs('1100000'), w8] + rmmod(d7, rm_arg_w8) + [u08]) - -addop("scasb", [bs8(0xae)]) -addop("scasw", [bs8(0xaf), bs_opmode16]) -addop("scasd", [bs8(0xaf), bs_opmode32]) -addop("scasq", [bs8(0xaf), bs_opmode64]) - -addop("shl", [bs('110100'), d_cl1, w8] - + rmmod(d4, rm_arg_w8), [rm_arg_w8, d_cl1]) -addop("shl", [bs('1100000'), w8] + rmmod(d4, rm_arg_w8) + [u08]) -addop("shr", [bs('110100'), d_cl1, w8] - + rmmod(d5, rm_arg_w8), [rm_arg_w8, d_cl1]) -addop("shr", [bs('1100000'), w8] + rmmod(d5, rm_arg_w8) + [u08]) - -addop("sbb", [bs("0001110"), w8, d_eax, d_imm]) -addop("sbb", [bs("100000"), se, w8] + rmmod(d3, rm_arg_w8) + [d_imm]) -addop("sbb", [bs("000110"), swapargs, w8] + - rmmod(rmreg, rm_arg_w8), [rm_arg_w8, rmreg]) - -addop("set", [bs8(0x0f), bs('1001'), cond] + rmmod(regnoarg, rm_arg_08)) -addop("sgdt", [bs8(0x0f), bs8(0x01)] + rmmod(d0, modrm=mod_mem)) -addop("shld", [bs8(0x0f), bs8(0xa4)] + - rmmod(rmreg) + [u08], [rm_arg, rmreg, u08]) -addop("shld", [bs8(0x0f), bs8(0xa5)] + - rmmod(rmreg) + [d_cl], [rm_arg, rmreg, d_cl]) -addop("shrd", [bs8(0x0f), bs8(0xac)] + - rmmod(rmreg) + [u08], [rm_arg, rmreg, u08]) -addop("shrd", [bs8(0x0f), bs8(0xad)] + - rmmod(rmreg) + [d_cl], [rm_arg, rmreg, d_cl]) -addop("sidt", [bs8(0x0f), bs8(0x01)] + rmmod(d1, modrm=mod_mem)) -addop("sldt", [bs8(0x0f), bs8(0x00)] + rmmod(d0, rm_arg_x=rm_arg_reg_m16)) -addop("smsw", [bs8(0x0f), bs8(0x01)] + rmmod(d4)) -addop("stc", [bs8(0xf9)]) -addop("std", [bs8(0xfd)]) -addop("sti", [bs8(0xfb)]) -addop("stosb", [bs8(0xaa)]) -addop("stosw", [bs8(0xab), bs_opmode16]) -addop("stosd", [bs8(0xab), bs_opmode32]) -addop("stosq", [bs8(0xab), bs_opmode64]) - -addop("str", [bs8(0x0f), bs8(0x00)] + rmmod(d1)) - -addop("sub", [bs("0010110"), w8, d_eax, d_imm]) -addop("sub", [bs("100000"), se, w8] + rmmod(d5, rm_arg_w8) + [d_imm]) -addop("sub", [bs("001010"), swapargs, w8] + - rmmod(rmreg, rm_arg_w8), [rm_arg_w8, rmreg]) - -addop("syscall", [bs8(0x0f), bs8(0x05)]) -addop("sysenter", [bs8(0x0f), bs8(0x34)]) -addop("sysexit", [bs8(0x0f), bs8(0x35)]) -addop("sysret", [bs8(0x0f), bs8(0x07)]) -addop("test", [bs("1010100"), w8, d_eax, d_imm]) -addop("test", [bs("1111011"), w8] + rmmod(d0, rm_arg_w8) + [d_imm]) -addop("test", [bs("1000010"), w8] + - rmmod(rmreg, rm_arg_w8), [rm_arg_w8, rmreg]) -addop("ud2", [bs8(0x0f), bs8(0x0b)]) -addop("verr", [bs8(0x0f), bs8(0x00)] + rmmod(d4)) -addop("verw", [bs8(0x0f), bs8(0x00)] + rmmod(d5)) -addop("wbinvd", [bs8(0x0f), bs8(0x09)]) -addop("wrmsr", [bs8(0x0f), bs8(0x30)]) -addop("xadd", [bs8(0x0f), bs("1100000"), w8] - + rmmod(rmreg, rm_arg_w8), [rm_arg_w8, rmreg]) - -addop("nop", [bs8(0x90), no_rex], alias=True) - -addop("xchg", [bs('10010'), d_eax, reg]) -addop("xchg", [bs('1000011'), w8] + - rmmod(rmreg, rm_arg_w8), [rm_arg_w8, rmreg]) -addop("xlat", [bs8(0xd7)]) - - -addop("xor", [bs("0011010"), w8, d_eax, d_imm]) -addop("xor", [bs("100000"), se, w8] + rmmod(d6, rm_arg_w8) + [d_imm]) -addop("xor", [bs("001100"), swapargs, w8] + - rmmod(rmreg, rm_arg_w8), [rm_arg_w8, rmreg]) - - -addop("xgetbv", [bs8(0x0f), bs8(0x01), bs8(0xd0)]) - - - -#### MMX/SSE/AVX operations -#### Categories are the same than here: https://software.intel.com/sites/landingpage/IntrinsicsGuide/ -#### - -### Arithmetic (integers) -### - -## Move -# SSE -addop("movapd", [bs8(0x0f), bs("0010100"), swapargs] - + rmmod(xmm_reg, rm_arg_xmm) + [bs_opmode16], [xmm_reg, rm_arg_xmm]) -addop("movaps", [bs8(0x0f), bs("0010100"), swapargs] - + rmmod(xmm_reg, rm_arg_xmm_m128) + [bs_opmode32], [xmm_reg, rm_arg_xmm_m128]) -addop("movaps", [bs8(0x0f), bs("0010100"), swapargs] - + rmmod(xmm_reg, rm_arg_xmm_m128) + [bs_opmode64], [xmm_reg, rm_arg_xmm_m128]) -addop("movdqu", [bs8(0x0f), bs("011"), swapargs, bs("1111"), pref_f3] - + rmmod(xmm_reg, rm_arg_xmm), [xmm_reg, rm_arg_xmm]) -addop("movdqa", [bs8(0x0f), bs("011"), swapargs, bs("1111"), pref_66] - + rmmod(xmm_reg, rm_arg_xmm), [xmm_reg, rm_arg_xmm]) - -addop("movhpd", [bs8(0x0f), bs("0001011"), swapargs, pref_66] + - rmmod(xmm_reg, rm_arg_m64), [xmm_reg, rm_arg_m64]) -addop("movhps", [bs8(0x0f), bs("0001011"), swapargs, no_xmm_pref] + - rmmod(xmm_reg, rm_arg_m64), [xmm_reg, rm_arg_m64]) -addop("movlpd", [bs8(0x0f), bs("0001001"), swapargs, pref_66] + - rmmod(xmm_reg, rm_arg_m64), [xmm_reg, rm_arg_m64]) -addop("movlps", [bs8(0x0f), bs("0001001"), swapargs, no_xmm_pref] + - rmmod(xmm_reg, rm_arg_m64), [xmm_reg, rm_arg_m64]) - -addop("movhlps", [bs8(0x0f), bs8(0x12), no_xmm_pref] + - rmmod(xmm_reg, rm_arg_xmm_reg), [xmm_reg, rm_arg_xmm_reg]) -addop("movlhps", [bs8(0x0f), bs8(0x16), no_xmm_pref] + - rmmod(xmm_reg, rm_arg_xmm_reg), [xmm_reg, rm_arg_xmm_reg]) - -addop("movdq2q", [bs8(0x0f), bs8(0xd6), pref_f2] + - rmmod(mm_reg, rm_arg_xmm_reg), [mm_reg, rm_arg_xmm_reg]) -addop("movq2dq", [bs8(0x0f), bs8(0xd6), pref_f3] + - rmmod(xmm_reg, rm_arg_mm)) - -## Additions -# SSE -addop("paddb", [bs8(0x0f), bs8(0xfc), pref_66] + rmmod(xmm_reg, rm_arg_xmm)) -addop("paddw", [bs8(0x0f), bs8(0xfd), pref_66] + rmmod(xmm_reg, rm_arg_xmm)) -addop("paddd", [bs8(0x0f), bs8(0xfe), pref_66] + rmmod(xmm_reg, rm_arg_xmm)) -addop("paddq", [bs8(0x0f), bs8(0xd4), pref_66] + rmmod(xmm_reg, rm_arg_xmm)) - -addop("paddb", [bs8(0x0f), bs8(0xfc), no_xmm_pref] + rmmod(mm_reg, rm_arg_mm)) -addop("paddw", [bs8(0x0f), bs8(0xfd), no_xmm_pref] + rmmod(mm_reg, rm_arg_mm)) -addop("paddd", [bs8(0x0f), bs8(0xfe), no_xmm_pref] + rmmod(mm_reg, rm_arg_mm)) -addop("paddq", [bs8(0x0f), bs8(0xd4), no_xmm_pref] + rmmod(mm_reg, rm_arg_mm)) - -## Substractions -# SSE -addop("psubb", [bs8(0x0f), bs8(0xf8), pref_66] + rmmod(xmm_reg, rm_arg_xmm)) -addop("psubw", [bs8(0x0f), bs8(0xf9), pref_66] + rmmod(xmm_reg, rm_arg_xmm)) -addop("psubd", [bs8(0x0f), bs8(0xfa), pref_66] + rmmod(xmm_reg, rm_arg_xmm)) -addop("psubq", [bs8(0x0f), bs8(0xfb), pref_66] + rmmod(xmm_reg, rm_arg_xmm)) - -addop("psubb", [bs8(0x0f), bs8(0xf8), no_xmm_pref] + rmmod(mm_reg, rm_arg_mm)) -addop("psubw", [bs8(0x0f), bs8(0xf9), no_xmm_pref] + rmmod(mm_reg, rm_arg_mm)) -addop("psubd", [bs8(0x0f), bs8(0xfa), no_xmm_pref] + rmmod(mm_reg, rm_arg_mm)) -addop("psubq", [bs8(0x0f), bs8(0xfb), no_xmm_pref] + rmmod(mm_reg, rm_arg_mm)) - -### Arithmetic (floating-point) -### - -## Additions -# SSE -addop("addps", [bs8(0x0f), bs8(0x58), no_xmm_pref] + rmmod(xmm_reg, rm_arg_xmm)) -addop("addpd", [bs8(0x0f), bs8(0x58), pref_66] + rmmod(xmm_reg, rm_arg_xmm)) - -## Substractions -# SSE -addop("subps", [bs8(0x0f), bs8(0x5c), no_xmm_pref] + rmmod(xmm_reg, rm_arg_xmm)) -addop("subpd", [bs8(0x0f), bs8(0x5c), pref_66] + rmmod(xmm_reg, rm_arg_xmm)) - -## Multiplications -# SSE -addop("mulps", [bs8(0x0f), bs8(0x59), no_xmm_pref] + rmmod(xmm_reg, rm_arg_xmm)) -addop("mulpd", [bs8(0x0f), bs8(0x59), pref_66] + rmmod(xmm_reg, rm_arg_xmm)) - -## Divisions -# SSE -addop("divps", [bs8(0x0f), bs8(0x5e), no_xmm_pref] + rmmod(xmm_reg, rm_arg_xmm)) -addop("divpd", [bs8(0x0f), bs8(0x5e), pref_66] + rmmod(xmm_reg, rm_arg_xmm)) - -### Logical (floating-point) -### - -## XOR -addop("xorps", [bs8(0x0f), bs8(0x57), no_xmm_pref] + rmmod(xmm_reg, rm_arg_xmm)) -addop("xorpd", [bs8(0x0f), bs8(0x57), pref_66] + rmmod(xmm_reg, rm_arg_xmm)) - -## AND -addop("andps", [bs8(0x0f), bs8(0x54), no_xmm_pref] + rmmod(xmm_reg, rm_arg_xmm)) -addop("andpd", [bs8(0x0f), bs8(0x54), pref_66] + rmmod(xmm_reg, rm_arg_xmm)) - -addop("andnps", [bs8(0x0f), bs8(0x55), no_xmm_pref] + rmmod(xmm_reg, rm_arg_xmm)) -addop("andnpd", [bs8(0x0f), bs8(0x55), pref_66] + rmmod(xmm_reg, rm_arg_xmm)) - -## OR -addop("orps", [bs8(0x0f), bs8(0x56), no_xmm_pref] + rmmod(xmm_reg, rm_arg_xmm)) -addop("orpd", [bs8(0x0f), bs8(0x56), pref_66] + rmmod(xmm_reg, rm_arg_xmm)) - -## AND -# MMX -addop("pand", [bs8(0x0f), bs8(0xdb), no_xmm_pref] + - rmmod(mm_reg, rm_arg_mm), [mm_reg, rm_arg_mm]) -# SSE -addop("pand", [bs8(0x0f), bs8(0xdb), pref_66] + - rmmod(xmm_reg, rm_arg_xmm), [xmm_reg, rm_arg_xmm]) - -## ANDN -# MMX -addop("pandn", [bs8(0x0f), bs8(0xdf), no_xmm_pref] + - rmmod(mm_reg, rm_arg_mm), [mm_reg, rm_arg_mm]) -# SSE -addop("pandn", [bs8(0x0f), bs8(0xdf), pref_66] + - rmmod(xmm_reg, rm_arg_xmm), [xmm_reg, rm_arg_xmm]) - -## OR -# MMX -addop("por", [bs8(0x0f), bs8(0xeb), no_xmm_pref] + - rmmod(mm_reg, rm_arg_mm), [mm_reg, rm_arg_mm]) -# SSE -addop("por", [bs8(0x0f), bs8(0xeb), pref_66] + - rmmod(xmm_reg, rm_arg_xmm), [xmm_reg, rm_arg_xmm]) - -## XOR -# MMX -addop("pxor", [bs8(0x0f), bs8(0xef), no_xmm_pref] + - rmmod(mm_reg, rm_arg_mm)) -# MMX -addop("pxor", [bs8(0x0f), bs8(0xef), pref_66] + - rmmod(xmm_reg, rm_arg_xmm)) - -### Comparisons (floating-point) -### -addop("minps", [bs8(0x0f), bs8(0x5d), no_xmm_pref] + rmmod(xmm_reg, - rm_arg_xmm_m128)) -addop("minss", [bs8(0x0f), bs8(0x5d), pref_f3] + rmmod(xmm_reg, - rm_arg_xmm_m32)) -addop("minpd", [bs8(0x0f), bs8(0x5d), pref_66] + rmmod(xmm_reg, - rm_arg_xmm_m128)) -addop("minsd", [bs8(0x0f), bs8(0x5d), pref_f2] + rmmod(xmm_reg, - rm_arg_xmm_m64)) -addop("maxps", [bs8(0x0f), bs8(0x5f), no_xmm_pref] + rmmod(xmm_reg, - rm_arg_xmm_m128)) -addop("maxpd", [bs8(0x0f), bs8(0x5f), pref_66] + rmmod(xmm_reg, - rm_arg_xmm_m128)) -addop("maxsd", [bs8(0x0f), bs8(0x5f), pref_f2] + rmmod(xmm_reg, rm_arg_xmm_m64)) -addop("maxss", [bs8(0x0f), bs8(0x5f), pref_f3] + rmmod(xmm_reg, rm_arg_xmm_m32)) - -for cond_name, value in [ - ("eq", 0x00), - ("lt", 0x01), - ("le", 0x02), - ("unord", 0x03), - ("neq", 0x04), - ("nlt", 0x05), - ("nle", 0x06), - ("ord", 0x07), -]: - addop("cmp%sps" % cond_name, [bs8(0x0f), bs8(0xc2), no_xmm_pref] + - rmmod(xmm_reg, rm_arg_xmm_m64) + [bs8(value)]) - addop("cmp%spd" % cond_name, [bs8(0x0f), bs8(0xc2), pref_66] + - rmmod(xmm_reg, rm_arg_xmm_m64) + [bs8(value)]) - addop("cmp%sss" % cond_name, [bs8(0x0f), bs8(0xc2), pref_f3] + - rmmod(xmm_reg, rm_arg_xmm_m32) + [bs8(value)]) - addop("cmp%ssd" % cond_name, [bs8(0x0f), bs8(0xc2), pref_f2] + - rmmod(xmm_reg, rm_arg_xmm_m32) + [bs8(value)]) - - - -addop("pshufb", [bs8(0x0f), bs8(0x38), bs8(0x00), no_xmm_pref] + - rmmod(mm_reg, rm_arg_mm_m64)) -addop("pshufb", [bs8(0x0f), bs8(0x38), bs8(0x00), pref_66] + - rmmod(xmm_reg, rm_arg_xmm_m128)) -addop("pshufd", [bs8(0x0f), bs8(0x70), pref_66] + - rmmod(xmm_reg, rm_arg_xmm_m128) + [u08]) -addop("pshuflw", [bs8(0x0f), bs8(0x70), pref_f2] + - rmmod(xmm_reg, rm_arg_xmm_m128) + [u08]) -addop("pshufhw", [bs8(0x0f), bs8(0x70), pref_f3] + - rmmod(xmm_reg, rm_arg_xmm_m128) + [u08]) - - -### Convert -### SS = single precision -### SD = double precision -### - -## SS -> SD -## - -addop("cvtdq2pd", [bs8(0x0f), bs8(0xe6), pref_f3] - + rmmod(xmm_reg, rm_arg_xmm_m64)) -addop("cvtdq2ps", [bs8(0x0f), bs8(0x5b), no_xmm_pref] - + rmmod(xmm_reg, rm_arg_xmm)) -addop("cvtpd2dq", [bs8(0x0f), bs8(0xe6), pref_f2] - + rmmod(xmm_reg, rm_arg_xmm)) -addop("cvtpd2pi", [bs8(0x0f), bs8(0x2d), pref_66] - + rmmod(mm_reg, rm_arg_xmm)) -addop("cvtpd2ps", [bs8(0x0f), bs8(0x5a), pref_66] - + rmmod(xmm_reg, rm_arg_xmm)) -addop("cvtpi2pd", [bs8(0x0f), bs8(0x2a), pref_66] - + rmmod(xmm_reg, rm_arg_mm_m64)) -addop("cvtpi2ps", [bs8(0x0f), bs8(0x2a), no_xmm_pref] - + rmmod(xmm_reg, rm_arg_mm_m64)) -addop("cvtps2dq", [bs8(0x0f), bs8(0x5b), pref_66] - + rmmod(xmm_reg, rm_arg_xmm)) -addop("cvtps2pd", [bs8(0x0f), bs8(0x5a), no_xmm_pref] - + rmmod(xmm_reg, rm_arg_xmm_m64)) -addop("cvtps2pi", [bs8(0x0f), bs8(0x2d), no_xmm_pref] - + rmmod(mm_reg, rm_arg_xmm_m64)) -addop("cvtsd2si", [bs8(0x0f), bs8(0x2d), pref_f2] - + rmmod(reg, rm_arg_xmm_m64)) -addop("cvtsd2ss", [bs8(0x0f), bs8(0x5a), pref_f2] - + rmmod(xmm_reg, rm_arg_xmm_m64)) -addop("cvtsi2sd", [bs8(0x0f), bs8(0x2a), pref_f2] - + rmmod(xmm_reg, rm_arg)) -addop("cvtsi2ss", [bs8(0x0f), bs8(0x2a), xmmreg, pref_f3] - + rmmod(xmm_reg, rm_arg)) -addop("cvtss2sd", [bs8(0x0f), bs8(0x5a), pref_f3] - + rmmod(xmm_reg, rm_arg_xmm_m32)) -addop("cvtss2si", [bs8(0x0f), bs8(0x2d), pref_f3] - + rmmod(rmreg, rm_arg_xmm_m32)) -addop("cvttpd2pi",[bs8(0x0f), bs8(0x2c), pref_66] - + rmmod(mm_reg, rm_arg_xmm)) -addop("cvttpd2dq",[bs8(0x0f), bs8(0xe6), pref_66] - + rmmod(xmm_reg, rm_arg_xmm)) -addop("cvttps2dq",[bs8(0x0f), bs8(0x5b), pref_f3] - + rmmod(xmm_reg, rm_arg_xmm)) -addop("cvttps2pi",[bs8(0x0f), bs8(0x2c), no_xmm_pref] - + rmmod(mm_reg, rm_arg_xmm_m64)) -addop("cvttsd2si",[bs8(0x0f), bs8(0x2c), pref_f2] - + rmmod(reg, rm_arg_xmm_m64)) -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] + - rmmod(d2, rm_arg_xmm) + [u08], [rm_arg_xmm, u08]) - -addop("psrlq", [bs8(0x0f), bs8(0xd3), no_xmm_pref] + - rmmod(mm_reg, rm_arg_mm), [mm_reg, rm_arg_mm]) -addop("psrlq", [bs8(0x0f), bs8(0xd3), pref_66] + - rmmod(xmm_reg, rm_arg_xmm), [xmm_reg, rm_arg_xmm]) - - -addop("psrld", [bs8(0x0f), bs8(0x72), no_xmm_pref] + - rmmod(d2, rm_arg_mm) + [u08], [rm_arg_mm, u08]) -addop("psrld", [bs8(0x0f), bs8(0x72), pref_66] + - rmmod(d2, rm_arg_xmm) + [u08], [rm_arg_xmm, u08]) - -addop("psrld", [bs8(0x0f), bs8(0xd2), no_xmm_pref] + - rmmod(mm_reg, rm_arg_mm), [mm_reg, rm_arg_mm]) -addop("psrld", [bs8(0x0f), bs8(0xd2), pref_66] + - rmmod(xmm_reg, rm_arg_xmm), [xmm_reg, rm_arg_xmm]) - -addop("psrldq", [bs8(0x0f), bs8(0x73), pref_66] + - rmmod(d3, rm_arg_xmm) + [u08], [rm_arg_xmm, u08]) - -addop("psrlw", [bs8(0x0f), bs8(0x71), no_xmm_pref] + - rmmod(d2, rm_arg_mm) + [u08], [rm_arg_mm, u08]) -addop("psrlw", [bs8(0x0f), bs8(0x71), pref_66] + - rmmod(d2, rm_arg_xmm) + [u08], [rm_arg_xmm, u08]) - -addop("psrlw", [bs8(0x0f), bs8(0xd1), no_xmm_pref] + - rmmod(mm_reg, rm_arg_mm_m64), [mm_reg, rm_arg_mm_m64]) -addop("psrlw", [bs8(0x0f), bs8(0xd1), pref_66] + - rmmod(xmm_reg, rm_arg_xmm_m128), [xmm_reg, rm_arg_xmm_m128]) - -addop("psraw", [bs8(0x0f), bs8(0xe1), no_xmm_pref] + - rmmod(mm_reg, rm_arg_mm_m64), [mm_reg, rm_arg_mm_m64]) -addop("psraw", [bs8(0x0f), bs8(0xe1), pref_66] + - rmmod(xmm_reg, rm_arg_xmm_m128), [xmm_reg, rm_arg_xmm_m128]) - -addop("psraw", [bs8(0x0f), bs8(0x71), no_xmm_pref] + - rmmod(d4, rm_arg_mm_m64) + [u08], [rm_arg_mm_m64, u08]) -addop("psraw", [bs8(0x0f), bs8(0x71), pref_66] + - rmmod(d4, rm_arg_xmm_m128) + [u08], [rm_arg_xmm_m128, u08]) - -addop("psrad", [bs8(0x0f), bs8(0xe2), no_xmm_pref] + - rmmod(mm_reg, rm_arg_mm_m64), [mm_reg, rm_arg_mm_m64]) -addop("psrad", [bs8(0x0f), bs8(0xe2), pref_66] + - rmmod(xmm_reg, rm_arg_xmm_m128), [xmm_reg, rm_arg_xmm_m128]) - -addop("psrad", [bs8(0x0f), bs8(0x72), no_xmm_pref] + - rmmod(d4, rm_arg_mm_m64) + [u08], [rm_arg_mm_m64, u08]) -addop("psrad", [bs8(0x0f), bs8(0x72), pref_66] + - rmmod(d4, rm_arg_xmm_m128) + [u08], [rm_arg_xmm_m128, u08]) - - -addop("psllq", [bs8(0x0f), bs8(0x73), no_xmm_pref] + - rmmod(d6, rm_arg_mm) + [u08], [rm_arg_mm, u08]) -addop("psllq", [bs8(0x0f), bs8(0x73), pref_66] + - rmmod(d6, rm_arg_xmm) + [u08], [rm_arg_xmm, u08]) - -addop("psllq", [bs8(0x0f), bs8(0xf3), no_xmm_pref] + - rmmod(mm_reg, rm_arg_mm), [mm_reg, rm_arg_mm]) -addop("psllq", [bs8(0x0f), bs8(0xf3), pref_66] + - rmmod(xmm_reg, rm_arg_xmm), [xmm_reg, rm_arg_xmm]) - - -addop("pslld", [bs8(0x0f), bs8(0x72), no_xmm_pref] + - rmmod(d6, rm_arg_mm) + [u08], [rm_arg_mm, u08]) -addop("pslld", [bs8(0x0f), bs8(0x72), pref_66] + - rmmod(d6, rm_arg_xmm) + [u08], [rm_arg_xmm, u08]) - -addop("pslld", [bs8(0x0f), bs8(0xf2), no_xmm_pref] + - rmmod(mm_reg, rm_arg_mm), [mm_reg, rm_arg_mm]) -addop("pslld", [bs8(0x0f), bs8(0xf2), pref_66] + - rmmod(xmm_reg, rm_arg_xmm), [xmm_reg, rm_arg_xmm]) - - -addop("psllw", [bs8(0x0f), bs8(0x71), no_xmm_pref] + - rmmod(d6, rm_arg_mm) + [u08], [rm_arg_mm, u08]) -addop("psllw", [bs8(0x0f), bs8(0x71), pref_66] + - rmmod(d6, rm_arg_xmm) + [u08], [rm_arg_xmm, u08]) - -addop("psllw", [bs8(0x0f), bs8(0xf1), no_xmm_pref] + - rmmod(mm_reg, rm_arg_mm), [mm_reg, rm_arg_mm]) -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)) -addop("pmaxub", [bs8(0x0f), bs8(0xde), pref_66] + - rmmod(xmm_reg, rm_arg_xmm)) - -addop("pmaxuw", [bs8(0x0f), bs8(0x38), bs8(0x3e), pref_66] + - rmmod(xmm_reg, rm_arg_xmm)) - -addop("pmaxud", [bs8(0x0f), bs8(0x38), bs8(0x3f), pref_66] + - rmmod(xmm_reg, rm_arg_xmm)) - -addop("pmaxsw", [bs8(0x0f), bs8(0xee), no_xmm_pref] + - rmmod(mm_reg, rm_arg_mm_m64)) -addop("pmaxsw", [bs8(0x0f), bs8(0xee), pref_66] + - rmmod(xmm_reg, rm_arg_xmm_m128)) - -addop("pminub", [bs8(0x0f), bs8(0xda), no_xmm_pref] + - rmmod(mm_reg, rm_arg_mm)) -addop("pminub", [bs8(0x0f), bs8(0xda), pref_66] + - rmmod(xmm_reg, rm_arg_xmm)) - -addop("pminuw", [bs8(0x0f), bs8(0x38), bs8(0x3a), pref_66] + - rmmod(xmm_reg, rm_arg_xmm)) - -addop("pminud", [bs8(0x0f), bs8(0x38), bs8(0x3b), pref_66] + - rmmod(xmm_reg, rm_arg_xmm)) - - -addop("pcmpeqb", [bs8(0x0f), bs8(0x74), no_xmm_pref] + - rmmod(mm_reg, rm_arg_mm)) -addop("pcmpeqb", [bs8(0x0f), bs8(0x74), pref_66] + - rmmod(xmm_reg, rm_arg_xmm)) - -addop("pcmpeqw", [bs8(0x0f), bs8(0x75), no_xmm_pref] + - rmmod(mm_reg, rm_arg_mm)) -addop("pcmpeqw", [bs8(0x0f), bs8(0x75), pref_66] + - rmmod(xmm_reg, rm_arg_xmm)) - -addop("pcmpeqd", [bs8(0x0f), bs8(0x76), no_xmm_pref] + - rmmod(mm_reg, rm_arg_mm)) -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("pcmpgtw", [bs8(0x0f), bs8(0x65), no_xmm_pref] + - rmmod(mm_reg, rm_arg_mm)) -addop("pcmpgtw", [bs8(0x0f), bs8(0x65), 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] + - 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)) -addop("punpckhbw", [bs8(0x0f), bs8(0x68), pref_66] + - rmmod(xmm_reg, rm_arg_xmm)) - -addop("punpckhwd", [bs8(0x0f), bs8(0x69), no_xmm_pref] + - rmmod(mm_reg, rm_arg_mm)) -addop("punpckhwd", [bs8(0x0f), bs8(0x69), pref_66] + - rmmod(xmm_reg, rm_arg_xmm)) - -addop("punpckhdq", [bs8(0x0f), bs8(0x6a), no_xmm_pref] + - rmmod(mm_reg, rm_arg_mm)) -addop("punpckhdq", [bs8(0x0f), bs8(0x6a), pref_66] + - rmmod(xmm_reg, rm_arg_xmm)) - -addop("punpckhqdq", [bs8(0x0f), bs8(0x6d), pref_66] + - rmmod(xmm_reg, rm_arg_xmm)) - - - -addop("punpcklbw", [bs8(0x0f), bs8(0x60), no_xmm_pref] + - rmmod(mm_reg, rm_arg_mm)) -addop("punpcklbw", [bs8(0x0f), bs8(0x60), pref_66] + - rmmod(xmm_reg, rm_arg_xmm)) - -addop("punpcklwd", [bs8(0x0f), bs8(0x61), no_xmm_pref] + - rmmod(mm_reg, rm_arg_mm)) -addop("punpcklwd", [bs8(0x0f), bs8(0x61), pref_66] + - rmmod(xmm_reg, rm_arg_xmm)) - -addop("punpckldq", [bs8(0x0f), bs8(0x62), no_xmm_pref] + - rmmod(mm_reg, rm_arg_mm)) -addop("punpckldq", [bs8(0x0f), bs8(0x62), pref_66] + - rmmod(xmm_reg, rm_arg_xmm)) - -addop("punpcklqdq", [bs8(0x0f), bs8(0x6c), pref_66] + - rmmod(xmm_reg, rm_arg_xmm)) - - -addop("unpckhps", [bs8(0x0f), bs8(0x15), no_xmm_pref] + - rmmod(xmm_reg, rm_arg_xmm)) -addop("unpckhpd", [bs8(0x0f), bs8(0x15), pref_66] + - rmmod(xmm_reg, rm_arg_xmm)) - - -addop("unpcklps", [bs8(0x0f), bs8(0x14), no_xmm_pref] + - rmmod(xmm_reg, rm_arg_xmm)) -addop("unpcklpd", [bs8(0x0f), bs8(0x14), pref_66] + - rmmod(xmm_reg, rm_arg_xmm)) - - - -addop("pinsrb", [bs8(0x0f), bs8(0x3a), bs8(0x20), pref_66] + - rmmod(xmm_reg, rm_arg_reg_m08) + [u08]) -addop("pinsrd", [bs8(0x0f), bs8(0x3a), bs8(0x22), pref_66, bs_opmode32] + - rmmod(xmm_reg, rm_arg) + [u08]) -addop("pinsrq", [bs8(0x0f), bs8(0x3a), bs8(0x22), pref_66] + - rmmod(xmm_reg, rm_arg_m64) + [bs_opmode64] + [u08]) - -addop("pinsrw", [bs8(0x0f), bs8(0xc4), no_xmm_pref] + - rmmod(mm_reg, rm_arg_reg_m16) + [u08]) -addop("pinsrw", [bs8(0x0f), bs8(0xc4), pref_66] + - rmmod(xmm_reg, rm_arg_reg_m16) + [u08]) - - -addop("pextrb", [bs8(0x0f), bs8(0x3a), bs8(0x14), pref_66] + - rmmod(xmm_reg, rm_arg_reg_m08) + [u08], [rm_arg_reg_m08, xmm_reg, u08]) -addop("pextrd", [bs8(0x0f), bs8(0x3a), bs8(0x16), pref_66, bs_opmode32] + - rmmod(xmm_reg, rm_arg) + [u08], [rm_arg, xmm_reg, u08]) -addop("pextrq", [bs8(0x0f), bs8(0x3a), bs8(0x16), pref_66] + - rmmod(xmm_reg, rm_arg_m64) + [bs_opmode64] + [u08], [rm_arg_m64, xmm_reg, u08]) - - -addop("pextrw", [bs8(0x0f), bs8(0x3a), bs8(0x15), pref_66] + - rmmod(xmm_reg, rm_arg_reg_m16) + [u08], [rm_arg_reg_m16, xmm_reg, u08]) -addop("pextrw", [bs8(0x0f), bs8(0xc5), no_xmm_pref] + - rmmod(rmreg, rm_arg_mm) + [u08], [rmreg, rm_arg_mm, u08]) -addop("pextrw", [bs8(0x0f), bs8(0xc5), pref_66] + - rmmod(rmreg, rm_arg_xmm) + [u08], [rmreg, rm_arg_xmm, u08]) - - -addop("sqrtpd", [bs8(0x0f), bs8(0x51), pref_66] + - rmmod(xmm_reg, rm_arg_xmm)) -addop("sqrtps", [bs8(0x0f), bs8(0x51), no_xmm_pref] + - rmmod(xmm_reg, rm_arg_xmm)) -addop("sqrtsd", [bs8(0x0f), bs8(0x51), pref_f2] + - rmmod(xmm_reg, rm_arg_xmm_m64)) -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_modrm, rm_arg_mm_reg)) -addop("pmovmskb", [bs8(0x0f), bs8(0xd7), pref_66] + - rmmod(reg_modrm, rm_arg_xmm_reg)) - -addop("shufps", [bs8(0x0f), bs8(0xc6), no_xmm_pref] + - rmmod(xmm_reg, rm_arg_xmm) + [u08]) -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)) - -addop("packsswb", [bs8(0x0f), bs8(0x63), no_xmm_pref] + - rmmod(mm_reg, rm_arg_mm_m64)) -addop("packsswb", [bs8(0x0f), bs8(0x63), pref_66] + - rmmod(xmm_reg, rm_arg_xmm_m128)) -addop("packssdw", [bs8(0x0f), bs8(0x6b), no_xmm_pref] + - rmmod(mm_reg, rm_arg_mm_m64)) -addop("packssdw", [bs8(0x0f), bs8(0x6b), pref_66] + - rmmod(xmm_reg, rm_arg_xmm_m128)) - -addop("packuswb", [bs8(0x0f), bs8(0x67), no_xmm_pref] + - rmmod(mm_reg, rm_arg_mm_m64)) -addop("packuswb", [bs8(0x0f), bs8(0x67), pref_66] + - rmmod(xmm_reg, rm_arg_xmm_m128)) - -addop("pmullw", [bs8(0x0f), bs8(0xd5), no_xmm_pref] + - rmmod(mm_reg, rm_arg_mm_m64)) -addop("pmullw", [bs8(0x0f), bs8(0xd5), pref_66] + - rmmod(xmm_reg, rm_arg_xmm_m128)) -addop("pmulhuw", [bs8(0x0f), bs8(0xe4), no_xmm_pref] + - rmmod(mm_reg, rm_arg_mm_m64)) -addop("pmulhuw", [bs8(0x0f), bs8(0xe4), pref_66] + - rmmod(xmm_reg, rm_arg_xmm_m128)) -addop("pmulhw", [bs8(0x0f), bs8(0xe5), no_xmm_pref] + - rmmod(mm_reg, rm_arg_mm_m64)) -addop("pmulhw", [bs8(0x0f), bs8(0xe5), pref_66] + - rmmod(xmm_reg, rm_arg_xmm_m128)) -addop("pmuludq", [bs8(0x0f), bs8(0xf4), no_xmm_pref] + - rmmod(mm_reg, rm_arg_mm_m64)) -addop("pmuludq", [bs8(0x0f), bs8(0xf4), pref_66] + - rmmod(xmm_reg, rm_arg_xmm_m128)) - - -addop("psubusb", [bs8(0x0f), bs8(0xd8), no_xmm_pref] + - rmmod(mm_reg, rm_arg_mm_m64)) -addop("psubusb", [bs8(0x0f), bs8(0xd8), pref_66] + - rmmod(xmm_reg, rm_arg_xmm_m128)) -addop("psubusw", [bs8(0x0f), bs8(0xd9), no_xmm_pref] + - rmmod(mm_reg, rm_arg_mm_m64)) -addop("psubusw", [bs8(0x0f), bs8(0xd9), pref_66] + - rmmod(xmm_reg, rm_arg_xmm_m128)) -addop("psubsb", [bs8(0x0f), bs8(0xe8), no_xmm_pref] + - rmmod(mm_reg, rm_arg_mm_m64)) -addop("psubsb", [bs8(0x0f), bs8(0xe8), pref_66] + - rmmod(xmm_reg, rm_arg_xmm_m128)) -addop("psubsw", [bs8(0x0f), bs8(0xe9), no_xmm_pref] + - rmmod(mm_reg, rm_arg_mm_m64)) -addop("psubsw", [bs8(0x0f), bs8(0xe9), pref_66] + - rmmod(xmm_reg, rm_arg_xmm_m128)) - - -addop("paddusb", [bs8(0x0f), bs8(0xdc), no_xmm_pref] + - rmmod(mm_reg, rm_arg_mm_m64)) -addop("paddusb", [bs8(0x0f), bs8(0xdc), pref_66] + - rmmod(xmm_reg, rm_arg_xmm_m128)) -addop("paddusw", [bs8(0x0f), bs8(0xdd), no_xmm_pref] + - rmmod(mm_reg, rm_arg_mm_m64)) -addop("paddusw", [bs8(0x0f), bs8(0xdd), pref_66] + - rmmod(xmm_reg, rm_arg_xmm_m128)) -addop("paddsb", [bs8(0x0f), bs8(0xec), no_xmm_pref] + - rmmod(mm_reg, rm_arg_mm_m64)) -addop("paddsb", [bs8(0x0f), bs8(0xec), pref_66] + - rmmod(xmm_reg, rm_arg_xmm_m128)) -addop("paddsw", [bs8(0x0f), bs8(0xed), no_xmm_pref] + - rmmod(mm_reg, rm_arg_mm_m64)) -addop("paddsw", [bs8(0x0f), bs8(0xed), pref_66] + - rmmod(xmm_reg, rm_arg_xmm_m128)) - -addop("pmaddwd", [bs8(0x0f), bs8(0xf5), no_xmm_pref] + - rmmod(mm_reg, rm_arg_mm_m64)) -addop("pmaddwd", [bs8(0x0f), bs8(0xf5), pref_66] + - rmmod(xmm_reg, rm_arg_xmm_m128)) - -addop("psadbw", [bs8(0x0f), bs8(0xf6), no_xmm_pref] + - rmmod(mm_reg, rm_arg_mm_m64)) -addop("psadbw", [bs8(0x0f), bs8(0xf6), pref_66] + - rmmod(xmm_reg, rm_arg_xmm_m128)) - -addop("pavgb", [bs8(0x0f), bs8(0xe0), no_xmm_pref] + - rmmod(mm_reg, rm_arg_mm_m64)) -addop("pavgb", [bs8(0x0f), bs8(0xe0), pref_66] + - rmmod(xmm_reg, rm_arg_xmm_m128)) -addop("pavgw", [bs8(0x0f), bs8(0xe3), no_xmm_pref] + - rmmod(mm_reg, rm_arg_mm_m64)) -addop("pavgw", [bs8(0x0f), bs8(0xe3), pref_66] + - rmmod(xmm_reg, rm_arg_xmm_m128)) - -addop("maskmovq", [bs8(0x0f), bs8(0xf7), no_xmm_pref] + - rmmod(mm_reg, rm_arg_mm_reg)) -addop("maskmovdqu", [bs8(0x0f), bs8(0xf7), pref_66] + - rmmod(xmm_reg, rm_arg_xmm_reg)) - -addop("emms", [bs8(0x0f), bs8(0x77)]) - -addop("incssp", [pref_f3, bs8(0x0f), bs8(0xae)] + rmmod(d5)) -addop("rdssp", [pref_f3, bs8(0x0f), bs8(0x1e)] + rmmod(d1, modrm=mod_reg)) -addop("saveprevssp", [pref_f3, bs8(0x0f), bs8(0x01), bs8(0xea)]) -addop("rstorssp", [pref_f3, bs8(0x0f), bs8(0x01)] + rmmod(d5, rm_arg_xmm, modrm=mod_mem)) -addop("wrss", [bs8(0x0f), bs8(0x38), bs8(0xf6)] + rmmod(rmreg, rm_arg), [rm_arg, rmreg]) -addop("wruss", [pref_66, bs8(0x0f), bs8(0x38), bs8(0xf5)] + rmmod(rmreg, rm_arg), [rm_arg, rmreg]) -addop("setssbsy", [pref_f3, bs8(0x0f), bs8(0x01), bs8(0xe8)]) -addop("clrssbsy", [pref_f3, bs8(0x0f), bs8(0xae)] + rmmod(d6, rm_arg_xmm)) -addop("endbr64", [pref_f3, bs8(0x0f), bs8(0x1e), bs8(0xfa)]) -addop("endbr32", [pref_f3, bs8(0x0f), bs8(0x1e), bs8(0xfb)]) - -mn_x86.bintree = factor_one_bit(mn_x86.bintree) -# mn_x86.bintree = factor_fields_all(mn_x86.bintree) -""" -mod reg r/m - XX XXX XXX - -""" - - -def print_size(e): - print(e, e.size) - return e |