internal static bool Inject(advancedfx.injector.interop.InjectMessage injectMessage, IFormatter formatter, Stream stdIn, Stream stdOut) { string baseDirectory = System.IO.Path.GetDirectoryName(injectMessage.DllPath); byte[] datDllPath = Encoding.Unicode.GetBytes(injectMessage.DllPath + "\0"); byte[] datBaseDirectory = Encoding.Unicode.GetBytes(baseDirectory + "\0"); byte[] image = null; IntPtr argDllDir = IntPtr.Zero; IntPtr argDllFilePath = IntPtr.Zero; UIntPtr dllDirectorySz = new UIntPtr((ulong)datBaseDirectory.LongLength); UIntPtr dllFilePathSz = new UIntPtr((ulong)datDllPath.LongLength); UIntPtr imageSz = UIntPtr.Zero; IntPtr hProc = IntPtr.Zero; IntPtr hThread = IntPtr.Zero; IntPtr imageAfxHook = IntPtr.Zero; bool bOk = true; try { bOk = true; if (bOk && IntPtr.Zero == (hProc = OpenProcess(createThreadAccess, false, injectMessage.ProcessId))) { bOk = false; advancedfx.injector.interop.OpenProcessError e = new advancedfx.injector.interop.OpenProcessError(); e.GetLastError = Marshal.GetLastWin32Error(); formatter.Serialize(stdOut, e); } if (bOk && IntPtr.Zero == (argDllDir = VirtualAllocEx(hProc, IntPtr.Zero, dllDirectorySz, AllocationType.Reserve | AllocationType.Commit, MemoryProtection.ReadWrite))) { bOk = false; advancedfx.injector.interop.VirtualAllocExArgDllDirError e = new advancedfx.injector.interop.VirtualAllocExArgDllDirError(); e.GetLastError = Marshal.GetLastWin32Error(); formatter.Serialize(stdOut, e); } if (bOk && IntPtr.Zero == (argDllFilePath = VirtualAllocEx(hProc, IntPtr.Zero, dllFilePathSz, AllocationType.Reserve | AllocationType.Commit, MemoryProtection.ReadWrite))) { bOk = false; advancedfx.injector.interop.VirtualAllocExArgDllFilePathError e = new advancedfx.injector.interop.VirtualAllocExArgDllFilePathError(); e.GetLastError = Marshal.GetLastWin32Error(); formatter.Serialize(stdOut, e); } if (bOk && null == (image = GetImage(m_PGetModuleHandleW, m_PGetProcAddress, argDllDir, argDllFilePath))) { bOk = false; advancedfx.injector.interop.GetImageError e = new advancedfx.injector.interop.GetImageError(); formatter.Serialize(stdOut, e); } if (bOk) { imageSz = new UIntPtr((ulong)image.LongLength); if (bOk && IntPtr.Zero == (imageAfxHook = VirtualAllocEx(hProc, IntPtr.Zero, imageSz, AllocationType.Reserve | AllocationType.Commit, MemoryProtection.ExecuteReadWrite))) { bOk = false; advancedfx.injector.interop.VirtualAllocExImageError e = new advancedfx.injector.interop.VirtualAllocExImageError(); e.GetLastError = Marshal.GetLastWin32Error(); formatter.Serialize(stdOut, e); } if (bOk && !WriteProcessMemory(hProc, argDllDir, datBaseDirectory, dllDirectorySz, IntPtr.Zero)) { bOk = false; advancedfx.injector.interop.WriteProcessMemoryArgDllDirError e = new advancedfx.injector.interop.WriteProcessMemoryArgDllDirError(); e.GetLastError = Marshal.GetLastWin32Error(); formatter.Serialize(stdOut, e); } if (bOk && !WriteProcessMemory(hProc, argDllFilePath, datDllPath, dllFilePathSz, IntPtr.Zero)) { bOk = false; advancedfx.injector.interop.WriteProcessMemoryArgDllFilePathError e = new advancedfx.injector.interop.WriteProcessMemoryArgDllFilePathError(); e.GetLastError = Marshal.GetLastWin32Error(); formatter.Serialize(stdOut, e); } if (bOk && !WriteProcessMemory(hProc, imageAfxHook, image, imageSz, IntPtr.Zero)) { bOk = false; advancedfx.injector.interop.WriteProcessMemoryImageError e = new advancedfx.injector.interop.WriteProcessMemoryImageError(); e.GetLastError = Marshal.GetLastWin32Error(); formatter.Serialize(stdOut, e); } if (bOk && !FlushInstructionCache(hProc, imageAfxHook, imageSz)) { bOk = false; advancedfx.injector.interop.FlushInstructionCacheError e = new advancedfx.injector.interop.FlushInstructionCacheError(); e.GetLastError = Marshal.GetLastWin32Error(); formatter.Serialize(stdOut, e); } if (bOk && IntPtr.Zero == (hThread = CreateRemoteThread(hProc, IntPtr.Zero, UIntPtr.Zero, imageAfxHook, IntPtr.Zero, 0, IntPtr.Zero))) { bOk = false; advancedfx.injector.interop.CreateRemoteThreadError e = new advancedfx.injector.interop.CreateRemoteThreadError(); e.GetLastError = Marshal.GetLastWin32Error(); formatter.Serialize(stdOut, e); } if (bOk) { bOk = false; bool bWait; do { bWait = false; for (int i = 0; i < 60; i++) { if (WAIT_OBJECT_0 == WaitForSingleObject(hThread, 1000)) { bOk = true; break; } } if (!bOk) { advancedfx.injector.interop.ContinueWaitingQuestion e = new advancedfx.injector.interop.ContinueWaitingQuestion(); formatter.Serialize(stdOut, e); stdOut.Flush(); advancedfx.injector.interop.ContinueWaiting r = (advancedfx.injector.interop.ContinueWaiting)formatter.Deserialize(stdIn); bWait = r.Response; } } while (bWait); if (!bOk) { TerminateThread(hThread, 1); } else { if (!GetExitCodeThread(hThread, out UInt32 exitCode)) { bOk = false; advancedfx.injector.interop.GetExitCodeThreadError e = new advancedfx.injector.interop.GetExitCodeThreadError(); e.GetLastError = Marshal.GetLastWin32Error(); formatter.Serialize(stdOut, e); } if (bOk) { if (0 != exitCode) { bOk = false; if (1 <= exitCode && exitCode <= 15) { advancedfx.injector.interop.KnownExitCodeError e = new advancedfx.injector.interop.KnownExitCodeError(); e.ThreadExitCode = exitCode; formatter.Serialize(stdOut, e); } else { advancedfx.injector.interop.InvalidExitCodeError e = new advancedfx.injector.interop.InvalidExitCodeError(); formatter.Serialize(stdOut, e); } } } } } } } finally { if (IntPtr.Zero != hThread) { if (!CloseHandle(hThread)) { bOk = false; advancedfx.injector.interop.CloseHandleThreadError e = new advancedfx.injector.interop.CloseHandleThreadError(); e.GetLastError = Marshal.GetLastWin32Error(); formatter.Serialize(stdOut, e); } } if (IntPtr.Zero != imageAfxHook) { if (!VirtualFreeEx(hProc, imageAfxHook, UIntPtr.Zero, AllocationType.Release)) { bOk = false; advancedfx.injector.interop.VirtualFreeExImageError e = new advancedfx.injector.interop.VirtualFreeExImageError(); e.GetLastError = Marshal.GetLastWin32Error(); formatter.Serialize(stdOut, e); } } if (IntPtr.Zero != argDllFilePath) { if (!VirtualFreeEx(hProc, argDllFilePath, UIntPtr.Zero, AllocationType.Release)) { bOk = false; advancedfx.injector.interop.VirtualFreeExArgFilePathError e = new advancedfx.injector.interop.VirtualFreeExArgFilePathError(); e.GetLastError = Marshal.GetLastWin32Error(); formatter.Serialize(stdOut, e); } } if (IntPtr.Zero != argDllDir) { if (!VirtualFreeEx(hProc, argDllDir, UIntPtr.Zero, AllocationType.Release)) { bOk = false; advancedfx.injector.interop.VirtualFreeExArgDllDirError e = new advancedfx.injector.interop.VirtualFreeExArgDllDirError(); e.GetLastError = Marshal.GetLastWin32Error(); formatter.Serialize(stdOut, e); } } if (IntPtr.Zero != hProc) { if (!CloseHandle(hProc)) { bOk = false; advancedfx.injector.interop.CloseHandleThreadError e = new advancedfx.injector.interop.CloseHandleThreadError(); e.GetLastError = Marshal.GetLastWin32Error(); formatter.Serialize(stdOut, e); } } } return(bOk); }
public static bool Load(IEnumerable <GetHookPathDelegate> getHookPathCollection, string programPath, string cmdLine, string environment = null, bool showErrorMessage = true) { try { string programOptions = "\"" + programPath + "\" " + cmdLine; string programDirectory = System.IO.Path.GetDirectoryName(programPath); PROCESS_INFORMATION processInfo = new PROCESS_INFORMATION(); STARTUPINFOW startupInfo = new STARTUPINFOW(); startupInfo.cb = (UInt32)Marshal.SizeOf(startupInfo); if (!CreateProcessW( programPath , programOptions , null , null , true // inherit handles , //CREATE_DEFAULT_ERROR_MODE| CREATE_NEW_PROCESS_GROUP | DETACHED_PROCESS | CREATE_SUSPENDED //DEBUG_ONLY_THIS_PROCESS| //DEBUG_PROCESS // we want to catch debug event's (sadly also of childs) | CREATE_UNICODE_ENVIRONMENT , environment , programDirectory , ref startupInfo , out processInfo) ) { throw HlaeErrors.LoaderCreateProcessException(Marshal.GetLastWin32Error()); } try { bool isProcess64Bit = IsProcess64Bit(processInfo.hProcess); foreach (GetHookPathDelegate getHookPath in getHookPathCollection) { string hookPath = getHookPath(isProcess64Bit); using (System.Diagnostics.Process injector = new System.Diagnostics.Process()) { injector.StartInfo.UseShellExecute = false; injector.StartInfo.FileName = System.AppDomain.CurrentDomain.BaseDirectory + (isProcess64Bit ? "\\x64" : "") + "\\injector.exe"; injector.StartInfo.CreateNoWindow = true; injector.StartInfo.RedirectStandardInput = true; injector.StartInfo.RedirectStandardOutput = true; try { injector.Start(); } catch (Exception e) { throw HlaeErrors.InjectorStartException( injector.StartInfo.FileName, e ); } AfxError error = null; IFormatter formatter = new advancedfx.injector.interop.Formatter(); using (Stream injectorIn = injector.StandardInput.BaseStream) { using (Stream injectorOut = injector.StandardOutput.BaseStream) { advancedfx.injector.interop.InjectMessage injectMessage = new advancedfx.injector.interop.InjectMessage(); injectMessage.ProcessId = processInfo.dwProcessId; injectMessage.DllPath = hookPath; formatter.Serialize(injectorIn, injectMessage); injectorIn.Flush(); bool injectorExit = false; while (!injectorExit) { advancedfx.injector.interop.ProcessMessage m = (advancedfx.injector.interop.ProcessMessage)formatter.Deserialize(injectorOut); switch (m) { case advancedfx.injector.interop.ExceptionError exceptionError: if (null == error) { error = HlaeErrors.Unknown; } break; case advancedfx.injector.interop.OpenProcessError openProcessError: if (null == error) { error = HlaeErrors.OpenProcessFailed; } break; case advancedfx.injector.interop.VirtualAllocExArgDllDirError virtualAllocExArgDllDirError: if (null == error) { error = HlaeErrors.VirtualAllocExReadWriteFailed; } break; case advancedfx.injector.interop.VirtualAllocExArgDllFilePathError virtualAllocExArgDllFilePathError: if (null == error) { error = HlaeErrors.VirtualAllocExReadWriteFailed; } break; case advancedfx.injector.interop.GetImageError getImageError: if (null == error) { error = HlaeErrors.GetImageFailed; } break; case advancedfx.injector.interop.VirtualAllocExImageError virtualAllocExImageError: if (null == error) { error = HlaeErrors.VirtualAllocExReadWriteExecuteFailed; } break; case advancedfx.injector.interop.WriteProcessMemoryArgDllDirError writeProcessMemoryArgDllDirError: if (null == error) { error = HlaeErrors.WriteProcessMemoryFailed; } break; case advancedfx.injector.interop.WriteProcessMemoryArgDllFilePathError writeProcessMemoryArgDllFilePathError: if (null == error) { error = HlaeErrors.WriteProcessMemoryFailed; } break; case advancedfx.injector.interop.WriteProcessMemoryImageError writeProcessMemoryImageError: if (null == error) { error = HlaeErrors.WriteProcessMemoryFailed; } break; case advancedfx.injector.interop.FlushInstructionCacheError flushInstructionCacheError: if (null == error) { error = HlaeErrors.FlushInstructionCacheFailed; } break; case advancedfx.injector.interop.CreateRemoteThreadError createRemoteThreadError: if (null == error) { error = HlaeErrors.CreateRemoteThreadFailed; } break; case advancedfx.injector.interop.ContinueWaitingQuestion contineWaitingQuestion: { advancedfx.injector.interop.ContinueWaiting r = new advancedfx.injector.interop.ContinueWaiting(); r.Response = DialogResult.Yes == MessageBox.Show(L10n._("Image injection problem.\nContinue waiting?"), L10n._("injector Warning"), MessageBoxButtons.YesNo, MessageBoxIcon.Warning); formatter.Serialize(injectorIn, r); injectorIn.Flush(); } break; case advancedfx.injector.interop.TerminateThreadError terminateThreadError: // ignore for now break; case advancedfx.injector.interop.GetExitCodeThreadError getExitCodeThreadError: // ignore for now break; case advancedfx.injector.interop.InvalidExitCodeError invalidExitCodeError: if (null == error) { error = InjectorErrors.AfxHookUnknown; } break; case advancedfx.injector.interop.KnownExitCodeError knownExitCodeError: if (null == error) { error = InjectorErrors.Instance.GetById((int)knownExitCodeError.ThreadExitCode); } break; case advancedfx.injector.interop.CloseHandleThreadError closeHandleError: // ignore for now break; case advancedfx.injector.interop.VirtualFreeExImageError virtualFreeExImageError: // ignore for now break; case advancedfx.injector.interop.VirtualFreeExArgFilePathError virtualFreeExArgFilePathError: // ignore for now break; case advancedfx.injector.interop.VirtualFreeExArgDllDirError virtualFreeExArgDllDirError: // ignore for now break; case advancedfx.injector.interop.CloseHandleProcessError closeHandleProcessError: // ignore for now break; case advancedfx.injector.interop.InjectResponse injectResponse: bool injectorOk = injectResponse.Response; injector.WaitForExit(); if (!injectorOk) { throw null == error ? HlaeErrors.Unknown : error; } injectorExit = true; break; default: throw HlaeErrors.Unknown; } } } } } } } finally { System.Threading.Thread.Sleep(2000); ResumeThread(processInfo.hThread); CloseHandle(processInfo.hThread); CloseHandle(processInfo.hProcess); } } catch (AfxError e) { if (showErrorMessage) { using (ErrorDialogue frm = new ErrorDialogue()) { frm.Error = e; frm.ShowDialog(); } } return(false); } catch (Exception e) { if (showErrorMessage) { using (ErrorDialogue frm = new ErrorDialogue()) { frm.Error = HlaeErrors.LoaderException(e); frm.ShowDialog(); } } return(false); } return(true); }