public IntPtr GetMainWindowHandleOfAttachedProcess() { if (this.AttachedProcess == null) { return(IntPtr.Zero); } var screenOfWindow = Screen.FromHandle(_attachedProcessMainWindowHwnd); if (screenOfWindow.Bounds.IsEmpty) { // obtain it using window traversal and top most var allWindowHandles = GeneralUtils.GetProcessWindowHandles(_attachedProcess); foreach (var hwnd in allWindowHandles) { WINDOWINFO info = new WINDOWINFO(); Win32Wrapper.GetWindowInfo(hwnd, ref info); screenOfWindow = Screen.FromHandle(hwnd); if (!screenOfWindow.Bounds.IsEmpty && info.rcWindow.Width > 10) { // window is on a monitor and has a width wider than 10 _attachedProcessMainWindowHwnd = hwnd; break; } } } return(_attachedProcessMainWindowHwnd); }
public static List <IntPtr> GetProcessWindowHandles(Process process) { List <IntPtr> rootWindows = GeneralUtils.GetChildWindows(IntPtr.Zero); List <IntPtr> dsProcRootWindows = new List <IntPtr>(); foreach (IntPtr hWnd in rootWindows) { Win32Wrapper.GetWindowThreadProcessId(hWnd, out var lpdwProcessId); if (lpdwProcessId == process.Id) { dsProcRootWindows.Add(hWnd); } } return(dsProcRootWindows); }
public static List <IntPtr> GetChildWindows(IntPtr parent) { List <IntPtr> result = new List <IntPtr>(); GCHandle listHandle = GCHandle.Alloc(result); try { Win32Wrapper.Win32Callback childProc = new Win32Wrapper.Win32Callback(GeneralUtils.EnumWindow); Win32Wrapper.EnumChildWindows(parent, childProc, GCHandle.ToIntPtr(listHandle)); } finally { if (listHandle.IsAllocated) { listHandle.Free(); } } return(result); }
/// <summary> /// Injects the dll with the path specified into the process with the id specified. /// </summary> /// <param name="processId">the PID of the process to inject the dll into.</param> /// <param name="dllPathNameToInject">The full path + filename of the dll to inject</param> /// <returns>true if succeeded, false otherwise. If false is returned, <see cref="LastError"/> is set with the error code.</returns> public bool PerformInjection(int processId, string dllPathNameToInject) { this.LastError = 0; uint dllLengthToPassInBytes = (uint)((dllPathNameToInject.Length + 1) * Marshal.SizeOf(typeof(char))); this.LastActionPerformed = "Opening the host process"; LogHandlerSingleton.Instance().LogLine("Opening the host process", "DllInjector", true); IntPtr processHandle = Win32Wrapper.OpenProcess(ProcessAccessFlags.CreateThread | ProcessAccessFlags.QueryInformation | ProcessAccessFlags.VirtualMemoryOperation | ProcessAccessFlags.VirtualMemoryWrite | ProcessAccessFlags.VirtualMemoryRead, false, (uint)processId); if (processHandle == IntPtr.Zero) { // failed, so set the error code and return this.LastError = Marshal.GetLastWin32Error(); return(false); } this.LastActionPerformed = "Obtaining the address of LoadLibraryA"; LogHandlerSingleton.Instance().LogLine("Obtaining the address of LoadLibraryA", "DllInjector", true); IntPtr loadLibraryAddress = Win32Wrapper.GetProcAddress(Win32Wrapper.GetModuleHandle("kernel32.dll"), "LoadLibraryA"); if (loadLibraryAddress == IntPtr.Zero) { this.LastError = Marshal.GetLastWin32Error(); return(false); } this.LastActionPerformed = "Allocating memory in the host process for the dll filename"; LogHandlerSingleton.Instance().LogLine("Allocating memory in the host process for the dll filename", "DllInjector", true); IntPtr memoryInTargetProcess = Win32Wrapper.VirtualAllocEx(processHandle, IntPtr.Zero, dllLengthToPassInBytes, AllocationType.Commit | AllocationType.Reserve, MemoryProtection.ReadWrite); if (memoryInTargetProcess == IntPtr.Zero) { this.LastError = Marshal.GetLastWin32Error(); return(false); } Thread.Sleep(500); this.LastActionPerformed = "Writing dll filename into memory allocated in host process"; LogHandlerSingleton.Instance().LogLine("Writing dll filename into memory allocated in host process", "DllInjector", true); var bytesToWrite = Encoding.Default.GetBytes(dllPathNameToInject); bool result = Win32Wrapper.WriteProcessMemory(processHandle, memoryInTargetProcess, bytesToWrite, dllLengthToPassInBytes, out var bytesWritten); if (!result || (bytesWritten.ToInt32() != bytesToWrite.Length + 1)) { this.LastError = Marshal.GetLastWin32Error(); return(false); } this.LastActionPerformed = "Creating a thread in the host process to load the dll"; LogHandlerSingleton.Instance().LogLine("Creating a thread in the host process to load the dll", "DllInjector", true); IntPtr remoteThreadHandle = Win32Wrapper.CreateRemoteThread(processHandle, IntPtr.Zero, 0, loadLibraryAddress, memoryInTargetProcess, 0, IntPtr.Zero); if (remoteThreadHandle == IntPtr.Zero) { this.LastError = Marshal.GetLastWin32Error(); return(false); } // no clean up of the memory, we're not going to 'unload' the dll... result = Win32Wrapper.CloseHandle(processHandle); if (!result) { this.LastError = Marshal.GetLastWin32Error(); return(false); } this.LastActionPerformed = "Done"; LogHandlerSingleton.Instance().LogLine("Injection completed", "DllInjector", true); return(true); }