From d767ae5b8bfcba2dbfbbb4b0bffb54b4a5104649 Mon Sep 17 00:00:00 2001 From: Clement Rouault Date: Fri, 11 Dec 2015 18:42:31 +0100 Subject: [PATCH] Add And/Or + Fix Sub in simple_x[86|64] --- native_exec/simple_x64.py | 19 +++++++++++++++--- native_exec/simple_x86.py | 16 ++++++++++++++- native_exec/test_simple_x64.py | 36 +++++++++++++++++++++++++++++++++- native_exec/test_simple_x86.py | 17 ++++++++++++++++ 4 files changed, 83 insertions(+), 5 deletions(-) diff --git a/native_exec/simple_x64.py b/native_exec/simple_x64.py index 7562999..a034ba1 100644 --- a/native_exec/simple_x64.py +++ b/native_exec/simple_x64.py @@ -574,8 +574,6 @@ class ModRM_REG64__MEM(SubModRM): FIRE_UP_SIB = not arg2.base or arg2.base.upper() in ["RSP", "RBP"] or arg2.index if not FIRE_UP_SIB: - self.is_rex_needed = True - self.rex[4] = 1 self.setup_reg_as_register(arg1) self.setup_rm_as_mem_base(arg2.base) #self.setup_rm_as_register(arg2.base) @@ -748,6 +746,20 @@ class Inc(Instruction): encoding = [(RawBits.from_int(8, 0xff), Slash(0))] +class And(Instruction): + default_32_bits = True + encoding = [(RawBits.from_int(8, 0x25), RegisterRax(), Imm32()), + (RawBits.from_int(8, 0x81), Slash(4), Imm32()), + (RawBits.from_int(8, 0x21), ModRM([ModRM_REG__REG, ModRM_REG64__MEM]))] + + +class Or(Instruction): + default_32_bits = True + encoding = [(RawBits.from_int(8, 0x0d), RegisterRax(), Imm32()), + (RawBits.from_int(8, 0x81), Slash(1), Imm32()), + (RawBits.from_int(8, 0x09), ModRM([ModRM_REG__REG, ModRM_REG64__MEM]))] + + class Add(Instruction): default_32_bits = True encoding = [(RawBits.from_int(8, 0x05), RegisterRax(), Imm32()), @@ -758,7 +770,8 @@ class Add(Instruction): class Sub(Instruction): default_32_bits = True encoding = [(RawBits.from_int(8, 0x2D), RegisterRax(), Imm32()), - (RawBits.from_int(8, 0x81), Slash(5), Imm32())] + (RawBits.from_int(8, 0x81), Slash(5), Imm32()), + (RawBits.from_int(8, 0x29), ModRM([ModRM_REG__REG, ModRM_REG64__MEM]))] class Out(Instruction): diff --git a/native_exec/simple_x86.py b/native_exec/simple_x86.py index 99480a9..7aaccbf 100644 --- a/native_exec/simple_x86.py +++ b/native_exec/simple_x86.py @@ -624,10 +624,24 @@ class Add(Instruction): (RawBits.from_int(8, 0x81), Slash(0), Imm32()), (RawBits.from_int(8, 0x01), ModRM([ModRM_REG__REG, ModRM_REG__MEM]))] +class And(Instruction): + default_32_bits = True + encoding = [(RawBits.from_int(8, 0x25), RegisterEax(), Imm32()), + (RawBits.from_int(8, 0x81), Slash(4), Imm32()), + (RawBits.from_int(8, 0x21), ModRM([ModRM_REG__REG, ModRM_REG__MEM]))] + + +class Or(Instruction): + default_32_bits = True + encoding = [(RawBits.from_int(8, 0x0d), RegisterEax(), Imm32()), + (RawBits.from_int(8, 0x81), Slash(1), Imm32()), + (RawBits.from_int(8, 0x09), ModRM([ModRM_REG__REG, ModRM_REG__MEM]))] + class Sub(Instruction): encoding = [(RawBits.from_int(8, 0x2D), RegisterEax(), Imm32()), - (RawBits.from_int(8, 0x81), Slash(5), Imm32())] + (RawBits.from_int(8, 0x81), Slash(5), Imm32()), + (RawBits.from_int(8, 0x29), ModRM([ModRM_REG__REG, ModRM_REG__MEM]))] class Mov(Instruction): diff --git a/native_exec/test_simple_x64.py b/native_exec/test_simple_x64.py index 6de9fb9..f0c618f 100644 --- a/native_exec/test_simple_x64.py +++ b/native_exec/test_simple_x64.py @@ -13,14 +13,20 @@ mnemonic_name_exception = {'movabs': 'mov'} class TestInstr(object): - def __init__(self, instr_to_test, immediat_accepted=None, must_fail=None): + def __init__(self, instr_to_test, immediat_accepted=None, must_fail=None, debug=False): self.instr_to_test = instr_to_test self.immediat_accepted = immediat_accepted self.must_fail = must_fail + self.debug = debug def __call__(self, *args): try: + if self.debug: + import pdb;pdb.set_trace() + pdb.DONE = True res = bytes(self.instr_to_test(*args).get_code()) + if self.debug: + print(repr(res)) except ValueError as e: if self.must_fail == True: return True @@ -103,6 +109,10 @@ TestInstr(Add)('RAX', mem('[R9 + R8 * 2 + 0x7fffffff]')) TestInstr(Add)('RAX', mem('[R9 + R8 * 2 + -0x80000000]')) TestInstr(Add)('RAX', mem('[-1]')) TestInstr(Add)('RAX', mem('[0x7fffffff]')) + +TestInstr(Sub)('RCX', 'RSP') +TestInstr(Sub)('RCX', mem('[RSP]')) + TestInstr(Xor)('R15', mem('[RAX + R8 * 2 + 0x11223344]')) TestInstr(Xor)('RAX', 'RAX') TestInstr(Cmp)('RAX', -1) @@ -116,6 +126,23 @@ TestInstr(Mov)('R8', 0x1122334455667788) TestInstr(Mov)('RCX', -1) TestInstr(Mov, immediat_accepted=-1)('RCX', 0xffffffffffffffff) TestInstr(Mov)(mem('gs:[0x1122334455667788]'), 'RAX') + +TestInstr(And)('RCX', 'RBX') +TestInstr(And)('RAX', 0x11223344) +TestInstr(And)('RAX', mem('[RAX + 1]')) +TestInstr(And)(mem('[RAX + 1]'), 'R8') +TestInstr(And)(mem('[EAX + 1]'), 'R8') +TestInstr(And)(mem('[RAX + 1]'), 'EAX') + +TestInstr(Or)('RCX', 'RBX') +TestInstr(Or)('RAX', 0x11223344) +TestInstr(Or)('RAX', mem('[RAX + 1]')) +TestInstr(Or)(mem('[RAX + 1]'), 'R8') +TestInstr(Or)(mem('[EAX + 1]'), 'R8') +TestInstr(Or)(mem('[RAX + 1]'), 'EAX') + + + TestInstr(Push)('R15') TestInstr(Push)(0x42) TestInstr(Push)(-1) @@ -128,11 +155,18 @@ assert Xchg('RAX', 'RCX').get_code() == Xchg('RCX', 'RAX').get_code() # 32 / 64 bits register mixing TestInstr(Mov)('ECX', 'EBX') TestInstr(Mov)('RCX', mem('[EBX]')) +TestInstr(Mov)('ECX', mem('[RBX]')) +TestInstr(Mov)('ECX', mem('[EBX]')) TestInstr(Mov)('RCX', mem('[EBX + EBX]')) TestInstr(Mov)('RCX', mem('[ESP + EBX + 0x10]')) TestInstr(Mov)('ECX', mem('[ESP + EBX + 0x10]')) TestInstr(Mov)('ECX', mem('[RBX + RCX + 0x10]')) +TestInstr(Mov)(mem('[RBX + RCX + 0x10]'), 'ECX') +TestInstr(Mov)(mem('[EBX + ECX + 0x10]'), 'ECX') +TestInstr(Mov)(mem('[EBX + ECX + 0x10]'), 'R8') + + TestInstr(Mov, must_fail=True)('RCX', 'ECX') TestInstr(Mov, must_fail=True)('RCX', mem('[ECX + RCX]')) TestInstr(Mov, must_fail=True)('RCX', mem('[RBX + ECX]')) diff --git a/native_exec/test_simple_x86.py b/native_exec/test_simple_x86.py index f80ddcc..33a0b3b 100644 --- a/native_exec/test_simple_x86.py +++ b/native_exec/test_simple_x86.py @@ -106,6 +106,11 @@ TestInstr(Mov)('AX', mem('fs:[EAX + 0x30]')) TestInstr(Mov)('AX', mem('fs:[EAX + ECX * 4+0x30]')) TestInstr(Add)('EAX', 8) TestInstr(Add)('EAX', 0xffffffff) + + +TestInstr(Sub)('ECX', 'ESP') +TestInstr(Sub)('ECX', mem('[ESP]')) + TestInstr(Inc)('EAX') TestInstr(Inc)(mem('[0x42424242]')) TestInstr(Lea)('EAX', mem('[EAX + 1]')) @@ -116,6 +121,18 @@ TestInstr(Cpuid)() TestInstr(Movsb, expected_result='movsb byte ptr es:[edi], byte ptr [esi]')() TestInstr(Movsd, expected_result='movsd dword ptr es:[edi], dword ptr [esi]')() TestInstr(Xchg)('EAX', 'ESP') + +TestInstr(And)('ECX', 'EBX') +TestInstr(And)('EAX', 0x11223344) +TestInstr(And)('EAX', mem('[EAX + 1]')) +TestInstr(And)(mem('[EAX + EAX]'), 'EDX') + +TestInstr(Or)('ECX', 'EBX') +TestInstr(Or)('EAX', 0x11223344) +TestInstr(Or)('EAX', mem('[EAX + 1]')) +TestInstr(Or)(mem('[EAX + EAX]'), 'EDX') + + assert Xchg('EAX', 'ECX').get_code() == Xchg('ECX', 'EAX').get_code() code = MultipleInstr()