private static bool TryStartRemoteDllThreadHelper(SafeProcessHandle hRemoteProcess, SafeRemoteBufferHandle hRemoteDllPathBuffer, out SafeRemoteThreadHandle hRemoteThreadOut) { var hProcessUnsafe = hRemoteProcess.DangerousGetHandle(); var pRemoteDllPath = hRemoteDllPathBuffer.DangerousGetHandle(); try { uint remoteThreadId; var hRemoteThread = WinAPI.CreateRemoteThread( hProcessUnsafe, IntPtr.Zero, 0, pLoadLibraryA, pRemoteDllPath, 0, out remoteThreadId ); if (hRemoteThread == IntPtr.Zero) { logger.Warn($"CreateRemoteThread failed with errno {Marshal.GetLastWin32Error()}."); hRemoteThreadOut = null; } else { hRemoteThreadOut = new SafeRemoteThreadHandle(hRemoteThread); } } catch (Win32Exception e) { var errno = Marshal.GetLastWin32Error(); logger.Warn("Win32Exception thrown when creating remote thread. Errno: " + errno + ".", e); hRemoteThreadOut = null; } return hRemoteThreadOut != null; }
public static SafeRemoteThreadHandle StartRemoteDllThreadOrThrow(SafeProcessHandle hRemoteProcess, SafeRemoteBufferHandle hRemoteDllPathBuffer, int attempts) { for (var i = 0; i < attempts; i++) { SafeRemoteThreadHandle result; if (TryStartRemoteDllThreadHelper(hRemoteProcess, hRemoteDllPathBuffer, out result)) { return result; } } throw new Exception( "Could not create remote thread after " + attempts + " attempts!\n" + "\r\nhProcess: " + hRemoteProcess.DangerousGetHandle() + "\r\nhRemoteDllPathBuffer: " + hRemoteDllPathBuffer.DangerousGetHandle() + "\r\npLoadLibraryA: " + pLoadLibraryA + "\r\nErrno: " + Marshal.GetLastWin32Error() ); }
public ProcessInjectionResult InjectToProcessOrThrow(int targetProcessId, string dllPath) { // Normalize dll path so it is properly loaded in target process dllPath = Path.GetFullPath(dllPath); logger.Info("Injecting into processId " + targetProcessId + " dll " + dllPath); using (var hProcess = SafeProcessHandle.OpenOrThrow(targetProcessId)) using (var hDllPathBuffer = SafeRemoteBufferHandle.AllocateOrThrow(hProcess, dllPath)) using (var hRemoteThread = SafeRemoteThreadHandle.StartRemoteDllThreadOrThrow(hProcess, hDllPathBuffer, 10)) { logger.Info("Our dll is running in a remote thread."); if (hRemoteThread.TryWaitForTermination(kDllCompletionTimeoutMilliseconds)) { return(ProcessInjectionResult.Success); } else { return(ProcessInjectionResult.DllFailed); } } }
private static bool TryStartRemoteDllThreadHelper(SafeProcessHandle hRemoteProcess, SafeRemoteBufferHandle hRemoteDllPathBuffer, out SafeRemoteThreadHandle hRemoteThreadOut) { var hProcessUnsafe = hRemoteProcess.DangerousGetHandle(); var pRemoteDllPath = hRemoteDllPathBuffer.DangerousGetHandle(); try { uint remoteThreadId; var hRemoteThread = WinAPI.CreateRemoteThread( hProcessUnsafe, IntPtr.Zero, 0, pLoadLibraryA, pRemoteDllPath, 0, out remoteThreadId ); if (hRemoteThread == IntPtr.Zero) { logger.Warn($"CreateRemoteThread failed with errno {Marshal.GetLastWin32Error()}."); hRemoteThreadOut = null; } else { hRemoteThreadOut = new SafeRemoteThreadHandle(hRemoteThread); } } catch (Win32Exception e) { var errno = Marshal.GetLastWin32Error(); logger.Warn("Win32Exception thrown when creating remote thread. Errno: " + errno + ".", e); hRemoteThreadOut = null; } return(hRemoteThreadOut != null); }
public static SafeRemoteThreadHandle StartRemoteDllThreadOrThrow(SafeProcessHandle hRemoteProcess, SafeRemoteBufferHandle hRemoteDllPathBuffer, int attempts) { for (var i = 0; i < attempts; i++) { SafeRemoteThreadHandle result; if (TryStartRemoteDllThreadHelper(hRemoteProcess, hRemoteDllPathBuffer, out result)) { return(result); } } throw new Exception( "Could not create remote thread after " + attempts + " attempts!\n" + "\r\nhProcess: " + hRemoteProcess.DangerousGetHandle() + "\r\nhRemoteDllPathBuffer: " + hRemoteDllPathBuffer.DangerousGetHandle() + "\r\npLoadLibraryA: " + pLoadLibraryA + "\r\nErrno: " + Marshal.GetLastWin32Error() ); }