/// <summary> /// Finds the specified function in the remote module. /// </summary> /// <param name="functionName">The name of the function (case sensitive).</param> /// <returns>A new instance of a <see cref="RemoteFunction" /> class.</returns> /// <remarks> /// Interesting article on how DLL loading works: http://msdn.microsoft.com/en-us/magazine/bb985014.aspx /// </remarks> public IProcessFunction FindFunction(string functionName) { // Create the tuple var tuple = Tuple.Create(functionName, Process.Handle); // Check if the function is already cached if (CachedFunctions.ContainsKey(tuple)) { return(CachedFunctions[tuple]); } // If the function is not cached // Check if the local process has this module loaded var localModule = System.Diagnostics.Process.GetCurrentProcess() .Modules.Cast <ProcessModule>() .FirstOrDefault(m => m.FileName.ToLower() == Path.ToLower()); var isManuallyLoaded = false; try { // If this is not the case, load the module inside the local process if (localModule == null) { isManuallyLoaded = true; localModule = ModuleHelper.LoadLibrary(Native.FileName); } // Get the offset of the function var offset = ModuleHelper.GetProcAddress(localModule, functionName).ToInt64() - localModule.BaseAddress.ToInt64(); // Rebase the function with the remote module var function = new RemoteFunction(Process, new IntPtr(Native.BaseAddress.ToInt64() + offset), functionName); // Store the function in the cache CachedFunctions.Add(tuple, function); // Return the function rebased with the remote module return(function); } finally { // Free the module if it was manually loaded if (isManuallyLoaded) { ModuleHelper.FreeLibrary(localModule); } } }
/// <summary> /// Frees the loaded dynamic-link library (DLL) module and, if necessary, decrements its reference count. /// </summary> /// <param name="module">The <see cref="ProcessModule" /> object corresponding to the library to free.</param> public static void FreeLibrary(this ProcessModule module) { ModuleHelper.FreeLibrary(module.ModuleName); }