mirror of
https://github.com/hakril/PythonForWindows
synced 2026-06-08 14:31:45 +00:00
Added <Raw> pseudo instruction to both assemblers + corresponding test
This commit is contained in:
@@ -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()
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user