Example #1
0
        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);
        }
Example #2
0
        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;
            }
        }
Example #3
0
        /// <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);
            }
        }