def native_to_win32_pathname(name): """ @type name: str @param name: Native (NT) absolute pathname. @rtype: str @return: Win32 absolute pathname. """ # XXX TODO # There are probably some native paths that # won't be converted by this naive approach. if name.startswith(compat.b("\\")): if name.startswith(compat.b("\\??\\")): name = name[4:] elif name.startswith(compat.b("\\SystemRoot\\")): system_root_path = os.environ['SYSTEMROOT'] if system_root_path.endswith('\\'): system_root_path = system_root_path[:-1] name = system_root_path + name[11:] else: for drive_number in compat.xrange(ord('A'), ord('Z') + 1): drive_letter = '%c:' % drive_number try: device_native_path = win32.QueryDosDevice(drive_letter) except WindowsError: e = sys.exc_info()[1] if e.winerror in (win32.ERROR_FILE_NOT_FOUND, \ win32.ERROR_PATH_NOT_FOUND): continue raise if not device_native_path.endswith(compat.b('\\')): device_native_path += compat.b('\\') if name.startswith(device_native_path): name = drive_letter + compat.b('\\') + \ name[ len(device_native_path) : ] break return name
def native_to_win32_pathname(name): """ @type name: str @param name: Native (NT) absolute pathname. @rtype: str @return: Win32 absolute pathname. """ # XXX TODO # There are probably some native paths that # won't be converted by this naive approach. if name.startswith(compat.b("\\")): if name.startswith(compat.b("\\??\\")): name = name[4:] elif name.startswith(compat.b("\\SystemRoot\\")): system_root_path = os.environ['SYSTEMROOT'] if system_root_path.endswith('\\'): system_root_path = system_root_path[:-1] name = system_root_path + name[11:] else: for drive_number in compat.xrange(ord('A'), ord('Z') + 1): drive_letter = '%c:' % drive_number try: device_native_path = win32.QueryDosDevice(drive_letter) except WindowsError: e = sys.exc_info()[1] if e.winerror in (win32.ERROR_FILE_NOT_FOUND, \ win32.ERROR_PATH_NOT_FOUND): continue raise if not device_native_path.endswith(compat.b('\\')): device_native_path += compat.b('\\') if name.startswith(device_native_path): name = drive_letter + compat.b('\\') + \ name[ len(device_native_path) : ] break return name
def __init__(self, is_64): from winappdbg import compat self.is_64 = is_64 self._code = [] if not is_64: self._translations = { 'push esi': compat.b('\x56'), 'push eax': compat.b('\x50'), 'push ebp': compat.b('\x55'), 'push ebx': compat.b('\x53'), 'pop esi': compat.b('\x5E'), 'pop eax': compat.b('\x58'), 'pop ebp': compat.b('\x5D'), 'pop ebx': compat.b('\x5B'), 'mov esi': compat.b('\xBE'), 'mov eax': compat.b('\xB8'), 'mov ebp': compat.b('\xBD'), 'mov ebx': compat.b('\xBB'), 'call ebp': compat.b('\xFF\xD5'), 'call eax': compat.b('\xFF\xD0'), 'call ebx': compat.b('\xFF\xD3'), 'mov ebx,eax': compat.b('\x89\xC3'), 'mov eax,ebx': compat.b('\x89\xD8'), 'mov ebp,esp': compat.b('\x89\xE5'), 'mov esp,ebp': compat.b('\x89\xEC'), 'push dword': compat.b('\x68'), 'mov ebp,eax': compat.b('\x89\xC5'), 'mov eax,ebp': compat.b('\x89\xE8'), 'ret': compat.b('\xc3'), } else: # Translate 64 bits self._translations = { 'push rsi': compat.b('\x56'), 'push rax': compat.b('\x50'), 'push rbp': compat.b('\x55'), 'push rbx': compat.b('\x53'), 'push rsp': compat.b('\x54'), 'push rdi': compat.b('\x57'), 'pop rsi': compat.b('\x5E'), 'pop rax': compat.b('\x58'), 'pop rbp': compat.b('\x5D'), 'pop rbx': compat.b('\x5B'), 'pop rsp': compat.b('\x5C'), 'pop rdi': compat.b('\x5F'), 'mov rsi': compat.b('\x48\xBE'), 'mov rax': compat.b('\x48\xB8'), 'mov rbp': compat.b('\x48\xBD'), 'mov rbx': compat.b('\x48\xBB'), 'mov rdi': compat.b('\x48\xBF'), 'mov rcx': compat.b('\x48\xB9'), 'mov rdx': compat.b('\x48\xBA'), 'call rbp': compat.b('\xFF\xD5'), 'call rax': compat.b('\xFF\xD0'), 'call rbx': compat.b('\xFF\xD3'), 'mov rbx,rax': compat.b('\x48\x89\xC3'), 'mov rax,rbx': compat.b('\x48\x89\xD8'), 'mov rbp,rsp': compat.b('\x48\x89\xE5'), 'mov rsp,rbp': compat.b('\x48\x89\xEC'), 'mov rcx,rbp': compat.b('\x48\x89\xE9'), 'mov rbp,rax': compat.b('\x48\x89\xC5'), 'mov rax,rbp': compat.b('\x48\x89\xE8'), 'mov rdi,rbp': compat.b('\x48\x89\xEF'), 'ret': compat.b('\xc3'), }
def run_python_code_windows(pid, python_code, connect_debugger_tracing=False, show_debug_info=0): assert '\'' not in python_code, 'Having a single quote messes with our command.' from winappdbg import compat from winappdbg.process import Process if not isinstance(python_code, compat.bytes): python_code = compat.b(python_code) process = Process(pid) bits = process.get_bits() is_64 = bits == 64 if is_64 != is_python_64bit(): raise RuntimeError( "The architecture of the Python used to connect doesn't match the architecture of the target.\n" "Target 64 bits: %s\n" "Current Python 64 bits: %s" % (is_64, is_python_64bit())) print('Connecting to %s bits target' % (bits, )) assert resolve_label(process, compat.b('PyGILState_Ensure')) filedir = os.path.dirname(__file__) if is_64: suffix = 'amd64' else: suffix = 'x86' target_dll = os.path.join(filedir, 'attach_%s.dll' % suffix) if not os.path.exists(target_dll): raise RuntimeError('Could not find dll file to inject: %s' % target_dll) print('Injecting dll') process.inject_dll(target_dll.encode('mbcs')) print('Dll injected') process.scan_modules() attach_func = resolve_label(process, compat.b('AttachAndRunPythonCode')) assert attach_func print('Allocating code in target process') code_address = process.malloc(len(python_code)) assert code_address print('Writing code in target process') process.write(code_address, python_code) print('Allocating return value memory in target process') return_code_address = process.malloc(ctypes.sizeof(ctypes.c_int)) assert return_code_address CONNECT_DEBUGGER = 2 startup_info = 0 if show_debug_info: SHOW_DEBUG_INFO = 1 startup_info |= SHOW_DEBUG_INFO # Uncomment to show debug info if connect_debugger_tracing: startup_info |= CONNECT_DEBUGGER process.write_int(return_code_address, startup_info) helper = GenShellCodeHelper(is_64) if is_64: # Interesting read: http://msdn.microsoft.com/en-us/library/ms235286.aspx # Overview of x64 Calling Conventions (for windows: Linux is different!) # Register Usage: http://msdn.microsoft.com/en-us/library/9z1stfyw.aspx # The registers RAX, RCX, RDX, R8, R9, R10, R11 are considered volatile and must be considered destroyed on function calls (unless otherwise safety-provable by analysis such as whole program optimization). # # The registers RBX, RBP, RDI, RSI, RSP, R12, R13, R14, and R15 are considered nonvolatile and must be saved and restored by a function that uses them. # # Important: RCX: first int argument with helper.push('rdi'): # This one REALLY must be pushed/poped with helper.push('rsp'): with helper.push('rbp'): with helper.push('rbx'): with helper.push('rdi'): # Note: pop is automatic. helper.mov_to_register_addr( 'rcx', helper.pack_address(code_address)) helper.mov_to_register_addr( 'rdx', helper.pack_address(return_code_address)) helper.mov_to_register_addr( 'rbx', helper.pack_address(attach_func)) helper.call('rbx') else: with helper.push('eax'): # Note: pop is automatic. with helper.push('ebp'): with helper.push('ebx'): with helper.preserve_stack(): # Put our code as a parameter in the stack (on x86, we push parameters to # the stack) helper.push_addr( helper.pack_address(return_code_address)) helper.push_addr(helper.pack_address(code_address)) helper.mov_to_register_addr( 'ebx', helper.pack_address(attach_func)) helper.call('ebx') helper.ret() code = helper.get_code() # Uncomment to see the disassembled version of what we just did... # with open('f.asm', 'wb') as stream: # stream.write(code) # # exe = r'x:\nasm\nasm-2.07-win32\nasm-2.07\ndisasm.exe' # if is_64: # arch = '64' # else: # arch = '32' # # subprocess.call((exe + ' -b %s f.asm' % arch).split()) print('Injecting code to target process') thread, _thread_address = process.inject_code(code, 0) timeout = None # Could receive timeout in millis. print('Waiting for code to complete') thread.wait(timeout) return_code = process.read_int(return_code_address) if return_code == 0: print('Attach finished successfully.') else: print( 'Error when injecting code in target process. Error code: %s (on windows)' % (return_code, )) process.free(thread.pInjectedMemory) process.free(code_address) process.free(return_code_address) return return_code
def get_code(self): from winappdbg import compat return compat.b('').join(self._code)
def run_python_code_windows(pid, python_code, connect_debugger_tracing=False, show_debug_info=0): assert '\'' not in python_code, 'Having a single quote messes with our command.' from winappdbg import compat from winappdbg.process import Process if not isinstance(python_code, compat.bytes): python_code = compat.b(python_code) process = Process(pid) bits = process.get_bits() is_64 = bits == 64 if is_64 != is_python_64bit(): raise RuntimeError("The architecture of the Python used to connect doesn't match the architecture of the target.\n" "Target 64 bits: %s\n" "Current Python 64 bits: %s" % (is_64, is_python_64bit())) debug('Connecting to %s bits target' % (bits,)) assert resolve_label(process, compat.b('PyGILState_Ensure')) filedir = os.path.dirname(__file__) if is_64: suffix = 'amd64' else: suffix = 'x86' target_dll = os.path.join(filedir, 'attach_%s.dll' % suffix) if not os.path.exists(target_dll): raise RuntimeError('Could not find dll file to inject: %s' % target_dll) debug('Injecting dll') process.inject_dll(target_dll.encode('mbcs')) debug('Dll injected') process.scan_modules() attach_func = resolve_label(process, compat.b('AttachAndRunPythonCode')) assert attach_func debug('Allocating code in target process') code_address = process.malloc(len(python_code)) assert code_address debug('Writing code in target process') process.write(code_address, python_code) debug('Allocating return value memory in target process') return_code_address = process.malloc(ctypes.sizeof(ctypes.c_int)) assert return_code_address CONNECT_DEBUGGER = 2 startup_info = 0 if show_debug_info: SHOW_DEBUG_INFO = 1 startup_info |= SHOW_DEBUG_INFO # Uncomment to show debug info if connect_debugger_tracing: startup_info |= CONNECT_DEBUGGER process.write_int(return_code_address, startup_info) helper = GenShellCodeHelper(is_64) if is_64: # Interesting read: http://msdn.microsoft.com/en-us/library/ms235286.aspx # Overview of x64 Calling Conventions (for windows: Linux is different!) # Register Usage: http://msdn.microsoft.com/en-us/library/9z1stfyw.aspx # The registers RAX, RCX, RDX, R8, R9, R10, R11 are considered volatile and must be considered destroyed on function calls (unless otherwise safety-provable by analysis such as whole program optimization). # # The registers RBX, RBP, RDI, RSI, RSP, R12, R13, R14, and R15 are considered nonvolatile and must be saved and restored by a function that uses them. # # Important: RCX: first int argument with helper.push('rdi'): # This one REALLY must be pushed/poped with helper.push('rsp'): with helper.push('rbp'): with helper.push('rbx'): with helper.push('rdi'): # Note: pop is automatic. helper.mov_to_register_addr('rcx', helper.pack_address(code_address)) helper.mov_to_register_addr('rdx', helper.pack_address(return_code_address)) helper.mov_to_register_addr('rbx', helper.pack_address(attach_func)) helper.call('rbx') else: with helper.push('eax'): # Note: pop is automatic. with helper.push('ebp'): with helper.push('ebx'): with helper.preserve_stack(): # Put our code as a parameter in the stack (on x86, we push parameters to # the stack) helper.push_addr(helper.pack_address(return_code_address)) helper.push_addr(helper.pack_address(code_address)) helper.mov_to_register_addr('ebx', helper.pack_address(attach_func)) helper.call('ebx') helper.ret() code = helper.get_code() # Uncomment to see the disassembled version of what we just did... # with open('f.asm', 'wb') as stream: # stream.write(code) # # exe = r'x:\nasm\nasm-2.07-win32\nasm-2.07\ndisasm.exe' # if is_64: # arch = '64' # else: # arch = '32' # # subprocess.call((exe + ' -b %s f.asm' % arch).split()) debug('Injecting code to target process') thread, _thread_address = process.inject_code(code, 0) timeout = None # Could receive timeout in millis. debug('Waiting for code to complete') thread.wait(timeout) return_code = process.read_int(return_code_address) if return_code == 0: print('Attach finished successfully.') else: print('Error when injecting code in target process. Error code: %s (on windows)' % (return_code,)) process.free(thread.pInjectedMemory) process.free(code_address) process.free(return_code_address) return return_code
def get_code(self): from winappdbg import compat return compat.b('').join(self._code)
def __init__(self, is_64): from winappdbg import compat self.is_64 = is_64 self._code = [] if not is_64: self._translations = { 'push esi': compat.b('\x56'), 'push eax': compat.b('\x50'), 'push ebp': compat.b('\x55'), 'push ebx': compat.b('\x53'), 'pop esi': compat.b('\x5E'), 'pop eax': compat.b('\x58'), 'pop ebp': compat.b('\x5D'), 'pop ebx': compat.b('\x5B'), 'mov esi': compat.b('\xBE'), 'mov eax': compat.b('\xB8'), 'mov ebp': compat.b('\xBD'), 'mov ebx': compat.b('\xBB'), 'call ebp': compat.b('\xFF\xD5'), 'call eax': compat.b('\xFF\xD0'), 'call ebx': compat.b('\xFF\xD3'), 'mov ebx,eax': compat.b('\x89\xC3'), 'mov eax,ebx': compat.b('\x89\xD8'), 'mov ebp,esp': compat.b('\x89\xE5'), 'mov esp,ebp': compat.b('\x89\xEC'), 'push dword': compat.b('\x68'), 'mov ebp,eax': compat.b('\x89\xC5'), 'mov eax,ebp': compat.b('\x89\xE8'), 'ret': compat.b('\xc3'), } else: # Translate 64 bits self._translations = { 'push rsi': compat.b('\x56'), 'push rax': compat.b('\x50'), 'push rbp': compat.b('\x55'), 'push rbx': compat.b('\x53'), 'push rsp': compat.b('\x54'), 'push rdi': compat.b('\x57'), 'pop rsi': compat.b('\x5E'), 'pop rax': compat.b('\x58'), 'pop rbp': compat.b('\x5D'), 'pop rbx': compat.b('\x5B'), 'pop rsp': compat.b('\x5C'), 'pop rdi': compat.b('\x5F'), 'mov rsi': compat.b('\x48\xBE'), 'mov rax': compat.b('\x48\xB8'), 'mov rbp': compat.b('\x48\xBD'), 'mov rbx': compat.b('\x48\xBB'), 'mov rdi': compat.b('\x48\xBF'), 'mov rcx': compat.b('\x48\xB9'), 'mov rdx': compat.b('\x48\xBA'), 'call rbp': compat.b('\xFF\xD5'), 'call rax': compat.b('\xFF\xD0'), 'call rbx': compat.b('\xFF\xD3'), 'mov rbx,rax': compat.b('\x48\x89\xC3'), 'mov rax,rbx': compat.b('\x48\x89\xD8'), 'mov rbp,rsp': compat.b('\x48\x89\xE5'), 'mov rsp,rbp': compat.b('\x48\x89\xEC'), 'mov rcx,rbp': compat.b('\x48\x89\xE9'), 'mov rbp,rax': compat.b('\x48\x89\xC5'), 'mov rax,rbp': compat.b('\x48\x89\xE8'), 'mov rdi,rbp': compat.b('\x48\x89\xEF'), 'ret': compat.b('\xc3'), }
def __init__(self, is_64): from winappdbg import compat self.is_64 = is_64 self._code = [] if not is_64: self._translations = { "push esi": compat.b("\x56"), "push eax": compat.b("\x50"), "push ebp": compat.b("\x55"), "push ebx": compat.b("\x53"), "pop esi": compat.b("\x5E"), "pop eax": compat.b("\x58"), "pop ebp": compat.b("\x5D"), "pop ebx": compat.b("\x5B"), "mov esi": compat.b("\xBE"), "mov eax": compat.b("\xB8"), "mov ebp": compat.b("\xBD"), "mov ebx": compat.b("\xBB"), "call ebp": compat.b("\xFF\xD5"), "call eax": compat.b("\xFF\xD0"), "call ebx": compat.b("\xFF\xD3"), "mov ebx,eax": compat.b("\x89\xC3"), "mov eax,ebx": compat.b("\x89\xD8"), "mov ebp,esp": compat.b("\x89\xE5"), "mov esp,ebp": compat.b("\x89\xEC"), "push dword": compat.b("\x68"), "mov ebp,eax": compat.b("\x89\xC5"), "mov eax,ebp": compat.b("\x89\xE8"), "ret": compat.b("\xc3"), } else: # Translate 64 bits self._translations = { "push rsi": compat.b("\x56"), "push rax": compat.b("\x50"), "push rbp": compat.b("\x55"), "push rbx": compat.b("\x53"), "push rsp": compat.b("\x54"), "push rdi": compat.b("\x57"), "pop rsi": compat.b("\x5E"), "pop rax": compat.b("\x58"), "pop rbp": compat.b("\x5D"), "pop rbx": compat.b("\x5B"), "pop rsp": compat.b("\x5C"), "pop rdi": compat.b("\x5F"), "mov rsi": compat.b("\x48\xBE"), "mov rax": compat.b("\x48\xB8"), "mov rbp": compat.b("\x48\xBD"), "mov rbx": compat.b("\x48\xBB"), "mov rdi": compat.b("\x48\xBF"), "mov rcx": compat.b("\x48\xB9"), "mov rdx": compat.b("\x48\xBA"), "call rbp": compat.b("\xFF\xD5"), "call rax": compat.b("\xFF\xD0"), "call rbx": compat.b("\xFF\xD3"), "mov rbx,rax": compat.b("\x48\x89\xC3"), "mov rax,rbx": compat.b("\x48\x89\xD8"), "mov rbp,rsp": compat.b("\x48\x89\xE5"), "mov rsp,rbp": compat.b("\x48\x89\xEC"), "mov rcx,rbp": compat.b("\x48\x89\xE9"), "mov rbp,rax": compat.b("\x48\x89\xC5"), "mov rax,rbp": compat.b("\x48\x89\xE8"), "mov rdi,rbp": compat.b("\x48\x89\xEF"), "ret": compat.b("\xc3"), }
def run_python_code_windows(pid, python_code, connect_debugger_tracing=False, show_debug_info=0): assert '\'' not in python_code, 'Having a single quote messes with our command.' from winappdbg import compat from winappdbg.process import Process if not isinstance(python_code, compat.bytes): python_code = compat.b(python_code) process = Process(pid) bits = process.get_bits() is_64 = bits == 64 if is_64 != is_python_64bit(): raise RuntimeError( "The architecture of the Python used to connect doesn't match the architecture of the target.\n" "Target 64 bits: %s\n" "Current Python 64 bits: %s" % (is_64, is_python_64bit())) print('Connecting to %s bits target' % (bits, )) assert resolve_label(process, compat.b('PyGILState_Ensure')) filedir = os.path.dirname(__file__) if is_64: suffix = 'amd64' else: suffix = 'x86' target_dll = os.path.join(filedir, 'attach_%s.dll' % suffix) if not os.path.exists(target_dll): raise RuntimeError('Could not find dll file to inject: %s' % target_dll) print('Injecting dll') process.inject_dll(target_dll.encode('mbcs')) print('Dll injected') process.scan_modules() attach_func = resolve_label(process, compat.b('AttachAndRunPythonCode')) assert attach_func print('Allocating code in target process') code_address = process.malloc(len(python_code)) assert code_address print('Writing code in target process') process.write(code_address, python_code) print('Allocating return value memory in target process') attach_info_address = process.malloc(ctypes.sizeof(ctypes.c_int)) assert attach_info_address CONNECT_DEBUGGER = 2 attach_info = 0 if show_debug_info: SHOW_DEBUG_INFO = 1 attach_info |= SHOW_DEBUG_INFO # Uncomment to show debug info if connect_debugger_tracing: attach_info |= CONNECT_DEBUGGER # Note: previously the attach_info address was treated as read/write to have the return # value, but it seems that sometimes when the program wrote back the memory became # unreadable with the stack trace below when trying to read, so, we just write and # no longer inspect the return value. # i.e.: # Traceback (most recent call last): # File "X:\pydev\plugins\org.python.pydev.core\pysrc\pydevd_attach_to_process\attach_pydevd.py", line 72, in <module> # main(process_command_line(sys.argv[1:])) # File "X:\pydev\plugins\org.python.pydev.core\pysrc\pydevd_attach_to_process\attach_pydevd.py", line 68, in main # setup['pid'], python_code, connect_debugger_tracing=True, show_debug_info=show_debug_info_on_target_process) # File "X:\pydev\plugins\org.python.pydev.core\pysrc\pydevd_attach_to_process\add_code_to_python_process.py", line 392, in run_python_code_windows # return_code = process.read_int(return_code_address) # File "X:\pydev\plugins\org.python.pydev.core\pysrc\pydevd_attach_to_process\winappdbg\process.py", line 1673, in read_int # return self.__read_c_type(lpBaseAddress, compat.b('@l'), ctypes.c_int) # File "X:\pydev\plugins\org.python.pydev.core\pysrc\pydevd_attach_to_process\winappdbg\process.py", line 1568, in __read_c_type # packed = self.read(address, size) # File "X:\pydev\plugins\org.python.pydev.core\pysrc\pydevd_attach_to_process\winappdbg\process.py", line 1598, in read # if not self.is_buffer(lpBaseAddress, nSize): # File "X:\pydev\plugins\org.python.pydev.core\pysrc\pydevd_attach_to_process\winappdbg\process.py", line 2843, in is_buffer # mbi = self.mquery(address) # File "X:\pydev\plugins\org.python.pydev.core\pysrc\pydevd_attach_to_process\winappdbg\process.py", line 2533, in mquery # return win32.VirtualQueryEx(hProcess, lpAddress) # File "X:\pydev\plugins\org.python.pydev.core\pysrc\pydevd_attach_to_process\winappdbg\win32\kernel32.py", line 3742, in VirtualQueryEx # raise ctypes.WinError() # PermissionError: [WinError 5] Access is denied. # Process finished with exitValue: 1 process.write_int(attach_info_address, attach_info) helper = GenShellCodeHelper(is_64) if is_64: # Interesting read: http://msdn.microsoft.com/en-us/library/ms235286.aspx # Overview of x64 Calling Conventions (for windows: Linux is different!) # Register Usage: http://msdn.microsoft.com/en-us/library/9z1stfyw.aspx # The registers RAX, RCX, RDX, R8, R9, R10, R11 are considered volatile and must be considered destroyed on function calls (unless otherwise safety-provable by analysis such as whole program optimization). # # The registers RBX, RBP, RDI, RSI, RSP, R12, R13, R14, and R15 are considered nonvolatile and must be saved and restored by a function that uses them. # # Important: RCX: first int argument with helper.push('rdi'): # This one REALLY must be pushed/poped with helper.push('rsp'): with helper.push('rbp'): with helper.push('rbx'): with helper.push('rdi'): # Note: pop is automatic. helper.mov_to_register_addr( 'rcx', helper.pack_address(code_address)) helper.mov_to_register_addr( 'rdx', helper.pack_address(attach_info_address)) helper.mov_to_register_addr( 'rbx', helper.pack_address(attach_func)) helper.call('rbx') else: with helper.push('eax'): # Note: pop is automatic. with helper.push('ebp'): with helper.push('ebx'): with helper.preserve_stack(): # Put our code as a parameter in the stack (on x86, we push parameters to # the stack) helper.push_addr( helper.pack_address(attach_info_address)) helper.push_addr(helper.pack_address(code_address)) helper.mov_to_register_addr( 'ebx', helper.pack_address(attach_func)) helper.call('ebx') helper.ret() code = helper.get_code() # Uncomment to see the disassembled version of what we just did... # with open('f.asm', 'wb') as stream: # stream.write(code) # # exe = r'x:\nasm\nasm-2.07-win32\nasm-2.07\ndisasm.exe' # if is_64: # arch = '64' # else: # arch = '32' # # subprocess.call((exe + ' -b %s f.asm' % arch).split()) print('Injecting code to target process') thread, _thread_address = process.inject_code(code, 0) timeout = None # Could receive timeout in millis. print('Waiting for code to complete') thread.wait(timeout) # return_code = process.read_int(attach_info_address) # if return_code == 0: # print('Attach finished successfully.') # else: # print('Error when injecting code in target process. Error code: %s (on windows)' % (return_code,)) process.free(thread.pInjectedMemory) process.free(code_address) process.free(attach_info_address) return 0