# udis86 - test/testgen.py # # Copyright (c) 2009 Vivek Thampi # All rights reserved. # # Redistribution and use in source and binary forms, with or without modification, # are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation # and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON # ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import os import sys import random if ( len( os.getenv( 'UD_SCRIPT_DIR', "" ) ) ): scriptsPath = os.getenv( 'UD_SCRIPT_DIR' ) + "/scripts" else: scriptsPath = '../scripts' sys.path.append( scriptsPath ); import ud_opcode def bits2name(bits): bits2name_map = { 8 : "byte", 16 : "word", 32 : "dword", 64 : "qword", 80 : "tword", 128 : "oword", 256 : "yword", } return bits2name_map[bits] class UdTestGenerator( ud_opcode.UdOpcodeTables ): OprTable = [] ExcludeList = ( 'fcomp3', 'fcom2', 'fcomp5', 'fstp1', 'fstp8', 'fstp9', 'fxch4', 'fxch7', 'nop', 'xchg', 'movd', 'pmulhrw', # yasm bug 'vcvtpd2ps', # operand casting issues 'vcvtpd2dq', # - ditto - 'vcvttpd2dq', # - ditto - 'vmovd', 'vmovq' ) def __init__(self, mode, xml): super(UdTestGenerator, self).__init__(xml=xml) self.mode = mode pass def OprMem(self, size=None, cast=False): choices = [] if self.mode < 64: choices = ["[bx+si+0x1234]", "[bx+0x10]", "[bp+di+0x27]", "[di+0x100]"] choices.extend(("[eax+ebx]", "[ebx+ecx*4]", "[ebp+0x10]")) if self.mode == 64: choices.extend(("[rax+rbx]", "[rbx+r8-0x10]")) addr = random.choice(choices) if cast and size is not None: addr = "%s %s" % (bits2name(size), addr) return addr def OprImm(self, size, cast=False): imm = "0x%x" % random.randint(2, 1 << (size - 1)) if cast and size is not None: imm = "%s %s" % (bits2name(size), imm) return imm def Gpr(self, size): if size == 8: choices = ['al', 'cl'] if self.mode == 64: choices.extend(['sil', 'r10b']) elif size == 16: choices = ['ax', 'bp', 'dx'] if self.mode == 64: choices.extend(['r8w', 'r14w']) elif size == 32: choices = ['eax', 'ebp', 'edx'] if self.mode == 64: choices.extend(['r10d', 'r12d']) elif size == 64: choices = ['rax', 'rsi', 'rsp'] if self.mode == 64: choices.extend(['r9', 'r13']) return random.choice(choices) def Xmm(self): r = 16 if self.mode == 64 else 8 return "xmm%d" % random.choice(range(r)) def Ymm(self): r = 16 if self.mode == 64 else 8 return "ymm%d" % random.choice(range(r)) def Mmx(self): return "mm%d" % random.choice(range(8)) def Modrm_RM_GPR(self, size, cast=False): return random.choice([self.Gpr(size), self.OprMem(size=size, cast=cast)]) def Modrm_RM_XMM(self, size, cast=False): return random.choice([self.Xmm(), self.OprMem(size=size, cast=cast)]) def OprRxb(self, n): regs = [ 'al', 'cl', 'dl', 'bl' ] if self.mode == 64 and random.choice((False, True)): regs += [ 'spl', 'bpl', 'sil', 'dil', 'r8b', 'r9b', 'r10b', 'r11b', 'r12b', 'r13b', 'r14b', 'r15b' ] n |= random.choice((0, 8)) else: regs += [ 'ah', 'ch', 'dh', 'bh' ] return regs[n] def OprRxw(self, n): regs = [ 'ax', 'cx', 'dx', 'bx', 'sp', 'bp', 'si', 'di' ] if self.mode == 64 and random.choice((False, True)): regs += [ 'r8w', 'r9w', 'r10w', 'r11w', 'r12w', 'r13w', 'r14w', 'r15w' ] n |= random.choice((0, 8)) return regs[n] def OprRxd(self, n): regs = [ 'eax', 'ecx', 'edx', 'ebx', 'esp', 'ebp', 'esi', 'edi' ] if self.mode == 64 and random.choice((False, True)): regs += [ 'r8d', 'r9d', 'r10d', 'r11d', 'r12d', 'r13d', 'r14d', 'r15d' ] n |= random.choice((0, 8)) return regs[n] def OprRxq(self, n): regs = [ 'rax', 'rcx', 'rdx', 'rbx', 'rsp', 'rbp', 'rsi', 'rdi', 'r8', 'r9', 'r10', 'r11', 'r12', 'r13', 'r14', 'r15' ] n |= random.choice((0, 8)) return regs[n] def OprRxv(self, n): choices = [ self.OprRxw(n), self.OprRxd(n) ] if self.mode == 64: choices.append(self.OprRxq(n)) return random.choice(choices) def OprRxz(self, n): choices = [ self.OprRxw(n), self.OprRxd(n) ] return random.choice(choices) def OprRxy(self, n): choices = [ self.OprRxd(n) ] if self.mode == 64: choices.append(self.OprRxq(n)) return random.choice(choices) Opr_R0b = lambda s: s.OprRxb(0); Opr_R1b = lambda s: s.OprRxb(1); Opr_R2b = lambda s: s.OprRxb(2); Opr_R3b = lambda s: s.OprRxb(3); Opr_R4b = lambda s: s.OprRxb(4); Opr_R5b = lambda s: s.OprRxb(5); Opr_R6b = lambda s: s.OprRxb(6); Opr_R7b = lambda s: s.OprRxb(7); Opr_R0y = lambda s: s.OprRxy(0); Opr_R1y = lambda s: s.OprRxy(1); Opr_R2y = lambda s: s.OprRxy(2); Opr_R3y = lambda s: s.OprRxy(3); Opr_R4y = lambda s: s.OprRxy(4); Opr_R5y = lambda s: s.OprRxy(5); Opr_R6y = lambda s: s.OprRxy(6); Opr_R7y = lambda s: s.OprRxy(7); Opr_R0v = lambda s: s.OprRxv(0); Opr_R1v = lambda s: s.OprRxv(1); Opr_R2v = lambda s: s.OprRxv(2); Opr_R3v = lambda s: s.OprRxv(3); Opr_R4v = lambda s: s.OprRxv(4); Opr_R5v = lambda s: s.OprRxv(5); Opr_R6v = lambda s: s.OprRxv(6); Opr_R7v = lambda s: s.OprRxv(7); Opr_R0z = lambda s: s.OprRxz(0); Opr_R1z = lambda s: s.OprRxz(1); Opr_R2z = lambda s: s.OprRxz(2); Opr_R3z = lambda s: s.OprRxz(3); Opr_R4z = lambda s: s.OprRxz(4); Opr_R5z = lambda s: s.OprRxz(5); Opr_R6z = lambda s: s.OprRxz(6); Opr_R7z = lambda s: s.OprRxz(7); def Insn_Av(self): return random.choice([("word 0x100:0x100",), ("dword 0x100:0xfaddbc",)]) def Opr_R(self): if self.mode == 64: return self.OprRxq(random.choice(range(8))) return self.OprRxd(random.choice(range(8))); def Opr_C(self): return "cr3" def Opr_D(self): return "dr0" def Opr_S(self): return "fs" def Opr_ST0(self): return "st0" def Opr_ST1(self): return "st1" def Opr_ST2(self): return "st2" def Opr_ST3(self): return "st3" def Opr_ST4(self): return "st4" def Opr_ST5(self): return "st5" def Opr_ST6(self): return "st6" def Opr_ST7(self): return "st7" def Opr_CS(self): return "cs" def Opr_GS(self): return "gs" def Opr_ES(self): return "es" def Opr_FS(self): return "fs" def Opr_DS(self): return "ds" def Opr_SS(self): return "ss" def Opr_Ib(self, cast=False): return self.OprImm(8, cast=cast) def Opr_Iw(self, cast=False): return self.OprImm(16, cast=cast) def Opr_Id(self, cast=False): return self.OprImm(32, cast=cast) def Opr_Iq(self, cast=False): return self.OprImm(64, cast=cast) def Opr_Iz(self, cast=False): return random.choice((self.OprImm(16, cast=cast), self.OprImm(32, cast=cast))) Opr_sIz = Opr_Iz def Opr_Iw(self, cast=False): return self.OprImm(16, cast=cast) def Opr_I1(self, cast=False): return "1" def Opr_eAX(self): return random.choice(['ax', 'eax']) def Opr_rAX(self): choices = ['ax', 'eax'] if self.mode == 64: choices.append('rax') return random.choice(choices) def Insn_rAX_Iz(self): choices = [('ax', self.Opr_Iw()), ('eax', self.Opr_Id())] if self.mode == 64: choices.append(('rax', self.Opr_Id())) return random.choice(choices) Insn_rAX_sIz = Insn_rAX_Iz def Insn_Rxv_Iv(self, n): choices = [(self.OprRxw(n), self.Opr_Iw()), (self.OprRxd(n), self.Opr_Id())] if self.mode == 64: choices.append((self.OprRxq(n), self.Opr_Iq())) return random.choice(choices) Insn_R0v_Iv = lambda s: s.Insn_Rxv_Iv(0) Insn_R1v_Iv = lambda s: s.Insn_Rxv_Iv(1) Insn_R2v_Iv = lambda s: s.Insn_Rxv_Iv(2) Insn_R3v_Iv = lambda s: s.Insn_Rxv_Iv(3) Insn_R4v_Iv = lambda s: s.Insn_Rxv_Iv(4) Insn_R5v_Iv = lambda s: s.Insn_Rxv_Iv(5) Insn_R6v_Iv = lambda s: s.Insn_Rxv_Iv(6) Insn_R7v_Iv = lambda s: s.Insn_Rxv_Iv(7) def Insn_Rxv_rAX(self, n): choices = [(self.OprRxw(n), "ax"), (self.OprRxd(n), "eax")] if self.mode == 64: choices.append((self.OprRxq(n), "rax")) return random.choice(choices) Insn_R0v_rAX = lambda s: s.Insn_Rxv_rAX(0) Insn_R1v_rAX = lambda s: s.Insn_Rxv_rAX(1) Insn_R2v_rAX = lambda s: s.Insn_Rxv_rAX(2) Insn_R3v_rAX = lambda s: s.Insn_Rxv_rAX(3) Insn_R4v_rAX = lambda s: s.Insn_Rxv_rAX(4) Insn_R5v_rAX = lambda s: s.Insn_Rxv_rAX(5) Insn_R6v_rAX = lambda s: s.Insn_Rxv_rAX(6) Insn_R7v_rAX = lambda s: s.Insn_Rxv_rAX(7) def Opr_Gb(self): return self.Gpr(8) def Opr_Gw(self): return self.Gpr(16) def Opr_Gd(self): return self.Gpr(32) def Opr_Gq(self): return self.Gpr(64) def Opr_Gz(self): return random.choice([self.Gpr(16), self.Gpr(32)]) def Opr_Gv(self): choices = [self.Gpr(16), self.Gpr(32)] if self.mode == 64: choices.append(self.Gpr(64)) return random.choice(choices) def Opr_Gy(self): choices = [self.Gpr(32)] if self.mode == 64: choices.append(self.Gpr(64)) return random.choice(choices) def Opr_M(self): return self.OprMem(); def Opr_U(self, L=False): return self.Xmm() if not L else self.Ymm() Opr_Ux = Opr_U def Opr_N(self): return self.Mmx(); def Opr_Mb(self, cast=False): return self.OprMem(size=8, cast=cast); def Opr_Mw(self, cast=False): return self.OprMem(size=16, cast=cast); def Opr_Md(self, cast=False): return self.OprMem(size=32, cast=cast); def Opr_Mq(self, cast=False): return self.OprMem(size=64, cast=cast); def Opr_Mdq(self, cast=False): return self.OprMem(size=128, cast=cast); def Opr_Mt(self, cast=True): return self.OprMem(size=80, cast=cast); def Opr_MwRd(self, cast=True): return random.choice((self.Opr_Mw(cast=cast), self.Opr_Gd())) def Opr_MwRv(self, cast=False): return random.choice((self.Opr_Mw(cast=cast), self.Opr_Gv())) def Opr_MwRy(self, cast=True): return random.choice((self.Opr_Mw(cast=cast), self.Opr_Gy())) def Opr_MdRy(self, cast=False): return random.choice((self.Opr_Md(cast=cast), self.Opr_Gy())) def Opr_MbRv(self, cast=False): return random.choice((self.Opr_Mb(cast=cast), self.Opr_Gv())) def Opr_MbRd(self, cast=False): return random.choice((self.Opr_Mb(cast=cast), self.Opr_Gd())) def Opr_MwRw(self, cast=False): return random.choice((self.Opr_Mw(cast=cast), self.Opr_Gw())) def Opr_MwU(self, cast=False): return random.choice((self.Opr_Mw(cast=cast), self.Xmm())) def Opr_MdU(self, cast=False): return random.choice((self.Opr_Md(cast=cast), self.Xmm())) def Opr_MqU(self, cast=False): return random.choice((self.Opr_Mq(cast=cast), self.Xmm())) def Insn_V_MwU(self, cast=False): return (self.Opr_V(), self.Opr_MwU(cast=True)) def Insn_V_MdU(self, cast=False): return self.Opr_V(), self.Opr_MdU(cast=True) def Insn_V_MqU(self, cast=False): return self.Opr_V(), self.Opr_MqU(cast=True) def Insn_Vx_MwU(self): L = random.choice((True, False)) if self.vexl else False return self.Opr_V(L), self.Opr_MwU(cast=True) def Insn_Vx_MdU(self, cast=False): L = random.choice((True, False)) if self.vexl else False return self.Opr_V(), self.Opr_MdU(cast=True) def Insn_Vx_MqU(self, cast=False): L = random.choice((True, False)) if self.vexl else False return self.Opr_V(), self.Opr_MqU(cast=True) def Insn_V_Md(self, cast=False): return self.Opr_V(), self.Opr_Md(cast=True) def Insn_V_Mq(self, cast=False): return self.Opr_V(), self.Opr_Mq(cast=True) def Insn_Mq_V(self): x, y = self.Insn_V_Mq() return y, x def Insn_Md_V(self): x, y = self.Insn_V_Md() return y, x def Insn_Vqq_Mq(self, cast=False): return self.Opr_Vqq(), self.Opr_Mq(cast=True) def Insn_Wdq_Vqq_Ib(self, cast=False): return self.Opr_W(size=128, cast=True), self.Opr_Vqq(), self.Opr_Ib() def Insn_MbRv(self): return [self.Opr_MbRv(cast=True)] def Insn_MbRv_V_Ib(self): return [self.Opr_MbRv(cast=True), self.Opr_V(), self.Opr_Ib()] def Insn_V_MbRd_Ib(self): return [self.Opr_V(), self.Opr_MbRd(cast=True), self.Opr_Ib()] def Insn_MwRv(self): return [self.Opr_MwRv(cast=True)] def Insn_MwRd_V_Ib(self): return [self.Opr_MwRd(cast=True), self.Opr_V(), self.Opr_Ib()] Insn_MwRd_Vx_Ib = Insn_MwRd_V_Ib def Insn_S_MwRv(self): if self.mode == 64: return [self.Opr_S(), self.Opr_MwRd(cast=False)] if self.mode == 16: return [self.Opr_S(), self.Opr_MwRw(cast=False)] if self.mode == 32: return [self.Opr_S(), self.Opr_MwRd(cast=False)] def Insn_Mw(self): return [self.Opr_Mw(cast=True)] def Insn_Md(self): return [self.Opr_Md(cast=True)] def Insn_Mq(self): return [self.Opr_Mq(cast=True)] def Opr_Eb(self, cast=False): return self.Modrm_RM_GPR(8, cast=cast) def Opr_Ew(self, cast=False): return self.Modrm_RM_GPR(16, cast=cast) def Opr_Ed(self, cast=False): return self.Modrm_RM_GPR(32, cast=cast) def Opr_Eq(self, cast=False): return self.Modrm_RM_GPR(64, cast=cast) def Opr_Ey(self, cast=False): choices = [self.Modrm_RM_GPR(32, cast=cast)] if self.mode == 64: choices.append(self.Modrm_RM_GPR(64, cast=cast)) return random.choice(choices) def Insn_Fv(self): return ("far "+ self.Opr_Mv(cast=True),) def Insn_V_Ew_Ib(self): return self.Opr_V(), self.Opr_Ew(cast=True), self.Opr_Ib() def Insn_V_Eq_Ib(self): return self.Opr_V(), self.Opr_Eq(cast=True), self.Opr_Ib() def Insn_V_Mo(self): return self.Opr_V(), self.Opr_M() def Insn_V_Md_Ib(self): return self.Opr_V(), self.Opr_Md(cast=True), self.Opr_Ib() def Insn_V_Ed(self): return self.Opr_V(), self.Opr_Ed(cast=True) def Insn_V_Ed_Ib(self): x, y = self.Insn_V_Ed() return x, y, self.Opr_Ib() def Insn_P_Ew_Ib(self): return self.Opr_P(), self.Opr_Ew(cast=True), self.Opr_Ib() def Insn_V_Ey(self): return self.Opr_V(), self.Opr_Ey(cast=True) def Insn_Ey_V(self): x, y = self.Insn_V_Ey() return y, x def Insn_P_Ey(self): return self.Opr_P(), self.Opr_Ey(cast=True) def Insn_Ey_P(self): x, y = self.Insn_P_Ey() return y, x def Opr_Mv(self, cast=False): choices = [self.Opr_Mw(cast), self.Opr_Md(cast)] if self.mode == 64: choices.append(self.Opr_Mq(cast)) return random.choice(choices) def Opr_Ev(self, cast=False): choices = [self.Opr_Ew(cast), self.Opr_Ed(cast)] if self.mode == 64: choices.append(self.Opr_Eq(cast)) return random.choice(choices) def Insn_Ev(self): choices = [self.Modrm_RM_GPR(16, cast=True), self.Modrm_RM_GPR(32, cast=True)] if self.mode == 64: choices.append(self.Modrm_RM_GPR(64, cast=True)) return [random.choice(choices)] def Opr_V(self, L=False): return self.Xmm() if not L else self.Ymm() Opr_Vdq = Xmm Opr_Vqq = Ymm Opr_Hqq = Ymm def Opr_Vsd(self, L=False): return self.Xmm() if not L else self.Ymm() def Opr_L(self, L=False): return self.Xmm() if not L else self.Ymm() def Opr_H(self, L=False): return self.Opr_V(L) def Opr_W(self, L=False, cast=False, size=None): if not L: if size is None: size = 128 return random.choice([self.Xmm(), self.OprMem(size=size, cast=cast)]) else: if size is None: size = 256 return random.choice([self.Ymm(), self.OprMem(size=size, cast=cast)]) Opr_Wx = Opr_W def Opr_Wdq(self, cast=False): return self.Opr_W(cast=cast, size=128) def Opr_Wsd(self, L=False): return random.choice([self.Xmm(), self.OprMem(size=64, cast=False)]) def Opr_Wdq(self, cast=False): return random.choice([self.Xmm(), self.OprMem(size=128, cast=cast)]) def Opr_Wqq(self, L=False): return random.choice([self.Ymm(), self.OprMem(size=256, cast=False)]) def Insn_V_H_W(self): L = random.choice((True, False)) if self.vexl else False return [self.Opr_V(L), self.Opr_H(L), self.Opr_W(L)] def Insn_Vx_Wx(self): L = random.choice((True, False)) if self.vexl else False return [self.Opr_V(L), self.Opr_W(L, cast=False)] def Insn_Wx_Vx(self): x, y = self.Insn_Vx_Wx() return y, x def Insn_Vx_U(self): L = random.choice((True, False)) if self.vexl else False return self.Opr_V(L), self.Opr_U(L) def Insn_Eq_Vx(self): L = random.choice((True, False)) if self.vexl else False return self.Opr_Eq(), self.Opr_V(L) def Insn_Ey_Vx(self): L = random.choice((True, False)) if self.vexl else False return self.Opr_Ey(cast=True), self.Opr_V(L) def Insn_Vx_Ey(self): x, y = self.Insn_Ey_Vx() return y, x def Insn_Vdq_Wx(self): L = random.choice((True, False)) if self.vexl else False return [self.Opr_Vdq(), self.Opr_W(L, cast=True)] def Insn_Vdq_W(self): return [self.Opr_V(), self.Opr_W(cast=False)] def Insn_V_Wdq(self): return [self.Opr_V(), self.Opr_W(cast=False)] def Insn_Vx_Ux(self): L = random.choice((True, False)) if self.vexl else False return self.Opr_V(L), self.Opr_U(L) def Insn_Vx_Wdq(self): L = random.choice((True, False)) if self.vexl else False return [self.Opr_V(L), self.Opr_W(L=False, cast=L)] def Insn_Vx_Wx_Ib(self): L = random.choice((True, False)) if self.vexl else False return [self.Opr_V(L), self.Opr_W(L), self.Opr_Ib()] def Insn_Vx_Hx_Wx(self): L = random.choice((True, False)) if self.vexl else False return [self.Opr_V(L), self.Opr_H(L), self.Opr_W(L)] def Insn_Hx_Vx_Wx(self): L = random.choice((True, False)) if self.vexl else False return [self.Opr_H(L), self.Opr_V(L), self.Opr_W(L)] def Insn_Vx_Hx_Ux(self): L = random.choice((True, False)) if self.vexl else False return [self.Opr_V(L), self.Opr_H(L), self.Opr_U(L)] def Insn_Hx_Ux_Ib(self): L = random.choice((True, False)) if self.vexl else False return [self.Opr_H(L), self.Opr_U(L), self.Opr_Ib()] def Insn_Vx_Hx_Ey(self): L = random.choice((True, False)) if self.vexl else False return self.Opr_V(L), self.Opr_H(L), self.Opr_Ey(cast=True) def Insn_Vx_Hx_Ed_Ib(self): L = random.choice((True, False)) if self.vexl else False return self.Opr_V(L), self.Opr_H(L), self.Opr_Ed(cast=True), self.Opr_Ib() Insn_V_H_Ed_Ib = Insn_Vx_Hx_Ed_Ib def Insn_V_H_Eq_Ib(self): return self.Opr_V(), self.Opr_H(), self.Opr_Eq(cast=True), self.Opr_Ib() def Insn_V_H_MbRd_Ib(self): return self.Opr_V(), self.Opr_H(), self.Opr_MbRd(cast=True), self.Opr_Ib() def Insn_Vx_Hx_Wx_Ib(self): L = random.choice((True, False)) if self.vexl else False return [self.Opr_V(L), self.Opr_H(L), self.Opr_W(L), self.Opr_Ib()] def Insn_Vx_Hx_M(self): L = random.choice((True, False)) if self.vexl else False return self.Opr_V(L), self.Opr_H(L), self.Opr_M() def Insn_Vx_Hx_Md_Ib(self): L = random.choice((True, False)) if self.vexl else False return [self.Opr_V(L), self.Opr_H(L), self.Opr_Md(cast=True), self.Opr_Ib()] def Insn_Vqq_Hqq_Wdq_Ib(self): return [self.Opr_Vqq(), self.Opr_Hqq(), self.Opr_Wdq(cast=True), self.Opr_Ib()] def Insn_Vx_Hx_Wx_Lx(self): L = random.choice((True, False)) if self.vexl else False return [self.Opr_V(L), self.Opr_H(L), self.Opr_W(L), self.Opr_L(L)] def Insn_Vx_Hx_MqU(self): L = random.choice((True, False)) if self.vexl else False return self.Opr_V(L), self.Opr_H(L), self.Opr_MqU(cast=True) def Insn_Vx_Hx_MdU(self): L = random.choice((True, False)) if self.vexl else False return self.Opr_V(L), self.Opr_H(L), self.Opr_MdU(cast=True) def Insn_Vx_M(self): L = random.choice((True, False)) if self.vexl else False return self.Opr_V(L), self.Opr_M() def Insn_M_Vx(self): x, y = self.Insn_Vx_M() return y, x def Insn_MdRy_Vx_Ib(self): L = random.choice((True, False)) if self.vexl else False return self.Opr_MdRy(cast=True), self.Opr_V(L), self.Opr_Ib() def Insn_MdRy_V_Ib(self): return self.Opr_MdRy(cast=True), self.Opr_V(), self.Opr_Ib() def Insn_MdRv_Vx_Ib(self): L = random.choice((True, False)) if self.vexl else False return self.Opr_MdRv(cast=True), self.Opr_V(L), self.Opr_Ib() def Insn_MdRv_V_Ib(self): return self.Opr_MdRv(cast=True), self.Opr_V(), self.Opr_Ib() def Insn_MwRv_Vx_Ib(self): L = random.choice((True, False)) if self.vexl else False return self.Opr_MwRv(cast=True), self.Opr_V(L), self.Opr_Ib() def Insn_MwRv_V_Ib(self): return self.Opr_MwRv(cast=True), self.Opr_V(), self.Opr_Ib() def Insn_Ed_Vx_Ib(self): L = random.choice((True, False)) if self.vexl else False return self.Opr_Ed(cast=True), self.Opr_V(L), self.Opr_Ib() def Opr_P(self): return self.Mmx() def Opr_Q(self, cast=False): return random.choice([self.Mmx(), self.OprMem(size=64, cast=cast)]) def Opr_CL(self): return "cl" def Opr_AL(self): return "al" def Opr_Ob(self): return "[0x100]" def Insn_rAX_Ov(self): choices = [ ("ax", "[0x100]"), ("eax", "[0x1000]") ] if self.mode == 64: choices.append(("rax", "[0x1223221]")) return random.choice(choices) def Insn_Ov_rAX(self): x, y = self.Insn_rAX_Ov() return y, x def Opr_AX(self): return "ax" def Opr_DX(self): return "dx" def Insn_Eb_CL(self): return self.Opr_Eb(cast=True), self.Opr_CL() def Insn_Ev_CL(self): return self.Opr_Ev(cast=True), self.Opr_CL() def Insn_Eb(self): return [self.Modrm_RM_GPR(size=8, cast=True)] def Insn_Ew(self): return [self.Modrm_RM_GPR(size=16, cast=True)] def Insn_Ev_Gv(self): choices = [ (self.Opr_Ew(), self.Opr_Gw()), (self.Opr_Ed(), self.Opr_Gd()) ] if self.mode == 64: choices.append((self.Opr_Eq(), self.Opr_Gq())) return random.choice(choices) def Insn_Ev_Gy(self): choices = [ (self.Opr_Ew(), self.Opr_Gd()), (self.Opr_Ed(), self.Opr_Gd()) ] if self.mode == 64: choices.append((self.Opr_Eq(), self.Opr_Gq())) return random.choice(choices) def Insn_Ev_Gv_CL(self): x, y = self.Insn_Ev_Gv(); return x, y, self.Opr_CL() def Insn_Gv_Ev_CL(self): x, y = self.Insn_Ev_Gv(); return y, x, self.Opr_CL() def Insn_Gv_Ev_Ib(self): x, y = self.Insn_Ev_Gv(); return y, x, self.Opr_Ib(cast=False) Insn_Gv_Ev_sIb = Insn_Gv_Ev_Ib def Insn_Gv_Ev_Iz(self): choices = [ (self.Opr_Gw(), self.Opr_Ew(), self.Opr_Iw()), (self.Opr_Gd(), self.Opr_Ed(), self.Opr_Id()) ] if self.mode == 64: choices.append((self.Opr_Gq(), self.Opr_Eq(), self.Opr_Iz())) return random.choice(choices) def Insn_Ev_Ib(self): return self.Opr_Ev(cast=True), self.Opr_Ib() Insn_Ev_sIb = Insn_Ev_Ib def Insn_Gq_Ed(self): return self.Opr_Gq(), self.Opr_Ed(cast=True) def Insn_Gy_Eb(self): return self.Opr_Gy(), self.Opr_Eb(cast=True) def Insn_Gy_Ew(self): return self.Opr_Gy(), self.Opr_Ew(cast=True) def Insn_Gy_W(self): choices = [(self.Gpr(32), self.Opr_W(size=32, cast=False)),] if self.mode == 64: choices.append([self.Gpr(64), self.Opr_W(size=32, cast=True)]) return random.choice(choices) def Insn_Gy_MqU(self): choices = [(self.Gpr(32), self.Opr_W(size=64, cast=True)),] if self.mode == 64: choices.append([self.Gpr(64), self.Opr_W(size=64, cast=False)]) return random.choice(choices) def Insn_Gy_MdU(self): choices = [(self.Gpr(32), self.Opr_W(size=32, cast=False)),] if self.mode == 64: choices.append([self.Gpr(64), self.Opr_W(size=32, cast=True)]) return random.choice(choices) def Insn_Gd_Ux(self): L = random.choice((True, False)) if self.vexl else False return self.Gpr(32), self.Opr_U(L) def Insn_Gy_Ux(self): L = random.choice((True, False)) if self.vexl else False choices = [(self.Gpr(32), self.Opr_U(L)),] if self.mode == 64: choices.append([self.Gpr(64), self.Opr_U(L)]) return random.choice(choices) def Insn_Gy_Ux_Ib(self): x, y = self.Insn_Gy_Ux() return x, y, self.Opr_Ib() def Insn_Ev_Iz(self): choices = [(self.Opr_Ew(cast=True), self.Opr_Iw()), (self.Opr_Ed(cast=True), self.Opr_Id())] if self.mode == 64: choices.append((self.Opr_Eq(cast=True), self.Opr_Id())) return random.choice(choices) Insn_Ev_sIz = Insn_Ev_Iz def Insn_Gv_Ev(self): x, y = self.Insn_Ev_Gv(); return (y, x) def Insn_Gy_Ev(self): x, y = self.Insn_Ev_Gy(); return (y, x) def Insn_Gv_Eb(self): return (self.Opr_Gv(), self.Opr_Eb(cast=True)) def Insn_Gv_Ew(self): choices = [(self.Opr_Gw(), self.Opr_Ew(cast=False)), (self.Opr_Gd(), self.Opr_Ew(cast=True))] if self.mode == 64: choices.append((self.Opr_Gq(), self.Opr_Ew(cast=True))) return random.choice(choices) def Insn_V_Q(self): return [self.Opr_V(), self.Opr_Q(cast=True)] def Insn_Eb_Ib(self): return (self.Opr_Eb(cast=True), self.Opr_Ib(cast=False)) def Insn_Eb_I1(self): return (self.Opr_Eb(cast=True), self.Opr_I1()) def Insn_Ev_I1(self): return (self.Opr_Ev(cast=True), self.Opr_I1()) def Insn_Ev_Ib(self): return (self.Opr_Ev(cast=True), self.Opr_Ib(cast=False)) Insn_Ev_sIb = Insn_Ev_Ib def Insn_Ev_Gv_Ib(self): choices = [ (self.Opr_Ew(), self.Opr_Gw(), self.Opr_Ib(cast=False)), (self.Opr_Ed(), self.Opr_Gd(), self.Opr_Ib(cast=False)) ] if self.mode == 64: choices.append( (self.Opr_Eq(), self.Opr_Gq(), self.Opr_Ib(cast=False)) ) return random.choice(choices) Insn_Ev_Gv_sIb = Insn_Ev_Gv_Ib def Insn_Ev_V_Ib(self): return self.Opr_Ev(cast=True), self.Opr_V(), self.Opr_Ib(cast=False) def Insn_Ed_V_Ib(self): return self.Opr_Ed(cast=True), self.Opr_V(), self.Opr_Ib(cast=False) def Insn_Ew_V_Ib(self): return (self.Opr_Ew(cast=True), self.Opr_V(), self.Opr_Ib(cast=False)) def generate_yasm( self, mode, seed ): opr_combos = {} random.seed( seed ) print("[bits %s]" % mode) for insn in self.getInsnList(): if insn.mnemonic in self.ExcludeList: continue if insn.vendor == 'intel': continue if ((insn.mode == '!64' and self.mode == 64) or (insn.mode == '64' and self.mode != 64)): continue if insn.osize == '64' and self.mode != 64: continue if insn.isDef64(): continue if len(insn.operands) == 0: continue if "Jb" in insn.operands or "Jz" in insn.operands: continue if insn.lookupPrefix("vexl"): self.vexl = True else: self.vexl = False fusedName = '_'.join(insn.operands) if fusedName not in opr_combos: opr_combos[fusedName] = { 'covered' : False, 'freq' : 0 } opr_combos[fusedName]['freq'] += 1 fn = getattr(self, "Insn_" + fusedName , None) if fn is not None: operands = ", ".join(fn()) else: oprgens = [ getattr(self, "Opr_" + opr, None) for opr in insn.operands ] if None not in oprgens: operands = ", ".join([ oprgen() for oprgen in oprgens ]) else: operands = None if operands is not None: print("\t%s %s" % (insn.mnemonic, operands)) opr_combos[fusedName]['covered'] = True # stats total = 0 covered = 0 for combo in sorted(opr_combos, key=lambda k: opr_combos[k]['freq']): total += 1 is_covered = opr_combos[combo]['covered'] covered += (1 if is_covered else 0) if not is_covered: sys.stderr.write("==> %12s : %5d\n" % (combo, opr_combos[combo]['freq'])) sys.stderr.write("MODE%s: Coverage = %d / %d (%d%%)\n" % (self.mode, covered, total, (100 * covered / total))) def main(): generator = UdTestGenerator(mode=int(sys.argv[3]), xml=sys.argv[1]) generator.generate_yasm( sys.argv[ 3 ], int( sys.argv[ 2 ] ) ) if __name__ == '__main__': main()