在检查Microsoft Word的加载模块时,我发现了一些非常奇怪的东西。我写了一个小程序来输出所有加载的DLL的位置。这是输出:
当我试图在我的电脑上找到这些模块时,我找不到它们在给定位置,但在另一个位置:
我无法弄清楚为什么DLL的路径不同,我也找不到与谷歌相关的任何东西,虽然我怀疑它与VFS的东西有关。
也就是说,Process Explorer以某种方式设法显示DLL的原始位置。
有人可以告诉我Process Explorer如何做到这一点,以及如何在我的代码中实现相同的结果?
---------------编辑---------------- < / p>
我也试过注入一个DLL并走了WINWORD的LDR,但我仍然看不到原来的DLL位置。
Sysinternal的ListDlls实用程序也不显示原始DLL位置。 目前,只有Process Explorer显示正确的位置。
答案 0 :(得分:3)
Office 2016正在使用App-V重定向并虚拟化其部分路径。这使得查找DLL有点复杂化。 Process Explorer使用稍微复杂的 1 方法来查找DLL。一般来说,这个过程是:
TH32CS_SNAPMODULE
和TH32CS_SNAPMODULE32
标记创建工具帮助32快照。Module32First
和Module32Next
获取有关此过程中模块的信息。GetFinalPathNameByHandle
获取已解析的路径。 (请注意,这将是包含前导\\?\
的路径,但这很容易删除。)示例实现:
// Obtain the Process ID however you like. I used GetWindowThreadProcessId.
if (processId != 0)
{
HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, processId);
if (snapshot != INVALID_HANDLE_VALUE)
{
MODULEENTRY32W moduleInfo = { 0 };
moduleInfo.dwSize = sizeof(MODULEENTRY32W);
BOOL ok = Module32FirstW(snapshot, &moduleInfo);
if (!ok)
{
// The read failed, handle the error here.
}
do
{
HANDLE hFile = CreateFileW(moduleInfo.szExePath,
0,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (hFile)
{
WCHAR realPath[MAX_PATH];
DWORD result = GetFinalPathNameByHandleW(hFile,
realPath,
MAX_PATH,
FILE_NAME_NORMALIZED);
if (result > 0)
{
wcout << L"Module: " << realPath << endl;
}
CloseHandle(hFile);
}
else
{
wcout << L"Module Name: " << moduleInfo.szExePath << endl;
}
} while (Module32NextW(snapshot, &moduleInfo));
CloseHandle(snapshot);
}
}
1 请注意,Process Explorer是由Sysinternals编写的,可能正在使用较低级别的信息。此方法确实在2016年安装时解析了DLL。