Added <Raw> pseudo instruction to both assemblers + corresponding test

This commit is contained in:
hakril
2019-08-07 17:42:56 +02:00
parent 960838ae3c
commit 6fcba46739
4 changed files with 46 additions and 12 deletions
+13 -4
View File
@@ -12,6 +12,14 @@ if capstone:
disassembleur = capstone.Cs(capstone.CS_ARCH_X86, capstone.CS_MODE_64)
disassembleur.detail = True
@pytest.fixture
def need_capstone():
if capstone is None:
raise pytest.Skip("Capstone is not installed")
return True
pytestmark = pytest.mark.usefixtures("need_capstone")
def disas(x):
return list(disassembleur.disasm(x, 0))
@@ -264,6 +272,7 @@ def test_assembler():
CheckInstr(Add, must_fail=True)('RAX', 0xffffffff)
code = MultipleInstr()
code += Nop()
code += Rep + Nop()
@@ -271,10 +280,10 @@ def test_assembler():
print(repr(code.get_code()))
assert code.get_code() == "\x90\xf3\x90\xc3"
if capstone is None:
test_assembler = pytest.mark.skip("Capstone not installed")(test_assembler)
# pytestmark = pytest.mark.skip("YOLO")
def test_simple_x64_raw_instruction():
# Test the fake instruction "raw"
# By emetting a multi-char nop manually
CheckInstr(Raw, expected_result="nop word ptr [rax + rax]")("66 0F 1F 84 00 00 00 00 00")
if __name__ == "__main__":
test_assembler()
+21 -7
View File
@@ -13,6 +13,14 @@ if capstone:
disassembleur = capstone.Cs(capstone.CS_ARCH_X86, capstone.CS_MODE_32)
disassembleur.detail = True
@pytest.fixture
def need_capstone():
if capstone is None:
raise pytest.Skip("Capstone is not installed")
return True
pytestmark = pytest.mark.usefixtures("need_capstone")
def disas(x):
return list(disassembleur.disasm(x, 0))
@@ -38,6 +46,13 @@ class CheckInstr(object):
print("{0} {1}".format(capres.mnemonic, capres.op_str))
if len(res) != len(capres.bytes):
raise AssertionError("Not all bytes have been used by the disassembler")
if self.expected_result is not None:
if "{0} {1}".format(capres.mnemonic, capres.op_str) == self.expected_result:
return True
else:
raise AssertionError("Expected result <{0}> got <{1}>".format(self.expected_result, "{0} {1}".format(capres.mnemonic, capres.op_str)))
self.compare_mnemo(capres)
self.compare_args(args, capres)
@@ -48,12 +63,6 @@ class CheckInstr(object):
return True
def compare_args(self, args, capres):
if self.expected_result is not None:
result = "{0} {1}".format(capres.mnemonic, capres.op_str)
if result != self.expected_result:
raise AssertionError("Bad expected result expect <{0}> got <{1}>".format(self.expected_result, result))
return
capres_op = list(capres.operands)
if len(args) != len(capres_op):
raise AssertionError("Expected {0} operands got {1}".format(len(args), len(capres_op)))
@@ -190,9 +199,9 @@ def test_assembler():
CheckInstr(x86.Test)('EAX', 'EAX')
CheckInstr(x86.Test, expected_result="test edi, ecx")('ECX', 'EDI')
CheckInstr(x86.Test)(mem('[ECX + 0x100]'), 'ECX')
assert x86.Test(mem('[ECX + 0x100]'), 'ECX').get_code() == x86.Test('ECX', mem('[ECX + 0x100]')).get_code()
assert Xchg('EAX', 'ECX').get_code() == Xchg('ECX', 'EAX').get_code()
@@ -203,6 +212,11 @@ def test_assembler():
print(repr(code.get_code()))
assert code.get_code() == "\x90\xf3\x90\xc3"
def test_simple_x64_raw_instruction():
# Test the fake instruction "raw"
# By emetting a multi-char nop manually
CheckInstr(Raw, expected_result="nop word ptr [eax + eax]")("66 0F 1F 84 00 00 00 00 00")
if capstone is None:
test_assembler = pytest.mark.skip("Capstone not installed")(test_assembler)
+10
View File
@@ -1059,6 +1059,16 @@ def JmpAt(addr):
code += Jmp('RAX')
return code
class Raw(Instruction):
"""Output raw data"""
def __init__(self, *initial_args):
if len(initial_args) != 1:
raise ValueError("raw 'opcode' only accept one argument")
# Accept space
self.data = initial_args[0].replace(" ", "").decode("hex")
def get_code(self):
return self.data
class Label(object):
def __init__(self, name):
+2 -1
View File
@@ -858,7 +858,8 @@ class Raw(Instruction):
def __init__(self, *initial_args):
if len(initial_args) != 1:
raise ValueError("raw 'opcode' only accept one argument")
self.data = initial_args[0].decode("hex")
# Accept space
self.data = initial_args[0].replace(" ", "").decode("hex")
def get_code(self):
return self.data