internal static Process GetParentProcess(Process process) { int pid = process.Id; Process parentProc = null; IntPtr handleToSnapshot = IntPtr.Zero; try { NM.ProcessEntry32 procEntry = new NM.ProcessEntry32(); procEntry.dwSize = (uint)Marshal.SizeOf(typeof(NM.ProcessEntry32)); handleToSnapshot = NM.CreateToolhelp32Snapshot(NM.ToolHelpCreateSnapshotFlags.Process, 0); if (NM.Process32First(handleToSnapshot, ref procEntry)) { do { if (pid == procEntry.th32ProcessID) { parentProc = Process.GetProcessById((int)procEntry.th32ParentProcessID); break; } }while (NM.Process32Next(handleToSnapshot, ref procEntry)); } else { throw GUI.ApeException("Failed with win32 error code " + Marshal.GetLastWin32Error().ToString()); } } finally { NM.CloseHandle(handleToSnapshot); } return(parentProc); }
private static void Dispose() { // Close AckEvent if (m_AckEvent != IntPtr.Zero) { if (!NM.CloseHandle(m_AckEvent)) { throw CreateApplicationException("Failed to close handle for 'AckEvent'"); } m_AckEvent = IntPtr.Zero; } // Close ReadyEvent if (m_ReadyEvent != IntPtr.Zero) { if (!NM.CloseHandle(m_ReadyEvent)) { throw CreateApplicationException("Failed to close handle for 'ReadyEvent'"); } m_ReadyEvent = IntPtr.Zero; } // Close SharedFile if (m_SharedFile != IntPtr.Zero) { if (!NM.CloseHandle(m_SharedFile)) { throw CreateApplicationException("Failed to close handle for 'SharedFile'"); } m_SharedFile = IntPtr.Zero; } // Unmap SharedMem if (m_SharedMem != IntPtr.Zero) { if (!NM.UnmapViewOfFile(m_SharedMem)) { throw CreateApplicationException("Failed to unmap view for slot 'DBWIN_BUFFER'"); } m_SharedMem = IntPtr.Zero; } // Close our mutex if (m_Mutex != null) { m_Mutex.Close(); m_Mutex = null; } }
/// <summary> /// Injects the specified process with the specified assembly and calls the specified method /// </summary> /// <param name="processToInject">The process to inject the assembly into</param> /// <param name="apePid">The pid of the APE process to communicate with</param> /// <param name="assembly">The assembly to inject</param> /// <param name="method">The method in the assembly to call</param> /// <returns>The injection thread exit code</returns> public static uint Inject(Process processToInject, int apePid, string assembly, string method) { try { if (processToInject == null) { throw new Exception("Null process"); } if (processToInject.Id == Process.GetCurrentProcess().Id) { throw new Exception("Cannot inject the current process"); } IntPtr handleOfProcessToInject = NM.OpenProcess(NM.ProcessAccessFlags.QueryInformation | NM.ProcessAccessFlags.CreateThread | NM.ProcessAccessFlags.VMOperation | NM.ProcessAccessFlags.VMWrite | NM.ProcessAccessFlags.VMRead, false, processToInject.Id); if (handleOfProcessToInject == IntPtr.Zero) { throw new Win32Exception(Marshal.GetLastWin32Error()); } if (!File.Exists(assembly)) { throw new FileNotFoundException("Cannot find file " + assembly); } string absoluteAssemblyPath = Path.GetFullPath(assembly); string assemblyFilename = Path.GetFileName(absoluteAssemblyPath); IntPtr pAssemblyPathInThisProcess = Marshal.StringToHGlobalUni(absoluteAssemblyPath); IntPtr pAssemblyPathInRemoteProcess = IntPtr.Zero; IntPtr hRemoteThread = IntPtr.Zero; ProcessModule moduleInRemoteProcess = null; try { IntPtr hKernel32 = NM.GetModuleHandle("Kernel32"); if (hKernel32 == IntPtr.Zero) { throw new Win32Exception(Marshal.GetLastWin32Error()); } IntPtr hLoadLibrary = NM.GetProcAddress(hKernel32, "LoadLibraryW"); if (hLoadLibrary == IntPtr.Zero) { throw new Win32Exception(Marshal.GetLastWin32Error()); } uint sizeOfAssemblyPath = (uint)Encoding.Unicode.GetByteCount(absoluteAssemblyPath); // Allocate memory to the remote process for absoluteAssemblyPath pAssemblyPathInRemoteProcess = NM.VirtualAllocEx(handleOfProcessToInject, IntPtr.Zero, sizeOfAssemblyPath, NM.AllocationType.Commit, NM.MemoryProtection.ReadWrite); if (pAssemblyPathInRemoteProcess == IntPtr.Zero) { throw new Win32Exception(Marshal.GetLastWin32Error()); } // Write absoluteAssemblyPath to the remote process int bytesWritten; if (!NM.WriteProcessMemory(handleOfProcessToInject, pAssemblyPathInRemoteProcess, pAssemblyPathInThisProcess, sizeOfAssemblyPath, out bytesWritten)) { throw new Win32Exception(Marshal.GetLastWin32Error()); } // Load dll via call to LoadLibrary using CreateRemoteThread hRemoteThread = NM.CreateRemoteThread(handleOfProcessToInject, IntPtr.Zero, 0, hLoadLibrary, pAssemblyPathInRemoteProcess, 0, IntPtr.Zero); if (hRemoteThread == IntPtr.Zero) { throw new Win32Exception(Marshal.GetLastWin32Error()); } // Wait for the thread to exit if (NM.WaitForSingleObject(hRemoteThread, 30000) != NM.ThreadWaitValue.Object0) { throw new Win32Exception(Marshal.GetLastWin32Error()); } // Iterate modules in target process to find our newly injected module processToInject.Refresh(); foreach (ProcessModule module in processToInject.Modules) { if (module.ModuleName == assemblyFilename) { moduleInRemoteProcess = module; break; } } if (moduleInRemoteProcess == null) { throw new Exception("Could not find module in remote process!"); } } finally { // Tidy up Marshal.FreeHGlobal(pAssemblyPathInThisProcess); NM.CloseHandle(hRemoteThread); NM.VirtualFreeEx(handleOfProcessToInject, pAssemblyPathInRemoteProcess, 0, NM.AllocationType.Release); } IntPtr pFunc = FindExport(moduleInRemoteProcess, method); IntPtr parameter = new IntPtr(apePid); try { // Start a thread in the remote process calling the method and passing the APE pid as a parameter hRemoteThread = NM.CreateRemoteThread(handleOfProcessToInject, IntPtr.Zero, 0, pFunc, parameter, 0, IntPtr.Zero); if (hRemoteThread == IntPtr.Zero) { throw new Win32Exception(Marshal.GetLastWin32Error()); } // Wait for the thread to exit if (NM.WaitForSingleObject(hRemoteThread, 30000) != NM.ThreadWaitValue.Object0) { throw new Win32Exception(Marshal.GetLastWin32Error()); } uint exitCode; if (!NM.GetExitCodeThread(hRemoteThread, out exitCode)) { throw new Win32Exception(Marshal.GetLastWin32Error()); } return(exitCode); } finally { NM.CloseHandle(hRemoteThread); } } catch (Exception ex) { MessageBox.Show(ex.Message + "\r\n" + ex.StackTrace); return(1); } }