diff --git a/server/funq_server/runner_win.py b/server/funq_server/runner_win.py index 5a5bb83..fc6d9f8 100644 --- a/server/funq_server/runner_win.py +++ b/server/funq_server/runner_win.py @@ -33,7 +33,7 @@ # knowledge of the CeCILL v2.1 license and that you accept its terms. from funq_server.runner import RunnerInjector -from ctypes import windll, wintypes, byref +from ctypes import wintypes, byref import ctypes import time @@ -42,7 +42,7 @@ # # - https://docs.microsoft.com/en-us/windows/win32/dlls/dynamic-link-library-best-practices # noqa: E501 # - https://blog.nettitude.com/uk/dll-injection-part-two -# - https://stackoverflow.com/questions/17392721/error-invalid-parameter-error-57-when-calling-createremotethread-with-python-3-2/17524073#17524073 +# - https://stackoverflow.com/questions/17392721/error-invalid-parameter-error-57-when-calling-createremotethread-with-python-3-2/17524073#17524073 # noqa: E501 # - https://stackoverflow.com/questions/27332509/createremotethread-on-loadlibrary-and-get-the-hmodule-back # noqa: E501 # - https://github.com/numaru/injector @@ -66,7 +66,7 @@ def start_subprocess(self): # too early, it does not work 100% reliable (in rare cases, the # process freezes or crashes). When slightly delaying the injection, # it seems to work more reliable. One seconds seems to be a safe - # choice to also make it reliable if the system is very busy. # + # choice to also make it reliable if the system is very busy. # Hopefully someone finds a better way some day (without delay)... time.sleep(1.0) @@ -146,41 +146,40 @@ def _inject_dll(self, pid, dll_path): # Start the injection. size = (len(dll_path) + 1) * ctypes.sizeof(wintypes.WCHAR) - process_handle = None - path_address = None - thread_handle = None + h_process = None + adr_path = None + h_thread = None try: # Get handle to the running process. - process_handle = kernel32.OpenProcess( + h_process = kernel32.OpenProcess( PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION | PROCESS_VM_WRITE, False, pid) - if process_handle is None: - self._raise_windows_error("OpenProcess()", process_handle) + if h_process is None: + self._raise_windows_error("OpenProcess()", h_process) # Allocate memory for the DLL path. - path_address = kernel32.VirtualAllocEx( - process_handle, None, size, MEM_COMMIT | MEM_RESERVE, + adr_path = kernel32.VirtualAllocEx( + h_process, None, size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE) - if path_address is None: - self._raise_windows_error("VirtualAllocEx()", path_address) + if adr_path is None: + self._raise_windows_error("VirtualAllocEx()", adr_path) # Write DLL path into the allocated memory region. success = kernel32.WriteProcessMemory( - process_handle, path_address, dll_path, size, None) + h_process, adr_path, dll_path, size, None) if not success: self._raise_windows_error("WriteProcessMemory()", success) - # Create and start new thread in the process. The entry point of the - # new thread is LoadLibraryW() with our DLL path as argument. - thread_handle = kernel32.CreateRemoteThread( - process_handle, None, 0, kernel32.LoadLibraryW, path_address, - 0, None) - if thread_handle is None: - self._raise_windows_error("CreateRemoteThread()", thread_handle) + # Create and start new thread in the process. The entry point of + # the new thread is LoadLibraryW() with our DLL path as argument. + h_thread = kernel32.CreateRemoteThread( + h_process, None, 0, kernel32.LoadLibraryW, adr_path, 0, None) + if h_thread is None: + self._raise_windows_error("CreateRemoteThread()", h_thread) # Wait (with 10s timeout) until the thread exited, i.e. our DLL # injection either succeeded or failed. - error = kernel32.WaitForSingleObject(thread_handle, 10000) + error = kernel32.WaitForSingleObject(h_thread, 10000) if error: self._raise_windows_error("WaitForSingleObject()", error) @@ -189,25 +188,25 @@ def _inject_dll(self, pid, dll_path): # successfully or not. libfunq_handle = wintypes.DWORD(0) success = kernel32.GetExitCodeThread( - thread_handle, byref(libfunq_handle)) + h_thread, byref(libfunq_handle)) if not success: self._raise_windows_error("GetExitCodeThread()", success) if not libfunq_handle: self._raise_windows_error("LoadLibraryW()", libfunq_handle) finally: - if path_address is not None: - success = kernel32.VirtualFreeEx(process_handle, path_address, - 0, MEM_RELEASE) + if adr_path is not None: + success = kernel32.VirtualFreeEx(h_process, adr_path, 0, + MEM_RELEASE) if not success: self._raise_windows_error("VirtualFreeEx()", success) - if thread_handle is not None: - success = kernel32.CloseHandle(thread_handle) + if h_thread is not None: + success = kernel32.CloseHandle(h_thread) if not success: self._raise_windows_error("CloseHandle()", success) - if process_handle is not None: - success = kernel32.CloseHandle(process_handle) + if h_process is not None: + success = kernel32.CloseHandle(h_process) if not success: self._raise_windows_error("CloseHandle()", success)