diff --git a/windows/native_exec/simple_x64.py b/windows/native_exec/simple_x64.py index a034ba1..556b2c5 100644 --- a/windows/native_exec/simple_x64.py +++ b/windows/native_exec/simple_x64.py @@ -651,7 +651,11 @@ class Slash(object): raise ValueError("Missing arg for Slash") # Reuse all the MODRm logique with the reg as our self.reg # The sens of param is strange I need to fix the `reversed` logique - arg_consum, value, rex = ModRM([ModRM_REG__REG, ModRM_REG64__MEM], has_direction_bit=False).accept_arg(args[:1] + [self.reg] + args[1:], instr_state) + try: + arg_consum, value, rex = ModRM([ModRM_REG__REG, ModRM_REG64__MEM], has_direction_bit=False).accept_arg(args[:1] + [self.reg] + args[1:], instr_state) + except ValueError as e: + # Size mismatch + return None, None, None if value is None: return arg_consum, value, rex return arg_consum - 1, value, rex @@ -855,7 +859,9 @@ class Lea(Instruction): class Mov(Instruction): default_32_bits = True - encoding = [(Mov_RAX_OFF64(),), (Mov_OFF64_RAX(),), (RawBits.from_int(8, 0x89), ModRM([ModRM_REG__REG, ModRM_REG64__MEM])), + encoding = [(Mov_RAX_OFF64(),), (Mov_OFF64_RAX(),), + (RawBits.from_int(8, 0xc7), Slash(0), Imm32()), + (RawBits.from_int(8, 0x89), ModRM([ModRM_REG__REG, ModRM_REG64__MEM])), (RawBits.from_int(5, 0xb8 >> 3), X64RegisterSelector(), Imm64())] diff --git a/windows/native_exec/simple_x86.py b/windows/native_exec/simple_x86.py index 7aaccbf..c6eada9 100644 --- a/windows/native_exec/simple_x86.py +++ b/windows/native_exec/simple_x86.py @@ -483,6 +483,8 @@ class ControlRegisterModRM(object): return None, None reg = args[writecr] cr = args[not writecr] + if not isinstance(cr, str): + return None, None if not cr.lower().startswith("cr"): return None, None try: @@ -646,6 +648,7 @@ class Sub(Instruction): class Mov(Instruction): encoding = [(RawBits.from_int(8, 0x89), ModRM([ModRM_REG__REG, ModRM_REG__MEM])), + (RawBits.from_int(8, 0xc7), Slash(0), Imm32()), (RawBits.from_int(5, 0xb8 >> 3), X86RegisterSelector(), Imm32()), (RawBits.from_int(16, 0x0f20), ControlRegisterModRM(writecr=False)), (RawBits.from_int(16, 0x0f22), ControlRegisterModRM(writecr=True))] @@ -747,7 +750,7 @@ class MultipleInstr(object): def get_code(self): if self.expected_labels: - raise ValueError("Unresolved labels: {self.expected_labels}".format(self=self)) + raise ValueError("Unresolved labels: {0}".format(self.expected_labels.keys())) return b"".join([x[1].get_code() for x in sorted(self.instrs.items())]) def add_instruction(self, instruction): @@ -871,6 +874,38 @@ class MultipleInstr(object): self.add_instruction(other) return self + +def split_in_instruction(str): + for line in str.split("\n"): + if not line: + continue + for instr in line.split(";"): + if not instr: + continue + yield instr.strip() + +def assemble(str): + """Play test""" + shellcode = MultipleInstr() + for instr in split_in_instruction(str): + data = instr.split(" ", 1) + mnemo, args_raw = data[0], data[1:] + try: + instr_object = globals()[mnemo.capitalize()] + except: + raise ValueError("Unknow mnemonic <{0}>".format(mnemo)) + + args = [] + if args_raw: + for arg in args_raw[0].split(","): + arg = arg.strip() + if (arg[0] == "[" or arg[2:4] == ":[") and arg[-1] == "]": + print("MEM") + arg = mem(arg) + args.append(arg) + shellcode += instr_object(*args) + return shellcode.get_code() + # IDA : import windows.native_exec.simple_x86 as x86 # IDA testing diff --git a/windows/native_exec/test_simple_x64.py b/windows/native_exec/test_simple_x64.py index f0c618f..bf02d6b 100644 --- a/windows/native_exec/test_simple_x64.py +++ b/windows/native_exec/test_simple_x64.py @@ -126,6 +126,8 @@ TestInstr(Mov)('R8', 0x1122334455667788) TestInstr(Mov)('RCX', -1) TestInstr(Mov, immediat_accepted=-1)('RCX', 0xffffffffffffffff) TestInstr(Mov)(mem('gs:[0x1122334455667788]'), 'RAX') +TestInstr(Mov)(mem('[RAX]'), 0x11223344) +TestInstr(Mov)(mem('[EAX]'), 0x11223344) TestInstr(And)('RCX', 'RBX') TestInstr(And)('RAX', 0x11223344) diff --git a/windows/native_exec/test_simple_x86.py b/windows/native_exec/test_simple_x86.py index 33a0b3b..fbf02e7 100644 --- a/windows/native_exec/test_simple_x86.py +++ b/windows/native_exec/test_simple_x86.py @@ -10,11 +10,15 @@ def disas(x): class TestInstr(object): - def __init__(self, instr_to_test, expected_result=None): + def __init__(self, instr_to_test, expected_result=None, debug=False): self.instr_to_test = instr_to_test self.expected_result = expected_result + self.debug = debug def __call__(self, *args): + if self.debug: + import pdb;pdb.set_trace() + pdb.DONE = True res = bytes(self.instr_to_test(*args).get_code()) capres_list = disas(res) if len(capres_list) != 1: @@ -107,6 +111,10 @@ TestInstr(Mov)('AX', mem('fs:[EAX + ECX * 4+0x30]')) TestInstr(Add)('EAX', 8) TestInstr(Add)('EAX', 0xffffffff) +TestInstr(Add)(mem('[EAX]'), 10) +TestInstr(Mov)('EAX', mem('fs:[0xfffc]')) +TestInstr(Mov)(mem('fs:[0xfffc]'), 0) + TestInstr(Sub)('ECX', 'ESP') TestInstr(Sub)('ECX', mem('[ESP]'))