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); }
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 SafeRemoteBufferHandle AllocateOrThrow(SafeProcessHandle hProcessSafe, string text) { var hProcessUnsafe = hProcessSafe.DangerousGetHandle(); logger.Info($"Allocating remote string buffer for text {text}."); uint szText = (uint)(text.Length + 1); // +1 for null string terminator IntPtr pRemoteStringBuffer = WinAPI.VirtualAllocEx( hProcessUnsafe, IntPtr.Zero, szText, AllocationType.Commit, MemoryProtection.ExecuteReadWrite ); if (pRemoteStringBuffer == IntPtr.Zero) { throw new Exception( "Could not allocate memory inside target process!\r\n" + "\r\nDll Path: " + text + " (size " + szText + ")" + "\r\nErrno: " + Marshal.GetLastWin32Error() ); } logger.Info("Write string in remote process"); int bytesWritten; bool writeSuccessful = WinAPI.WriteProcessMemory( hProcessUnsafe, pRemoteStringBuffer, Encoding.ASCII.GetBytes(text), szText, out bytesWritten ); if (!writeSuccessful) { throw new Exception( "Call to WriteProcessMemory failed! \n" + "\nDll Path: " + text + " (size " + szText + ")" + "\nBytes Written: " + bytesWritten + "\nErrno: " + Marshal.GetLastWin32Error() ); } else if (bytesWritten != szText) { throw new Exception( "WriteProcessMemory did not write expected byte count! \n" + "\nDll Path: " + text + " (size " + szText + ")" + "\nBytes Written: " + bytesWritten + "\nErrno: " + Marshal.GetLastWin32Error() ); } return(new SafeRemoteBufferHandle(hProcessUnsafe, pRemoteStringBuffer)); }
public static SafeRemoteBufferHandle AllocateOrThrow(SafeProcessHandle hProcessSafe, string text) { var hProcessUnsafe = hProcessSafe.DangerousGetHandle(); logger.Info($"Allocating remote string buffer for text {text}."); uint szText = (uint)(text.Length + 1); // +1 for null string terminator IntPtr pRemoteStringBuffer = WinAPI.VirtualAllocEx( hProcessUnsafe, IntPtr.Zero, szText, AllocationType.Commit, MemoryProtection.ExecuteReadWrite ); if (pRemoteStringBuffer == IntPtr.Zero) { throw new Exception( "Could not allocate memory inside target process!\r\n" + "\r\nDll Path: " + text + " (size " + szText + ")" + "\r\nErrno: " + Marshal.GetLastWin32Error() ); } logger.Info("Write string in remote process"); int bytesWritten; bool writeSuccessful = WinAPI.WriteProcessMemory( hProcessUnsafe, pRemoteStringBuffer, Encoding.ASCII.GetBytes(text), szText, out bytesWritten ); if (!writeSuccessful) { throw new Exception( "Call to WriteProcessMemory failed! \n" + "\nDll Path: " + text + " (size " + szText + ")" + "\nBytes Written: " + bytesWritten + "\nErrno: " + Marshal.GetLastWin32Error() ); } else if (bytesWritten != szText) { throw new Exception( "WriteProcessMemory did not write expected byte count! \n" + "\nDll Path: " + text + " (size " + szText + ")" + "\nBytes Written: " + bytesWritten + "\nErrno: " + Marshal.GetLastWin32Error() ); } return new SafeRemoteBufferHandle(hProcessUnsafe, pRemoteStringBuffer); }
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 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() ); }