public static Process CreateProcessWithFlags(this ProcessStartInfo startInfo, ProcessCreationFlags creationFlags)
        {
            if (string.IsNullOrEmpty(startInfo.FileName))
            {
                throw new ArgumentException("No FileName was specified in ProcessStartInfo", "startInfo");
            }
            if (!File.Exists(startInfo.FileName))
            {
                throw new FileNotFoundException("Unable to find the specified the process file", startInfo.FileName);
            }

            var startupInfo = new STARTUPINFO();

            startupInfo.cb = Marshal.SizeOf(startupInfo);

            var args             = string.IsNullOrEmpty(startInfo.Arguments) ? null : new StringBuilder(startInfo.Arguments);
            var workingDirectory = string.IsNullOrEmpty(startInfo.WorkingDirectory) ? null : startInfo.WorkingDirectory;

            var procInfo = new PROCESS_INFORMATION();

            if (!Imports.CreateProcess(startInfo.FileName, args, IntPtr.Zero, IntPtr.Zero, false, creationFlags, IntPtr.Zero, workingDirectory, ref startupInfo, out procInfo))
            {
                throw new Win32Exception(Marshal.GetLastWin32Error());
            }

            var ret = Process.GetProcessById(procInfo.dwProcessId);

            ProcessMemoryManager.ForProcess(ret).MainThreadId = procInfo.dwThreadId;
            return(ret);
        }
        public void Eject()
        {
            var manager = ProcessMemoryManager.ForProcess(_parentProcess);

            if (!manager.InjectedModules.ContainsKey(ModuleName))
            {
                throw new Exception("The injected module does not appear to be associated to its parent process. This could indicate corrupted process state");
            }

            var hThread = IntPtr.Zero;

            try
            {
                var hKernel32 = Imports.GetModuleHandle("Kernel32");
                if (hKernel32 == IntPtr.Zero)
                {
                    throw new Win32Exception(Marshal.GetLastWin32Error());
                }

                var hFreeLib = Imports.GetProcAddress(hKernel32, "FreeLibrary");
                if (hFreeLib == IntPtr.Zero)
                {
                    throw new Win32Exception(Marshal.GetLastWin32Error());
                }

                hThread = Imports.CreateRemoteThread(_parentProcess.GetHandle(), IntPtr.Zero, 0, hFreeLib, BaseAddress, 0, IntPtr.Zero);
                if (hThread == IntPtr.Zero)
                {
                    throw new Win32Exception(Marshal.GetLastWin32Error());
                }
                if (Imports.WaitForSingleObject(hThread, (uint)ThreadWaitValue.Infinite) != (uint)ThreadWaitValue.Object0)
                {
                    throw new Win32Exception(Marshal.GetLastWin32Error());
                }

                IntPtr pFreeLibRet;
                if (!Imports.GetExitCodeThread(hThread, out pFreeLibRet))
                {
                    throw new Win32Exception(Marshal.GetLastWin32Error());
                }

                if (pFreeLibRet == IntPtr.Zero)
                {
                    throw new Exception("FreeLibrary failed in remote process");
                }
            }
            finally
            {
                if (hThread != IntPtr.Zero)
                {
                    Imports.CloseHandle(hThread);
                }
            }
        }
Beispiel #3
0
        public static InjectedModule GetInjectedModule(this Process proc, string moduleName)
        {
            var            modules = ProcessMemoryManager.ForProcess(proc).InjectedModules;
            InjectedModule module;

            if (modules.TryGetValue(moduleName, out module))
            {
                return(module);
            }
            //throw new ArgumentException("Invalid module name", "moduleName");
            return(null);
        }
Beispiel #4
0
        public static void Resume(this Process proc)
        {
            var hThread = IntPtr.Zero;

            try
            {
                hThread = Imports.OpenThread(ThreadAccessFlags.AllAccess, false,
                                             ProcessMemoryManager.ForProcess(proc).MainThreadId);
                if (hThread == IntPtr.Zero)
                {
                    throw new Win32Exception(Marshal.GetLastWin32Error());
                }

                var hr = Imports.ResumeThread(hThread);
                Marshal.ThrowExceptionForHR(hr);
            }
            finally
            {
                if (hThread != IntPtr.Zero)
                {
                    Imports.CloseHandle(hThread);
                }
            }
        }
Beispiel #5
0
 public static IntPtr GetHandle(this Process proc)
 {
     return(ProcessMemoryManager.ForProcess(proc).Handle);
 }
Beispiel #6
0
        public static InjectedModule InjectLibrary(this Process proc, string modulePath, string moduleName = null)
        {
            if (!File.Exists(modulePath))
            {
                throw new FileNotFoundException("Unable to find the specified module", modulePath);
            }
            modulePath = Path.GetFullPath(modulePath);
            if (string.IsNullOrEmpty(moduleName))
            {
                moduleName = Path.GetFileName(modulePath) ?? modulePath;
            }

            var manager = ProcessMemoryManager.ForProcess(proc);

            if (manager.InjectedModules.ContainsKey(moduleName))
            {
                throw new ArgumentException("Module with this name has already been injected", "moduleName");
            }

            // unmanaged resources that need to be freed
            var pLibRemote   = IntPtr.Zero;
            var hThread      = IntPtr.Zero;
            var pLibFullPath = Marshal.StringToHGlobalUni(modulePath);

            try
            {
                var sizeUni = Encoding.Unicode.GetByteCount(modulePath);

                // Handle to Kernel32.dll and LoadLibraryW
                var hKernel32 = Imports.GetModuleHandle("Kernel32");
                if (hKernel32 == IntPtr.Zero)
                {
                    throw new Win32Exception(Marshal.GetLastWin32Error());
                }

                var hLoadLib = Imports.GetProcAddress(hKernel32, "LoadLibraryW");
                if (hLoadLib == IntPtr.Zero)
                {
                    throw new Win32Exception(Marshal.GetLastWin32Error());
                }

                // allocate memory to the local process for libFullPath
                pLibRemote = Imports.VirtualAllocEx(proc.GetHandle(), IntPtr.Zero, (uint)sizeUni, AllocationType.Commit,
                                                    MemoryProtection.ReadWrite);
                if (pLibRemote == IntPtr.Zero)
                {
                    throw new Win32Exception(Marshal.GetLastWin32Error());
                }

                int bytesWritten;
                if (!Imports.WriteProcessMemory(proc.GetHandle(), pLibRemote, pLibFullPath, (uint)sizeUni, out bytesWritten) || bytesWritten != sizeUni)
                {
                    throw new Win32Exception(Marshal.GetLastWin32Error());
                }

                // load dll via call to LoadLibrary using CreateRemoteThread
                hThread = Imports.CreateRemoteThread(proc.GetHandle(), IntPtr.Zero, 0, hLoadLib, pLibRemote, 0,
                                                     IntPtr.Zero);

                if (hThread == IntPtr.Zero)
                {
                    throw new Win32Exception(Marshal.GetLastWin32Error());
                }
                if (Imports.WaitForSingleObject(hThread, (uint)ThreadWaitValue.Infinite) != (uint)ThreadWaitValue.Object0)
                {
                    throw new Win32Exception(Marshal.GetLastWin32Error());
                }

                IntPtr hLibModule = IntPtr.Zero;

                // get address of loaded module
                foreach (ProcessModule mod in proc.Modules)
                {
                    if (mod.FileName == modulePath)
                    {
                        hLibModule = mod.BaseAddress;
                        break;
                    }
                }

                if (hLibModule == IntPtr.Zero)
                {
                    throw new Exception("Module is not injected anymore and/or got unloaded.");
                }

                var module = new InjectedModule(hLibModule, moduleName, modulePath, proc);
                manager.InjectedModules[moduleName] = module;
                return(new InjectedModule(hLibModule, moduleName, modulePath, proc));
            }
            finally
            {
                Marshal.FreeHGlobal(pLibFullPath);
                if (hThread != IntPtr.Zero)
                {
                    Imports.CloseHandle(hThread);
                }
                if (pLibRemote != IntPtr.Zero)
                {
                    Imports.VirtualFreeEx(proc.GetHandle(), pLibRemote, 0, AllocationType.Release);
                }
            }
        }
Beispiel #7
0
 public static IEnumerable <InjectedModule> EnumInjectedModules(this Process proc)
 {
     return(ProcessMemoryManager.ForProcess(proc).InjectedModules.Values);
 }
        private IntPtr CallExportInternal(uint timeout, string funcName, IntPtr data, Type dataType, int dataSize)
        {
            var manager = ProcessMemoryManager.ForProcess(_parentProcess);

            if (!manager.InjectedModules.ContainsKey(ModuleName))
            {
                throw new Exception("The injected module does not appear to be associated to its parent process. This could indicate corrupted process state");
            }

            var pFunc = FindExport(funcName);

            var pDataRemote = IntPtr.Zero;
            var hThread     = IntPtr.Zero;

            try
            {
                // check if we have all required parameters to pass a data parameter
                // if we don't, assume we aren't passing any data
                if (!(data == IntPtr.Zero || dataSize == 0 || dataType == null))
                {
                    // allocate memory in remote process for parameter
                    pDataRemote = Imports.VirtualAllocEx(_parentProcess.GetHandle(), IntPtr.Zero, (uint)dataSize, AllocationType.Commit, MemoryProtection.ReadWrite);
                    if (pDataRemote == IntPtr.Zero)
                    {
                        throw new Win32Exception(Marshal.GetLastWin32Error());
                    }

                    // rebase the data so that pointers point to valid memory locations for the target process
                    // this renders the unmanaged structure useless in this process - should be able to re-rebase back to
                    // this target process by calling CustomMarshal.RebaseUnmanagedStructure(data, data, dataType); but not tested
                    CustomMarshal.RebaseUnmanagedStructure(data, pDataRemote, dataType);

                    int bytesWritten;
                    if (!Imports.WriteProcessMemory(_parentProcess.GetHandle(), pDataRemote, data, (uint)dataSize, out bytesWritten))
                    {
                        throw new Win32Exception(Marshal.GetLastWin32Error());
                    }
                }

                hThread = Imports.CreateRemoteThread(_parentProcess.GetHandle(), IntPtr.Zero, 0, pFunc, pDataRemote, 0, IntPtr.Zero);
                if (hThread == IntPtr.Zero)
                {
                    throw new Win32Exception(Marshal.GetLastWin32Error());
                }

                var singleObject = Imports.WaitForSingleObject(hThread, timeout);
                if (!(singleObject == (uint)ThreadWaitValue.Object0 || singleObject == (uint)ThreadWaitValue.Timeout))
                {
                    throw new Win32Exception(Marshal.GetLastWin32Error());
                }

                IntPtr pRet;
                if (!Imports.GetExitCodeThread(hThread, out pRet))
                {
                    throw new Win32Exception(Marshal.GetLastWin32Error());
                }

                return(pRet);
            }
            finally
            {
                if (pDataRemote != IntPtr.Zero)
                {
                    Imports.VirtualFreeEx(_parentProcess.GetHandle(), pDataRemote, 0, AllocationType.Release);
                }
                if (hThread != IntPtr.Zero)
                {
                    Imports.CloseHandle(hThread);
                }
            }
        }