/// <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 RemoteFunction FindFunction(string functionName) { // Create the tuple var tuple = Tuple.Create(functionName, MemorySharp.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 = Process.GetCurrentProcess() .Modules.Cast <ProcessModule>() .FirstOrDefault(m => string.Equals(m.FileName, Path, StringComparison.CurrentCultureIgnoreCase)); var isManuallyLoaded = false; try { // If this is not the case, load the module inside the local process if (localModule == null) { isManuallyLoaded = true; localModule = ModuleCore.LoadLibrary(Native.FileName); } // Get the offset of the function var offset = ModuleCore.GetProcAddress(localModule, functionName).ToInt64() - localModule.BaseAddress.ToInt64(); // Rebase the function with the remote module var function = new RemoteFunction(MemorySharp, 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) { ModuleCore.FreeLibrary(localModule); } } }