哪个模块调用了我的 DLL 导出函数?

Which module called my DLL exported function?

背景

我正在开发一个导出单个函数的 C++ windows DLL 模块

__declspec(dllexport) void Run()

动机

我想对我的函数实施某种访问权限。我希望防止未经授权的模块激活我的 DLL 进程。

我不需要 robust/bullet 证明机制。我只喜欢 "defend" 来自其他模块的这个过程 运行 在我自己的应用程序下。

方法

获取调用模块名称,根据名称决定是否允许访问。

问题

  1. 这种方法是否足够?
  2. 如果是这样,我如何获得调用模块的名称?

if so, how do I get the name of the calling module?

  1. 通过调用获取return地址_ReturnAddress
  2. 获取包含此 return 地址的图像的基址 - RtlPcToFileHeader
  3. 终于调用了GetModuleFileName函数

所以代码可以像这样

HMODULE hmod;
if (RtlPcToFileHeader(_ReturnAddress(), (void**)&hmod))
{
    WCHAR sz[MAX_PATH];
    if (GetModuleFileName(hmod, sz, MAX_PATH))
    {
        DbgPrint("%p %S\n", hmod, sz);
    }
}

关于 - 这在 XP 中有效吗?是的,但有一张纸条。 _ReturnAddressCL 内在的 - 所以不依赖于 os 版本(比如 gcc 存在 __builtin_return_address (0) ) GetModuleFileName 也是非常古老的 api 函数并且存在于 win2000, xp, 无处不在。关于 RtlPcToFileHeader - 它在 ntdll.dll 中导出(并实现)在从 xp 到最新的所有 windows 版本中。也从 win2003 开始,它也从 kernel32.dll 导出,但在这里实现 - 只需 jumpntdll.RtlPcToFileHeader - 所以如果想在 xp 上也使用它 - link 和 ntdll.lib 并将其放在前面kernel32.lib 按 libs 顺序或者可以通过 GetProcAddress(GetModuleHandle(L"ntdll"), "RtlPcToFileHeader");

在运行时获取它

或者即使有人担心 RtlPcToFileHeader 会从 ntdll 中删除(这当然不是)可以使用这个 GetProcAddress(GetModuleHandle(g_xp ? L"ntdll" : L"kernel32"), "RtlPcToFileHeader");