在许多情况下,加载一些较新的 API 会使用这样的构造:
(FARPROC&)pfnZwQueryVirtualMemory = ::GetProcAddress(::GetModuleHandle(L"ntdll.dll"), "ZwQueryVirtualMemory");
但是,考虑到Dll 劫持的可能性,因此指定 DLL 的绝对路径是否更好。还是只是矫枉过正?
WCHAR buff[MAX_PATH];
buff[0] = 0;
if(::GetSystemDirectory(buff, MAX_PATH) &&
::PathAddBackslash(buff) &&
SUCCEEDED(::StringCchCat(buff, MAX_PATH, L"ntdll.dll")))
{
(FARPROC&)pfnZwQueryVirtualMemory = ::GetProcAddress(::GetModuleHandle(buff), "ZwQueryVirtualMemory");
}
else
{
//Something went wrong
pfnZwQueryVirtualMemory = NULL;
}
后一种方法的问题在于它并不总是有效(例如使用Comctl32.dll
.)
您不必为 ntdll.dll 和 kernel32.dll 做任何特别的事情,因为它们将在您有机会做任何事情之前被加载,它们也在 known-dlls 列表中。
dll劫持问题通常包括辅助库。以 version.dll 为例,它不再在 known-dlls 列表中,因此明确链接到它是有问题的,它需要动态加载。
最好的解决方案是三件事的组合:
SetDefaultDllDirectories(LOAD_LIBRARY_SEARCH_SYSTEM32)
如果可用则调用(Win8+ 和更新的 Win7)。LoadLibrary
的完整路径(GetSystemDirectory
调用之前)GetModuleHandle
。如果SetDefaultDllDirectories
不可用,那么如果您不控制应用程序目录,就很难保护自己,因为各种 Windows 函数会延迟加载 shcore.dll 等没有完整路径的 dll(尤其是 shell API)。SetDllDirectory("")
对当前/工作目录有帮助,但对于未修补的 Win8 系统之前的系统没有好的应用程序目录解决方法,您只需要使用进程监视器进行测试并在 WinMain 早期手动加载有问题的库。
应用程序目录是一个问题,因为有些用户只是将所有内容都放在下载文件夹中并从那里运行它。这意味着您最终可能会在您的应用程序目录中发现一个恶意 dll。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句