GetProcAddress和所有加载的库

GetProcAddress with all loaded libraries

本文关键字:加载 GetProcAddress      更新时间:2023-10-16

使用dlopen,您可以提供NULL作为库名,并获得一个句柄,该句柄允许您在任何加载的库中查找符号:

如果filename是NULL指针,那么返回的句柄是主程序。当给定给dlsym()时,这个句柄会导致搜索符号,然后是加载在程序启动,然后由dlopen()加载的所有共享库RTLD_GLOBAL.

你能做同样的GetProcAddress ?我想搜索Windows API的存在,但在Windows 8中加载了不同的库。

通过查看COFF头,我知道加载了哪些库,我想我可以在那里循环处理句柄…

这是我当前使用的代码:

.hpp

#include <string>
#include <stdexcept>
/**
 * @~english
 * Looks up a Windows API function. Make sure you set @c _WIN32_WINNT so that the definition is available at compile
 * time.
 * @par Example
 * @code
 * # undef _WIN32_WINNT
 * # define _WIN32_WINNT 0x600
 * # include <system/inc/nt/windows.h>
 * static const auto initialize_srw_lock_ptr = FunctionPtrLookup(InitializeSRWLock, "kernel32");
 * @endcode
 * @param function the function definition to lookup
 * @retval nullptr the function did not exist on this version of Windows
 * @returns a function pointer to invoke
 */
#define FunctionPtrLookup(function, library) 
  FunctionLookup<decltype(function)>(#function, library)
/**
 * @~english
 * The return type of FunctionLookup
 */
typedef void(*FunctionLookupPtr)();
/**
 * @~english
 * Looks up a Windows API function. 
 * @param name the name of the function to find in the library
 * @retval nullptr the function did not exist on this version of Windows
 * @returns a function pointer to invoke
 * @see FunctionPtrLookup
 */
FunctionLookupPtr FunctionLookup(const std::string& name, const std::string& library);
/// @copydoc FunctionLookup
template<typename Signature>
const Signature * FunctionLookup(const std::string& name, const std::string& library) {
  return reinterpret_cast<const Signature*>(FunctionLookup(name, library));
}

.cpp

FunctionLookupPtr FunctionLookup(const std::string& name, const std::string& library) {
  const auto wide_library = Utf8ToWide(library);
  const auto lib = LoadLibraryW(wide_library.c_str());
  if (!lib) {
    return nullptr;
  }
  return reinterpret_cast<FunctionLookupPtr>(GetProcAddress(lib, name.c_str()));
}

理想情况下,我想要删除library变量

你可以使用EnumProcessModules来枚举当前进程的所有加载模块,使用这里的例子:http://msdn.microsoft.com/en-us/library/ms682621%28v=vs.85%29.aspx,如果你用GetCurrentProcessId()调用PrintModules,它将枚举当前进程的所有HMODULE句柄(值在hMods[i]中)。你可以将它们与GetProcAddress一起使用来查找你的函数。

你必须意识到有可能在不同的dll中找到相同的命名函数,大多数你知道WinAPI函数的dll名称。