GetProcAddress() 개인적인 메소드

private GetProcAddress ( IntPtr hModule, string procName ) : IntPtr
hModule System.IntPtr
procName string
리턴 System.IntPtr
예제 #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
            /**
             * Actual function to find export - loosely modelled off Cypher's idea/code for loading module into this
             * process to find address. Loads module as data, finds RVA of function and uses to find address in target
             * process
             */
            private IntPtr FindExport(string func)
            {
                IntPtr hModule = IntPtr.Zero;

                try
                {
                    // Load module into local process address space
                    hModule = Imports.LoadLibraryEx(Module.FileName, IntPtr.Zero, LoadLibraryExFlags.DontResolveDllReferences);
                    if (hModule == IntPtr.Zero)
                    {
                        throw new Win32Exception(Marshal.GetLastWin32Error());
                    }

                    // Call GetProcAddress to get the address of the function in the module locally
                    IntPtr pFunc = Imports.GetProcAddress(hModule, func);
                    if (pFunc == IntPtr.Zero)
                    {
                        throw new Win32Exception(Marshal.GetLastWin32Error());
                    }

                    // Get RVA of export and add to base address of injected module
                    // hack at the moment to deal with x64
                    bool   x64 = IntPtr.Size == 8;
                    IntPtr pExportAddr;
                    if (x64)
                    {
                        pExportAddr = new IntPtr(Module.BaseAddress.ToInt64() + (pFunc.ToInt64() - hModule.ToInt64()));
                    }
                    else
                    {
                        pExportAddr = new IntPtr(Module.BaseAddress.ToInt32() + (pFunc.ToInt32() - hModule.ToInt32()));
                    }

                    return(pExportAddr);
                }
                finally
                {
                    Imports.CloseHandle(hModule);
                }
            }
예제 #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
            }
        }