WaitForSingleObject() private method

private WaitForSingleObject ( IntPtr hObject, uint dwMilliseconds ) : uint
hObject System.IntPtr
dwMilliseconds uint
return uint
示例#1
0
        /// <summary>
        /// Ejects a library that this Injector has previously injected into the target process. <paramref name="libName"/> is the name of the module to
        /// eject, as per the name stored in <see cref="Injector.InjectLibrary"/>. Passing the same value as passed to InjectLibrary should always work unless a
        /// relative path was used and the program's working directory has changed.
        /// </summary>
        /// <param name="libName">The name of the module to eject</param>
        public void EjectLibrary(string libName)
        {
            string libSearchName = File.Exists(libName) ? Path.GetFileName(Path.GetFullPath(libName)) : libName;

            if (!injectedModules.ContainsKey(libSearchName))
            {
                throw new InvalidOperationException("That module has not been injected into the process and thus cannot be ejected");
            }

            // resources that need to be freed
            IntPtr hThread = IntPtr.Zero;

            try
            {
                // get handle to kernel32 and FreeLibrary
                IntPtr hKernel32 = Imports.GetModuleHandle("Kernel32");
                if (hKernel32 == IntPtr.Zero)
                {
                    throw new Win32Exception(Marshal.GetLastWin32Error());
                }
                IntPtr hFreeLib = Imports.GetProcAddress(hKernel32, "FreeLibrary");
                if (hFreeLib == IntPtr.Zero)
                {
                    throw new Win32Exception(Marshal.GetLastWin32Error());
                }

                hThread = Imports.CreateRemoteThread(_handle, IntPtr.Zero, 0, hFreeLib,
                                                     injectedModules[libSearchName].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());
                }

                // get exit code of FreeLibrary
                IntPtr pFreeLibRet; // = IntPtr.Zero;
                if (!Imports.GetExitCodeThread(hThread, out pFreeLibRet))
                {
                    throw new Win32Exception(Marshal.GetLastWin32Error());
                }

                if (pFreeLibRet == IntPtr.Zero)
                {
                    throw new Exception("FreeLibrary failed in remote process");
                }
            }
            catch
            {
            }
            finally
            {
                Imports.CloseHandle(hThread);
            }
        }
示例#2
0
        private IntPtr CallExportInternal(uint timeout, string libName, string funcName, IntPtr data, Type dataType, uint dataSize)
        {
            string libSearchName = File.Exists(libName) ? Path.GetFileName(Path.GetFullPath(libName)) : libName;

            if (!injectedModules.ContainsKey(libSearchName))
            {
                throw new InvalidOperationException("That module has not been injected into the process and thus cannot be ejected");
            }

            IntPtr pFunc = injectedModules[libSearchName][funcName];
            // resources that need to be cleaned
            IntPtr pDataRemote = IntPtr.Zero;
            IntPtr 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(_handle, IntPtr.Zero, 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(_handle, pDataRemote, data, dataSize, out bytesWritten))
                    {
                        throw new Win32Exception(Marshal.GetLastWin32Error());
                    }
                }

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

                uint 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
            {
                Imports.VirtualFreeEx(_process.Handle, pDataRemote, 0, AllocationType.Release);
                Imports.CloseHandle(hThread);
            }
        }
示例#3
0
        /// <summary>
        /// Injects a library into this Injector's process. <paramref name="libPath"/> can be
        /// relative or absolute; either way, the injected module will be referred to by module name only.
        /// I.e. "c:\some\directory\library.dll", "library.dll" and "..\library.dll" will all be referred to
        /// as "library.dll"
        /// </summary>
        /// <param name="libPath">Relative or absolute path to the dll to be injected</param>
        public void InjectLibrary(string libPath)
        {
            // (in?)sanity check, pretty sure this is never possible as the constructor will error - left over from how it previously was developed
            if (_process == null)
            {
                throw new InvalidOperationException("This injector has no associated process and thus cannot inject a library");
            }
            if (_handle == IntPtr.Zero)
            {
                throw new InvalidOperationException("This injector does not have a valid handle to the associated process and thus cannot inject a library");
            }

            if (!File.Exists(libPath))
            {
                throw new FileNotFoundException(string.Format("Unable to find library {0} to inject into process {1}", libPath, _process.ProcessName), libPath);
            }

            // convenience variables
            string fullPath = Path.GetFullPath(libPath);
            string libName  = Path.GetFileName(fullPath);

            // declare resources that need to be freed in finally
            IntPtr pLibRemote            = IntPtr.Zero;                          // pointer to allocated memory of lib path string
            IntPtr hThread               = IntPtr.Zero;                          // handle to thread from CreateRemoteThread
            IntPtr pLibFullPathUnmanaged = Marshal.StringToHGlobalUni(fullPath); // unmanaged C-String pointer

            try
            {
                uint sizeUni = (uint)Encoding.Unicode.GetByteCount(fullPath);

                // Get Handle to Kernel32.dll and pointer to LoadLibraryW
                IntPtr hKernel32 = Imports.GetModuleHandle("Kernel32");
                if (hKernel32 == IntPtr.Zero)
                {
                    throw new Win32Exception(Marshal.GetLastWin32Error());
                }
                IntPtr 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(_handle, IntPtr.Zero, sizeUni, AllocationType.Commit, MemoryProtection.ReadWrite);
                if (pLibRemote == IntPtr.Zero)
                {
                    throw new Win32Exception(Marshal.GetLastWin32Error());
                }

                // write libFullPath to pLibPath
                int bytesWritten;
                if (!Imports.WriteProcessMemory(_handle, pLibRemote, pLibFullPathUnmanaged, sizeUni, out bytesWritten) || bytesWritten != (int)sizeUni)
                {
                    throw new Win32Exception(Marshal.GetLastWin32Error());
                }

                // load dll via call to LoadLibrary using CreateRemoteThread
                hThread = Imports.CreateRemoteThread(_handle, 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());
                }

                // get address of loaded module - this doesn't work in x64, so just iterate module list to find injected module
                IntPtr hLibModule;// = IntPtr.Zero;
                if (!Imports.GetExitCodeThread(hThread, out hLibModule))
                {
                    throw new Win32Exception(Marshal.GetLastWin32Error());
                }
                if (hLibModule == IntPtr.Zero)
                {
                    throw new Exception("Code executed properly, but unable to get an appropriate module handle, possible Win32Exception", new Win32Exception(Marshal.GetLastWin32Error()));
                }

                // iterate modules in target process to find our newly injected module
                ProcessModule modFound = null;
                foreach (ProcessModule mod in _process.Modules)
                {
                    if (mod.ModuleName == libName)
                    {
                        modFound = mod;
                        break;
                    }
                }
                if (modFound == null)
                {
                    throw new Exception("Injected module could not be found within the target process!");
                }

                injectedModules.Add(libName, new InjectedModule(modFound));
            }
            finally
            {
                Marshal.FreeHGlobal(pLibFullPathUnmanaged);                                    // free unmanaged string
                Imports.CloseHandle(hThread);                                                  // close thread from CreateRemoteThread
                Imports.VirtualFreeEx(_process.Handle, pLibRemote, 0, AllocationType.Release); // Free memory allocated
            }
        }