import struct import ctypes import codecs import windows import windows.native_exec.simple_x64 as x64 from generated_def.winstructs import * # Special code for syswow64 process CS_32bits = 0x23 CS_64bits = 0x33 def genere_return_32bits_stub(ret_addr): ret_32b = x64.MultipleInstr() ret_32b += x64.Mov('RCX', (CS_32bits << 32) + ret_addr) ret_32b += x64.Push('RCX') ret_32b += x64.Retf32() # 32 bits return addr return ret_32b.get_code() # The format of a jump to 64bits mode dummy_jump = "\xea" + struct.pack("= 1: code_64b += x64.Mov('RCX', x64.create_displacement(disp=argument_buffer)) if nb_args >= 2: code_64b += x64.Mov('RDX', x64.create_displacement(disp=argument_buffer + (8 * 1))) if nb_args >= 3: code_64b += x64.Mov('R8', x64.create_displacement(disp=argument_buffer + (8 * 2))) if nb_args >= 4: code_64b += x64.Mov('R9', x64.create_displacement(disp=argument_buffer + (8 * 3))) for i in range(nb_args_on_stack): code_64b += x64.Mov('RAX', x64.create_displacement(disp=argument_buffer + 8 * (nb_args - 1 - i))) code_64b += x64.Push('RAX') # reserve space for register (calling convention) code_64b += x64.Push('R9') code_64b += x64.Push('R8') code_64b += x64.Push('RDX') code_64b += x64.Push('RCX') # Call code_64b += x64.Mov('R13', target_addr) code_64b += x64.Call('R13') # Clean stack code_64b += x64.Add('RSP', (4 + nb_args_on_stack) * 8) code_64b += x64.Pop('R13') code_64b += x64.Pop('R12') code_64b += x64.Pop('R11') code_64b += x64.Pop('R10') code_64b += x64.Pop('R9') code_64b += x64.Pop('R8') code_64b += x64.Pop('RDI') code_64b += x64.Pop('RSI') code_64b += x64.Pop('RDX') code_64b += x64.Pop('RCX') code_64b += x64.Pop('RBX') return try_generate_stub_target(code_64b.get_code(), argument_buffer, target) # TODO: this code should be a winfuct of type prototype :) def try_generate_stub_target(shellcode, argument_buffer, target): """shellcode must NOT end by a ret""" if not windows.current_process.is_wow_64: raise ValueError("Calling execute_64bits_code_from_syswow from non-syswow process") addr = windows.winproxy.VirtualAlloc(dwSize=0x1000) # post-exec 32bits stub (ret) ret = "\xC3" ret_addr = addr shell_code_addr = ret_addr + len(ret) + len(dummy_jump) # ljmp jump = "\xea" + struct.pack("