<s> import struct <EOL> import ctypes <EOL> import os <EOL> import windows <EOL> import windows . utils as utils <EOL> from . native_exec import simple_x86 as x86 <EOL> from . native_exec import simple_x64 as x64 <EOL> from windows . native_exec . nativeutils import GetProcAddress64 , GetProcAddress32 <EOL> from windows . dbgprint import dbgprint <EOL> def perform_manual_getproc_loadlib_32 ( target , dll_name ) : <EOL> dll = "<STR_LIT>" . encode ( "<STR_LIT>" ) <EOL> api = "<STR_LIT>" <EOL> dll_to_load = dll_name + "<STR_LIT:\x00>" <EOL> RemoteManualLoadLibray = x86 . MultipleInstr ( ) <EOL> code = RemoteManualLoadLibray <EOL> code += x86 . Mov ( "<STR_LIT>" , x86 . mem ( "<STR_LIT>" ) ) <EOL> code += x86 . Push ( x86 . mem ( "<STR_LIT>" ) ) <EOL> code += x86 . Push ( x86 . mem ( "<STR_LIT>" ) ) <EOL> code += x86 . Call ( "<STR_LIT>" ) <EOL> code += x86 . Push ( x86 . mem ( "<STR_LIT>" ) ) <EOL> code += x86 . Call ( "<STR_LIT>" ) <EOL> code += x86 . Pop ( "<STR_LIT>" ) <EOL> code += x86 . Pop ( "<STR_LIT>" ) <EOL> code += x86 . Ret ( ) <EOL> RemoteManualLoadLibray += GetProcAddress32 <EOL> with target . allocated_memory ( <NUM_LIT> ) as addr : <EOL> addr2 = addr + len ( dll ) <EOL> addr3 = addr2 + len ( api ) <EOL> addr4 = addr3 + len ( dll_to_load ) <EOL> target . write_memory ( addr , dll ) <EOL> target . write_memory ( addr2 , api ) <EOL> target . write_memory ( addr3 , dll_to_load ) <EOL> target . write_qword ( addr4 , addr ) <EOL> target . write_qword ( addr4 + <NUM_LIT:4> , addr2 ) <EOL> target . write_qword ( addr4 + <NUM_LIT> , addr3 ) <EOL> t = target . execute ( RemoteManualLoadLibray . get_code ( ) , addr4 ) <EOL> t . wait ( ) <EOL> return True <EOL> def perform_manual_getproc_loadlib_64 ( target , dll_name ) : <EOL> dll = "<STR_LIT>" . encode ( "<STR_LIT>" ) <EOL> api = "<STR_LIT>" <EOL> dll_to_load = dll_name + "<STR_LIT:\x00>" <EOL> RemoteManualLoadLibray = x64 . MultipleInstr ( ) <EOL> code = RemoteManualLoadLibray <EOL> code += x64 . Mov ( "<STR_LIT>" , "<STR_LIT>" ) <EOL> code += x64 . Mov ( "<STR_LIT>" , x64 . mem ( "<STR_LIT>" ) ) <EOL> code += x64 . Mov ( "<STR_LIT>" , x64 . mem ( "<STR_LIT>" ) ) <EOL> code += x64 . Call ( "<STR_LIT>" ) <EOL> code += x64 . Mov ( "<STR_LIT>" , x64 . mem ( "<STR_LIT>" ) ) <EOL> code += x64 . Push ( "<STR_LIT>" ) <EOL> code += x64 . Push ( "<STR_LIT>" ) <EOL> code += x64 . Push ( "<STR_LIT>" ) <EOL> code += x64 . Call ( "<STR_LIT>" ) <EOL> code += x64 . Pop ( "<STR_LIT>" ) <EOL> code += x64 . Pop ( "<STR_LIT>" ) <EOL> code += x64 . Pop ( "<STR_LIT>" ) <EOL> code += x64 . Ret ( ) <EOL> RemoteManualLoadLibray += GetProcAddress64 <EOL> with target . allocated_memory ( <NUM_LIT> ) as addr : <EOL> addr2 = addr + len ( dll ) <EOL> addr3 = addr2 + len ( api ) <EOL> addr4 = addr3 + len ( dll_to_load ) <EOL> target . write_memory ( addr , dll ) <EOL> target . write_memory ( addr2 , api ) <EOL> target . write_memory ( addr3 , dll_to_load ) <EOL> target . write_qword ( addr4 , addr ) <EOL> target . write_qword ( addr4 + <NUM_LIT:8> , addr2 ) <EOL> target . write_qword ( addr4 + <NUM_LIT> , addr3 ) <EOL> t = target . execute ( RemoteManualLoadLibray . get_code ( ) , addr4 ) <EOL> t . wait ( ) <EOL> return True <EOL> def load_dll_in_remote_process ( target , dll_name ) : <EOL> rpeb = target . peb <EOL> if rpeb . Ldr : <EOL> modules = rpeb . modules <EOL> if any ( mod . name == dll_name for mod in modules ) : <EOL> dbgprint ( "<STR_LIT>" , "<STR_LIT>" ) <EOL> return True <EOL> k32 = [ mod for mod in modules if mod . name . lower ( ) == "<STR_LIT>" ] <EOL> if k32 : <EOL> k32 = k32 [ <NUM_LIT:0> ] <EOL> try : <EOL> load_libraryA = k32 . pe . exports [ "<STR_LIT>" ] <EOL> except KeyError : <EOL> raise ValueError ( "<STR_LIT>" ) <EOL> with target . allocated_memory ( <NUM_LIT> ) as addr : <EOL> target . write_memory ( addr , dll_name + "<STR_LIT:\x00>" ) <EOL> t = target . create_thread ( load_libraryA , addr ) <EOL> t . wait ( ) <EOL> dbgprint ( "<STR_LIT>" , "<STR_LIT>" ) <EOL> return True <EOL> if target . bitness == <NUM_LIT:32> : <EOL> return perform_manual_getproc_loadlib_32 ( target , dll_name ) <EOL> return perform_manual_getproc_loadlib_64 ( target , dll_name ) <EOL> python_function_32_bits = { } <EOL> def generate_python_exec_shellcode_32 ( target , PYCODE_ADDR , PyDll ) : <EOL> if not python_function_32_bits : <EOL> pymodule = [ mod for mod in target . peb . modules if mod . name == PyDll ] [ <NUM_LIT:0> ] <EOL> Py_exports = pymodule . pe . exports <EOL> python_function_32_bits [ "<STR_LIT>" ] = Py_exports [ "<STR_LIT>" ] <EOL> python_function_32_bits [ "<STR_LIT>" ] = Py_exports [ "<STR_LIT>" ] <EOL> python_function_32_bits [ "<STR_LIT>" ] = Py_exports [ "<STR_LIT>" ] <EOL> python_function_32_bits [ "<STR_LIT>" ] = Py_exports [ "<STR_LIT>" ] <EOL> python_function_32_bits [ "<STR_LIT>" ] = Py_exports [ "<STR_LIT>" ] <EOL> python_function_32_bits [ "<STR_LIT>" ] = Py_exports [ "<STR_LIT>" ] <EOL> python_function_32_bits [ "<STR_LIT>" ] = Py_exports [ "<STR_LIT>" ] <EOL> Py_exports = python_function_32_bits <EOL> PyEval_InitThreads = Py_exports [ "<STR_LIT>" ] <EOL> Py_IsInitialized = Py_exports [ "<STR_LIT>" ] <EOL> PyGILState_Release = Py_exports [ "<STR_LIT>" ] <EOL> PyGILState_Ensure = Py_exports [ "<STR_LIT>" ] <EOL> PyEval_SaveThread = Py_exports [ "<STR_LIT>" ] <EOL> Py_Initialize = Py_exports [ "<STR_LIT>" ] <EOL> PyRun_SimpleString = Py_exports [ "<STR_LIT>" ] <EOL> code = x86 . MultipleInstr ( ) <EOL> code += x86 . Mov ( '<STR_LIT>' , Py_IsInitialized ) <EOL> code += x86 . Call ( '<STR_LIT>' ) <EOL> code += x86 . Mov ( "<STR_LIT>" , "<STR_LIT>" ) <EOL> code += x86 . Cmp ( "<STR_LIT>" , <NUM_LIT:0> ) <EOL> code += x86 . Jnz ( "<STR_LIT>" ) <EOL> code += x86 . Mov ( '<STR_LIT>' , PyEval_InitThreads ) <EOL> code += x86 . Call ( '<STR_LIT>' ) <EOL> code += x86 . Mov ( '<STR_LIT>' , Py_Initialize ) <EOL> code += x86 . Call ( '<STR_LIT>' ) <EOL> code += x86 . Label ( "<STR_LIT>" ) <EOL> code += x86 . Mov ( '<STR_LIT>' , PyGILState_Ensure ) <EOL> code += x86 . Call ( '<STR_LIT>' ) <EOL> code += x86 . Push ( '<STR_LIT>' ) <EOL> code += x86 . Push ( PYCODE_ADDR ) <EOL> code += x86 . Mov ( '<STR_LIT>' , PyRun_SimpleString ) <EOL> code += x86 . Call ( '<STR_LIT>' ) <EOL> code += x86 . Mov ( "<STR_LIT>" , "<STR_LIT>" ) <EOL> code += x86 . Mov ( '<STR_LIT>' , PyGILState_Release ) <EOL> code += x86 . Call ( '<STR_LIT>' ) <EOL> code += x86 . Pop ( '<STR_LIT>' ) <EOL> code += x86 . Cmp ( "<STR_LIT>" , <NUM_LIT:0> ) <EOL> code += x86 . Jnz ( "<STR_LIT>" ) <EOL> code += x86 . Mov ( '<STR_LIT>' , PyEval_SaveThread ) <EOL> code += x86 . Call ( '<STR_LIT>' ) <EOL> code += x86 . Label ( "<STR_LIT>" ) <EOL> code += x86 . Mov ( "<STR_LIT>" , "<STR_LIT>" ) <EOL> code += x86 . Pop ( "<STR_LIT>" ) <EOL> code += x86 . Ret ( ) <EOL> return code . get_code ( ) <EOL> python_function_64_bits = { } <EOL> def generate_python_exec_shellcode_64 ( target , PYCODE_ADDR , PyDll ) : <EOL> if not python_function_64_bits : <EOL> pymodule = [ mod for mod in target . peb . modules if mod . name == PyDll ] [ <NUM_LIT:0> ] <EOL> Py_exports = pymodule . pe . exports <EOL> python_function_64_bits [ "<STR_LIT>" ] = Py_exports [ "<STR_LIT>" ] <EOL> python_function_64_bits [ "<STR_LIT>" ] = Py_exports [ "<STR_LIT>" ] <EOL> python_function_64_bits [ "<STR_LIT>" ] = Py_exports [ "<STR_LIT>" ] <EOL> python_function_64_bits [ "<STR_LIT>" ] = Py_exports [ "<STR_LIT>" ] <EOL> python_function_64_bits [ "<STR_LIT>" ] = Py_exports [ "<STR_LIT>" ] <EOL> python_function_64_bits [ "<STR_LIT>" ] = Py_exports [ "<STR_LIT>" ] <EOL> python_function_64_bits [ "<STR_LIT>" ] = Py_exports [ "<STR_LIT>" ] <EOL> Py_exports = python_function_64_bits <EOL> PyEval_InitThreads = Py_exports [ "<STR_LIT>" ] <EOL> Py_IsInitialized = Py_exports [ "<STR_LIT>" ] <EOL> PyGILState_Release = Py_exports [ "<STR_LIT>" ] <EOL> PyGILState_Ensure = Py_exports [ "<STR_LIT>" ] <EOL> PyEval_SaveThread = Py_exports [ "<STR_LIT>" ] <EOL> Py_Initialize = Py_exports [ "<STR_LIT>" ] <EOL> PyRun_SimpleString = Py_exports [ "<STR_LIT>" ] <EOL> Reserve_space_for_call = x64 . MultipleInstr ( [ x64 . Push ( '<STR_LIT>' ) ] * <NUM_LIT:4> ) <EOL> Clean_space_for_call = x64 . MultipleInstr ( [ x64 . Pop ( '<STR_LIT>' ) ] * <NUM_LIT:4> ) <EOL> code = x64 . MultipleInstr ( ) <EOL> code += x64 . Push ( '<STR_LIT>' ) <EOL> code += Reserve_space_for_call <EOL> code += x64 . Mov ( '<STR_LIT>' , Py_IsInitialized ) <EOL> code += x64 . Call ( '<STR_LIT>' ) <EOL> code += x64 . Mov ( "<STR_LIT>" , "<STR_LIT>" ) <EOL> code += x64 . Cmp ( "<STR_LIT>" , <NUM_LIT:0> ) <EOL> code += x64 . Jnz ( "<STR_LIT>" ) <EOL> code += x64 . Mov ( '<STR_LIT>' , PyEval_InitThreads ) <EOL> code += x64 . Call ( '<STR_LIT>' ) <EOL> code += x64 . Mov ( '<STR_LIT>' , Py_Initialize ) <EOL> code += x64 . Call ( '<STR_LIT>' ) <EOL> code += x64 . Label ( "<STR_LIT>" ) <EOL> code += x64 . Mov ( '<STR_LIT>' , PyGILState_Ensure ) <EOL> code += x64 . Call ( '<STR_LIT>' ) <EOL> code += x64 . Mov ( '<STR_LIT>' , '<STR_LIT>' ) <EOL> code += x64 . Mov ( '<STR_LIT>' , PyRun_SimpleString ) <EOL> code += x64 . Mov ( '<STR_LIT>' , PYCODE_ADDR ) <EOL> code += x64 . Call ( '<STR_LIT>' ) <EOL> code += x64 . Mov ( '<STR_LIT>' , '<STR_LIT>' ) <EOL> code += x64 . Mov ( '<STR_LIT>' , '<STR_LIT>' ) <EOL> code += x64 . Mov ( '<STR_LIT>' , PyGILState_Release ) <EOL> code += x64 . Call ( '<STR_LIT>' ) <EOL> code += x64 . Cmp ( "<STR_LIT>" , <NUM_LIT:0> ) <EOL> code += x64 . Jnz ( "<STR_LIT>" ) <EOL> code += x64 . Mov ( '<STR_LIT>' , PyEval_SaveThread ) <EOL> code += x64 . Call ( '<STR_LIT>' ) <EOL> code += x64 . Label ( "<STR_LIT>" ) <EOL> code += Clean_space_for_call <EOL> code += x64 . Pop ( '<STR_LIT>' ) <EOL> code += x64 . Mov ( "<STR_LIT>" , "<STR_LIT>" ) <EOL> code += x64 . Ret ( ) <EOL> return code . get_code ( ) <EOL> def inject_python_command ( target , code_injected , PYDLL ) : <EOL> """<STR_LIT>""" <EOL> PYCODE = code_injected + "<STR_LIT:\x00>" <EOL> remote_addr = target . virtual_alloc ( len ( PYCODE ) + <NUM_LIT> ) <EOL> target . write_memory ( remote_addr , PYCODE ) <EOL> SHELLCODE_ADDR = remote_addr + len ( PYCODE ) <EOL> if target . bitness == <NUM_LIT:32> : <EOL> shellcode_generator = generate_python_exec_shellcode_32 <EOL> else : <EOL> shellcode_generator = generate_python_exec_shellcode_64 <EOL> shellcode = shellcode_generator ( target , remote_addr , PYDLL ) <EOL> target . write_memory ( SHELLCODE_ADDR , shellcode ) <EOL> return SHELLCODE_ADDR <EOL> def validate_python_dll_presence_on_disk ( process ) : <EOL> if windows . current_process . bitness == process . bitness : <EOL> return True <EOL> if windows . current_process . bitness == <NUM_LIT:32> and process . bitness == <NUM_LIT:64> : <EOL> with windows . utils . DisableWow64FsRedirection ( ) : <EOL> if not os . path . exists ( r"<STR_LIT>" ) : <EOL> raise ValueError ( "<STR_LIT>" ) <EOL> return True <EOL> if windows . current_process . bitness == <NUM_LIT:64> and process . bitness == <NUM_LIT:32> : <EOL> if not os . path . exists ( r"<STR_LIT>" ) : <EOL> raise ValueError ( "<STR_LIT>" ) <EOL> return True <EOL> raise NotImplementedError ( "<STR_LIT>" ) <EOL> def execute_python_code ( process , code ) : <EOL> validate_python_dll_presence_on_disk ( process ) <EOL> load_dll_in_remote_process ( process , "<STR_LIT>" ) <EOL> addr = inject_python_command ( process , code , "<STR_LIT>" ) <EOL> t = process . create_thread ( addr , <NUM_LIT:0> ) <EOL> return t <EOL> retrieve_exc = r"""<STR_LIT>""" <EOL> def retrieve_last_exception_data ( process ) : <EOL> with process . allocated_memory ( <NUM_LIT> ) as mem : <EOL> execute_python_code ( process , retrieve_exc . format ( mem ) ) <EOL> size = struct . unpack ( "<STR_LIT>" , process . read_memory ( mem , ctypes . sizeof ( ctypes . c_uint ) ) ) [ <NUM_LIT:0> ] <EOL> data = process . read_memory ( mem + ctypes . sizeof ( ctypes . c_uint ) , size ) <EOL> return data <EOL> class RemotePythonError ( Exception ) : <EOL> pass <EOL> def safe_execute_python ( process , code ) : <EOL> t = execute_python_code ( process , code ) <EOL> t . wait ( ) <EOL> if t . exit_code == <NUM_LIT:0> : <EOL> return True <EOL> if t . exit_code != <NUM_LIT> : <EOL> raise ValueError ( "<STR_LIT>" . format ( hex ( t . exit_code ) ) ) <EOL> data = retrieve_last_exception_data ( process ) <EOL> raise RemotePythonError ( data ) </s>
