private void EjectDll()
        {
            // Get address of FreeLibrary function in kernel32.
            IntPtr addrFreeLibrary = WinApi.GetProcAddress(_hKernel32, "FreeLibrary");

            if (addrFreeLibrary == IntPtr.Zero)
            {
                throw new Win32Exception(Marshal.GetLastWin32Error(),
                                         "Cannot find FreeLibrary function in kernel32 module.");
            }

            // Create remote thread to free library from target process.
            int    threadId;
            IntPtr hThread = WinApi.CreateRemoteThread(_hProcess, IntPtr.Zero, 0, addrFreeLibrary,
                                                       _hModule, 0, out threadId);

            if (hThread == IntPtr.Zero)
            {
                throw new Win32Exception(Marshal.GetLastWin32Error(),
                                         "Error creating remote thread in target process.");
            }

            // Wait for thread to finish.
            int waitRet = WinApi.WaitForSingleObject(hThread, 10000);

            if (waitRet == WinApi.WAIT_FAILED)
            {
                throw new Win32Exception();
            }
            if (waitRet == WinApi.WAIT_TIMEOUT)
            {
                throw new TimeoutException();
            }

            // Clean up.
            WinApi.CloseHandle(hThread);
        }
        private void InjectDll(string dllFileName)
        {
            bool retValue;

            // Get handle to target process.
            _hProcess = WinApi.OpenProcess(ProcessAccessFlags.All, false, _procInfo.dwProcessId);
            if (_hProcess == IntPtr.Zero)
            {
                throw new Win32Exception(Marshal.GetLastWin32Error(),
                                         string.Format("Cannot open process with ID {0}.", _procInfo.dwProcessId));
            }

            // Get address of LoadLibrary function in kernel32.
            _hKernel32 = WinApi.GetModuleHandle("kernel32");
            if (_hKernel32 == IntPtr.Zero)
            {
                throw new Win32Exception(Marshal.GetLastWin32Error(),
                                         "Cannot get handle to kernel32 module.");
            }

            // LoadLibraryA (ascii)/LoadLibraryW (unicode)
            IntPtr addrLoadLibrary = WinApi.GetProcAddress(_hKernel32, "LoadLibraryA");

            if (addrLoadLibrary == IntPtr.Zero)
            {
                throw new Win32Exception(Marshal.GetLastWin32Error(),
                                         "Cannot find LoadLibrary function in kernel32 module.");
            }

            // Write file name of DLL into process memory.
            _procBaseAddress = WinApi.VirtualAllocEx(_hProcess, IntPtr.Zero, dllFileName.Length,
                                                     WinApi.MEM_COMMIT, WinApi.PAGE_READWRITE);
            if (_procBaseAddress == IntPtr.Zero)
            {
                throw new Win32Exception(Marshal.GetLastWin32Error(),
                                         "Error allocating virtual memory in target process.");
            }

            int bytesWritten;

            retValue = WinApi.WriteProcessMemory(_hProcess, _procBaseAddress,
                                                 Encoding.ASCII.GetBytes(dllFileName), dllFileName.Length, out bytesWritten);
            if (!retValue)
            {
                throw new Win32Exception(Marshal.GetLastWin32Error(),
                                         "Error writing DLL file name in target process memory.");
            }

            // Create remote thread to load library into target process.
            IntPtr hThread = WinApi.CreateRemoteThread(_hProcess, IntPtr.Zero, 0, addrLoadLibrary,
                                                       _procBaseAddress, 0, out _threadId);

            if (hThread == IntPtr.Zero)
            {
                throw new Win32Exception(Marshal.GetLastWin32Error(),
                                         "Error creating remote thread in target process.");
            }

            // Wait for thread to finish.
            int waitRet = WinApi.WaitForSingleObject(hThread, 10000);

            if (waitRet == WinApi.WAIT_FAILED)
            {
                throw new Win32Exception();
            }
            if (waitRet == WinApi.WAIT_TIMEOUT)
            {
                throw new TimeoutException();
            }

            // Get handle to loaded module from exit code.
            // Note: exit code will be zero unless DLL has already terminated.
            int exitCode;

            WinApi.GetExitCodeThread(hThread, out exitCode);
            _hModule = (IntPtr)exitCode;

            // Clean up.
            WinApi.VirtualFreeEx(_hProcess, _procBaseAddress, dllFileName.Length, WinApi.MEM_RELEASE);
            WinApi.CloseHandle(hThread);
        }