示例#1
0
        /// <summary>
        ///     Obtains a pointer to the specified exported function.
        /// </summary>
        /// <param name="exportName">Name of the export.</param>
        /// <returns></returns>
        /// <exception cref="InjectionException">
        ///     Couldn't LoadLibrary into local thread to obtain export pointer!
        ///     or
        ///     Couldn't obtain function pointer for the specified export!
        /// </exception>
        public IntPtr GetExportPointer(string exportName)
        {
            // Fairly certain this method was first implemented by Cypher aka RaptorFactor, so kudos to him.
            IntPtr exportPtr;

            // Call LoadLibraryExW without resolving DLL references - if at all possible we don't want to run any remote code
            // on "our" thread - all we need to do is resolve an export.
            using (var lib = SafeLibraryHandle.LoadLibraryEx(Module.FileName, (uint)LoadLibraryExOptions.DontResolveDllReferences)
                   )
            {
                if (lib == null)
                {
                    throw new InjectionException("Couldn't LoadLibrary into local thread to obtain export pointer!");
                }

                var funcPtr = UnsafeNativeMethods.GetProcAddress(lib.DangerousGetHandle(), exportName);
                if (funcPtr == IntPtr.Zero)
                {
                    throw new InjectionException("Couldn't obtain function pointer for the specified export!");
                }

                // abs - base = ptr
                exportPtr = funcPtr - Module.BaseAddress.ToInt32();
            }

            return(exportPtr);
        }
示例#2
0
        /// <summary>
        ///     Frees this library through calling FreeLibrary.
        /// </summary>
        /// <param name="isLocalProcessMemory">if set to <c>true</c> [is local process memory].</param>
        /// <returns>
        ///     The exit code of FreeLibrary
        /// </returns>
        /// <exception cref="BlueRainException">Couldn't find FreeMemory in Kernel32!</exception>
        /// <exception cref="InjectionException">
        ///     WaitForSingleObject returned an unexpected value while waiting for the
        ///     remote thread to be created for module eject.
        /// </exception>
        public bool Free(bool isLocalProcessMemory)
        {
            // Easy game easy life.
            if (isLocalProcessMemory)
            {
                return(UnsafeNativeMethods.FreeLibrary(BaseAddress));
            }

            var kernel32Handle = UnsafeNativeMethods.GetModuleHandle(UnsafeNativeMethods.Kernel32);
            var freeLibrary    = UnsafeNativeMethods.GetProcAddress(kernel32Handle.DangerousGetHandle(), "FreeLibrary");

            if (freeLibrary == IntPtr.Zero)
            {
                throw new BlueRainException("Couldn't find FreeMemory in Kernel32!");
            }

            SafeMemoryHandle threadHandle = null;
            uint             exitCode;

            try
            {
                threadHandle = UnsafeNativeMethods.CreateRemoteThread(kernel32Handle.DangerousGetHandle(), IntPtr.Zero, 0,
                                                                      freeLibrary, BaseAddress, 0, IntPtr.Zero);

                if (UnsafeNativeMethods.WaitForSingleObject(threadHandle.DangerousGetHandle(), uint.MaxValue) != 0x0)
                {
                    throw new InjectionException(
                              "WaitForSingleObject returned an unexpected value while waiting for the remote thread to be created for module eject.");
                }

                UnsafeNativeMethods.GetExitCodeThread(threadHandle.DangerousGetHandle(), out exitCode);
            }
            finally
            {
                if (!kernel32Handle.IsClosed)
                {
                    kernel32Handle.Close();
                }

                if (threadHandle != null && !threadHandle.IsClosed)
                {
                    threadHandle.Close();
                }
            }

            return(exitCode != 0);
        }
示例#3
0
        private InjectedModule InjectLibraryExternal(string libraryPath)
        {
            // Injecting remotely consists of a few steps:
            // 1. GetProcAddress on kernel32 to get a pointer to LoadLibraryW
            // 2. Allocate chunk of memory to write the path to our library to
            // 3. CreateRemoteThread that calls LoadLibraryW and pass it a pointer to our chunk
            // 4. Get thread's exit code
            // 5. ????
            // 6. Profit
            var memory = _memory as ExternalProcessMemory;

            // Realistically won't happen, but code analysis complains about it being null.
            if (memory == null)
            {
                throw new InvalidOperationException("A valid memory instance is required for InjectLibraryExternal!");
            }

            if (memory.ProcessHandle.IsInvalid)
            {
                throw new InvalidOperationException("Can not inject library with an invalid ProcessHandle in ExternalProcessMemory!");
            }

            var path            = Path.GetFullPath(libraryPath);
            var libraryFileName = Path.GetFileName(libraryPath);

            ProcessModule ourModule;

            SafeMemoryHandle threadHandle   = null;
            SafeMemoryHandle kernel32Handle = null;

            try
            {
                kernel32Handle = UnsafeNativeMethods.GetModuleHandle(UnsafeNativeMethods.Kernel32);

                var loadLibraryPtr =
                    UnsafeNativeMethods.GetProcAddress(kernel32Handle.DangerousGetHandle(), "LoadLibraryW");

                if (loadLibraryPtr == IntPtr.Zero)
                {
                    throw new InjectionException("Couldn't obtain handle to LoadLibraryW in remote process!");
                }

                var pathBytes = Encoding.Unicode.GetBytes(path);

                using (var alloc = memory.Allocate((UIntPtr)pathBytes.Length))
                {
                    alloc.WriteBytes(IntPtr.Zero, pathBytes);

                    threadHandle = UnsafeNativeMethods.CreateRemoteThread(memory.ProcessHandle.DangerousGetHandle(), IntPtr.Zero, 0x0,
                                                                          loadLibraryPtr, alloc.Address, 0, IntPtr.Zero);

                    if (threadHandle.IsInvalid)
                    {
                        throw new InjectionException(
                                  "Couldn't obtain a handle to the remotely created thread for module injection!");
                    }
                }

                // ThreadWaitValue.Infinite = 0xFFFFFFFF = uint.MaxValue - Object0 = 0x0
                if (UnsafeNativeMethods.WaitForSingleObject(threadHandle.DangerousGetHandle(), uint.MaxValue) != 0x0)
                {
                    throw new InjectionException(
                              "WaitForSingleObject returned an unexpected value while waiting for the remote thread to be created for module injection.");
                }

                uint exitCode;
                if (!UnsafeNativeMethods.GetExitCodeThread(threadHandle.DangerousGetHandle(), out exitCode))
                {
                    throw new InjectionException("Couldn't obtain exit code for LoadLibraryW thread in remote process!");
                }

                // Let's make sure our module is actually present in the remote process now (assuming it's doing nothing special to hide itself..)
                var moduleHandle = UnsafeNativeMethods.GetModuleHandle(libraryFileName);
                if (moduleHandle.IsInvalid)
                {
                    throw new InjectionException(
                              "Couldn't obtain module handle to remotely injected library after LoadLibraryW!");
                }

                ourModule = memory.Process.Modules.Cast <ProcessModule>()
                            .FirstOrDefault(m => m.BaseAddress == moduleHandle.DangerousGetHandle());
            }
            finally
            {
                if (threadHandle != null && !threadHandle.IsClosed)
                {
                    threadHandle.Close();
                }

                if (kernel32Handle != null && !kernel32Handle.IsClosed)
                {
                    kernel32Handle.Close();
                }
            }

            // We can safely do this - if something went wrong we wouldn't be here.
            var module = new InjectedModule(ourModule, _memory);

            _injectedModules.Add(path, module);
            return(module);
        }