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); } } }
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); }
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); } } }
public static IntPtr GetHandle(this Process proc) { return(ProcessMemoryManager.ForProcess(proc).Handle); }
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); } } }
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); } } }