From dfe82172599995507c23a4e02ea07be7c89f7509 Mon Sep 17 00:00:00 2001 From: Clement Rouault Date: Fri, 13 May 2016 16:31:07 +0200 Subject: [PATCH] Fix system.version_name on windows10 --- windows/native_exec/native_function.py | 22 +++++----------------- windows/native_exec/simple_x64.py | 12 +++++++++++- windows/syswow64.py | 2 ++ windows/winobject/system.py | 2 +- 4 files changed, 19 insertions(+), 19 deletions(-) diff --git a/windows/native_exec/native_function.py b/windows/native_exec/native_function.py index 57b9082..d1806fa 100644 --- a/windows/native_exec/native_function.py +++ b/windows/native_exec/native_function.py @@ -122,7 +122,7 @@ def analyse_callback(callback): # For windows 32 bits with stdcall def generate_stub_32(callback): - c_callback = get_callback_address_32(callback) + c_callback = ctypes.cast(callback, ctypes.c_void_p).value gstate_save_addr = x86.create_displacement(disp=allocator.reserve_int()) return_addr_save_addr = x86.create_displacement(disp=allocator.reserve_int()) @@ -179,7 +179,7 @@ def generate_stub_32(callback): def generate_stub_64(callback): - c_callback = get_callback_address_64(callback) + c_callback = ctypes.cast(callback, ctypes.c_void_p).value REG_LEN = ctypes.sizeof(ctypes.c_void_p) register_to_save = ("RBX", "RCX", "RDX", "RSI", "RDI", "R8", "R9", "R10", "R11", "R12", "R13", "R14", "R15") @@ -292,18 +292,6 @@ def create_function(code, types): """ func_type = ctypes.CFUNCTYPE(*types) addr = allocator.write_code(code) - return func_type(addr) - - -# Return First argument for 32 bits code -raw_code = x86.MultipleInstr() -raw_code += x86.Mov('EAX', x86.mem('[ESP + 4]')) -raw_code += x86.Ret() -get_callback_address_32 = create_function(raw_code.get_code(), [ctypes.c_void_p]) - - -# Return First argument for 64 bits code -raw_code = x64.MultipleInstr() -raw_code += x64.Mov('RAX', 'RCX') -raw_code += x64.Ret() -get_callback_address_64 = create_function(raw_code.get_code(), [ctypes.c_void_p]) + res = func_type(addr) + res.code_addr = addr + return res diff --git a/windows/native_exec/simple_x64.py b/windows/native_exec/simple_x64.py index e02333c..f7d47cc 100644 --- a/windows/native_exec/simple_x64.py +++ b/windows/native_exec/simple_x64.py @@ -2,6 +2,8 @@ import collections import struct +DEBUG = False + class BitArray(object): def __init__(self, size, bits): self.size = size @@ -114,6 +116,8 @@ registers_32_bits = {'R15D': 'R15', 'R14D': 'R14', 'ESP': 'RSP', 'R9D': 'R9', 'R13D': 'R13', 'EBP': 'RBP', 'R12D': 'R12', 'EDX': 'RDX', 'EBX': 'RBX', 'ESI': 'RSI', 'ECX': 'RCX'} +registers_64_to_32_bits = {r64:r32 for r32,r64 in registers_32_bits.items()} + x64_segment_selectors = {'CS': CSPrefix, 'DS': DSPrefix, 'ES': ESPrefix, 'SS': SSPrefix, 'FS': FSPrefix, 'GS': GSPrefix} @@ -289,6 +293,8 @@ class RawBits(BitArray): class ImmediatOverflow(ValueError): pass +# 8 / 16 /32 only accept signed value because of jmp +# Should I have signed / unsigned stuff ? (seems so..) def accept_as_8immediat(x): try: @@ -645,14 +651,18 @@ class Slash(object): def __init__(self, reg_num): "reg = 7 for /7" self.reg = reg_order[reg_num] + self.reg_num = reg_num def accept_arg(self, args, instr_state): if len(args) < 1: 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 + injected_reg = self.reg + if X64.is_32b_reg(args[0]): + injected_reg = registers_64_to_32_bits[injected_reg] 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) + arg_consum, value, rex = ModRM([ModRM_REG__REG, ModRM_REG64__MEM], has_direction_bit=False).accept_arg(args[:1] + [injected_reg] + args[1:], instr_state) except ValueError as e: # Size mismatch return None, None, None diff --git a/windows/syswow64.py b/windows/syswow64.py index 30ca21d..b28b0cb 100644 --- a/windows/syswow64.py +++ b/windows/syswow64.py @@ -18,6 +18,8 @@ CS_64bits = 0x33 def genere_return_32bits_stub(ret_addr): ret_32b = x64.MultipleInstr() + # Transform 64b return value to ULONG64 return value + # EDX:EAX ret_32b += x64.Mov("RDX", "RAX") ret_32b += x64.Shr("RDX", 32) ret_32b += x64.Mov('RCX', (CS_32bits << 32) + ret_addr) diff --git a/windows/winobject/system.py b/windows/winobject/system.py index ead9b9b..c96e63c 100644 --- a/windows/winobject/system.py +++ b/windows/winobject/system.py @@ -154,7 +154,7 @@ class System(object): version = self.version is_workstation = self.product_type == VER_NT_WORKSTATION if version == (10, 0): - return ["Windows Server 2016, ""Windows 10"][is_workstation] + return ["Windows Server 2016", "Windows 10"][is_workstation] elif version == (6, 3): return ["Windows Server 2012 R2", "Windows 8.1"][is_workstation] elif version == (6, 2):