获取进程加载的模块并不存在

时间:2016-06-22 18:48:13

标签: c++ c windows debugging winapi

在检查Microsoft Word的加载模块时,我发现了一些非常奇怪的东西。我写了一个小程序来输出所有加载的DLL的位置。这是输出:

Loaded modules using snapshot's WinApi

当我试图在我的电脑上找到这些模块时,我找不到它们在给定位置,但在另一个位置:

The DLL's actual location

我无法弄清楚为什么DLL的路径不同,我也找不到与谷歌相关的任何东西,虽然我怀疑它与VFS的东西有关。

也就是说,Process Explorer以某种方式设法显示DLL的原始位置。

有人可以告诉我Process Explorer如何做到这一点,以及如何在我的代码中实现相同的结果?

---------------编辑---------------- < / p>

  1. 我也试过注入一个DLL并走了WINWORD的LDR,但我仍然看不到原来的DLL位置。

  2. Sysinternal的ListDlls实用程序也不显示原始DLL位置。 目前,只有Process Explorer显示正确的位置。

1 个答案:

答案 0 :(得分:3)

Office 2016正在使用App-V重定向并虚拟化其部分路径。这使得查找DLL有点复杂化。 Process Explorer使用稍微复杂的 1 方法来查找DLL。一般来说,这个过程是:

  1. 使用TH32CS_SNAPMODULETH32CS_SNAPMODULE32标记创建工具帮助32快照。
  2. 使用Module32FirstModule32Next获取有关此过程中模块的信息。
  3. 要解析在我的Office 2016上存在App-V dll的符号链接,请打开该文件,然后使用GetFinalPathNameByHandle获取已解析的路径。 (请注意,这将是包含前导\\?\的路径,但这很容易删除。)
  4. 示例实现:

    // 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。