1005 lines
31 KiB
Python
1005 lines
31 KiB
Python
# 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()
|