/// <summary> /// Injects a dll into a process by creating a remote thread on LoadLibrary. /// </summary> /// <param name="_hProcess">Handle to the process into which dll will be injected.</param> /// <param name="_szDllPath">Full path of the dll that will be injected.</param> /// <returns>Returns the base address of the injected dll on success, zero on failure.</returns> public static IntPtr InjectDllCreateThread(IntPtr _hProcess, string _szDllPath) { if (_hProcess == IntPtr.Zero) { throw new ArgumentNullException("_hProcess"); } if (_szDllPath.Length == 0) { throw new ArgumentNullException("_szDllPath"); } if (!_szDllPath.Contains("\\")) { _szDllPath = Path.GetFullPath(_szDllPath); } if (!File.Exists(_szDllPath)) { throw new ArgumentException("DLL not found.", "_szDllPath"); } var dwBaseAddress = IntPtr.Zero; IntPtr lpLoadLibrary; IntPtr lpDll; IntPtr hThread, threadId; var hKernel32 = OnyxNative.GetModuleHandle(_hProcess, "kernel32.dll"); lpLoadLibrary = (IntPtr)(hKernel32.ToInt64() + OnyxNative.GetExportedFunctionRVA(OnyxNative.GetModuleFileNameEx(_hProcess, hKernel32), "LoadLibraryW").ToInt64()); if (lpLoadLibrary != IntPtr.Zero) { lpDll = OnyxMemory.AllocateMemory(_hProcess); if (lpDll != IntPtr.Zero) { if (OnyxMemory.Write(_hProcess, lpDll, _szDllPath)) { //wait for thread handle to have signaled state hThread = OnyxNative.CreateRemoteThread( _hProcess, IntPtr.Zero, 0, lpLoadLibrary, lpDll, ThreadFlags.THREAD_EXECUTE_IMMEDIATELY, out threadId); //wait for thread handle to have signaled state //exit code will be equal to the base address of the dll if (OnyxNative.WaitForSingleObject(hThread, 5000) == WaitValues.WAIT_OBJECT_0) { OnyxNative.GetExitCodeThread(hThread, out dwBaseAddress); if (dwBaseAddress == IntPtr.Zero) { throw new Win32Exception(Marshal.GetLastWin32Error()); } } OnyxNative.CloseHandle(hThread); } OnyxMemory.FreeMemory(_hProcess, lpDll); } } return(dwBaseAddress); }