草庐IT

c++ - 获取实际不存在的进程加载模块

coder 2024-06-04 原文

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

当我试图在我的 PC 上找到这些模块时,我无法在给定位置找到它们,而是在另一个位置:

我无法弄清楚为什么 DLL 的路径不同,而且我在 Google 中也找不到任何相关内容,尽管我怀疑它与 VFS 相关。

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

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

---------------- 编辑 ----------------

  1. 我也尝试过注入(inject) DLL 并遍历 WINWORD 的 LDR,但我仍然看不到原始 DLL 的位置。

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

最佳答案

Office 2016 使用 App-V 来重定向和虚拟化它的一些路径。这使查找 DLL 变得有点复杂。 Process Explorer 使用稍微复杂的1 方法来查找 DLL。一般过程是:

  1. 使用 TH32CS_SNAPMODULETH32CS_SNAPMODULE32 标志创建一个 Tool Help 32 快照。
  2. 使用Module32FirstModule32Next获取有关进程中模块的信息。
  3. 要解析 App-V dll 在我的 Office 2016 上存在的符号链接(symbolic link),请打开文件,然后使用 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。

关于c++ - 获取实际不存在的进程加载模块,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37976044/

有关c++ - 获取实际不存在的进程加载模块的更多相关文章

  1. ruby - 在 Ruby 中使用匿名模块 - 2

    假设我做了一个模块如下:m=Module.newdoclassCendend三个问题:除了对m的引用之外,还有什么方法可以访问C和m中的其他内容?我可以在创建匿名模块后为其命名吗(就像我输入“module...”一样)?如何在使用完匿名模块后将其删除,使其定义的常量不再存在? 最佳答案 三个答案:是的,使用ObjectSpace.此代码使c引用你的类(class)C不引用m:c=nilObjectSpace.each_object{|obj|c=objif(Class===objandobj.name=~/::C$/)}当然这取决于

  2. ruby-on-rails - Ruby net/ldap 模块中的内存泄漏 - 2

    作为我的Rails应用程序的一部分,我编写了一个小导入程序,它从我们的LDAP系统中吸取数据并将其塞入一个用户表中。不幸的是,与LDAP相关的代码在遍历我们的32K用户时泄漏了大量内存,我一直无法弄清楚如何解决这个问题。这个问题似乎在某种程度上与LDAP库有关,因为当我删除对LDAP内容的调用时,内存使用情况会很好地稳定下来。此外,不断增加的对象是Net::BER::BerIdentifiedString和Net::BER::BerIdentifiedArray,它们都是LDAP库的一部分。当我运行导入时,内存使用量最终达到超过1GB的峰值。如果问题存在,我需要找到一些方法来更正我的代

  3. ruby-on-rails - 如何验证 update_all 是否实际在 Rails 中更新 - 2

    给定这段代码defcreate@upgrades=User.update_all(["role=?","upgraded"],:id=>params[:upgrade])redirect_toadmin_upgrades_path,:notice=>"Successfullyupgradeduser."end我如何在该操作中实际验证它们是否已保存或未重定向到适当的页面和消息? 最佳答案 在Rails3中,update_all不返回任何有意义的信息,除了已更新的记录数(这可能取决于您的DBMS是否返回该信息)。http://ar.ru

  4. ruby-on-rails - 在混合/模块中覆盖模型的属性访问器 - 2

    我有一个包含模块的模型。我想在模块中覆盖模型的访问器方法。例如:classBlah这显然行不通。有什么想法可以实现吗? 最佳答案 您的代码看起来是正确的。我们正在毫无困难地使用这个确切的模式。如果我没记错的话,Rails使用#method_missing作为属性setter,因此您的模块将优先,阻止ActiveRecord的setter。如果您正在使用ActiveSupport::Concern(参见thisblogpost),那么您的实例方法需要进入一个特殊的模块:classBlah

  5. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

    我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

  6. ruby - 在 jRuby 中使用 'fork' 生成进程的替代方案? - 2

    在MRIRuby中我可以这样做:deftransferinternal_server=self.init_serverpid=forkdointernal_server.runend#Maketheserverprocessrunindependently.Process.detach(pid)internal_client=self.init_client#Dootherstuffwithconnectingtointernal_server...internal_client.post('somedata')ensure#KillserverProcess.kill('KILL',

  7. ruby - 如何在续集中重新加载表模式? - 2

    鉴于我有以下迁移:Sequel.migrationdoupdoalter_table:usersdoadd_column:is_admin,:default=>falseend#SequelrunsaDESCRIBEtablestatement,whenthemodelisloaded.#Atthispoint,itdoesnotknowthatusershaveais_adminflag.#Soitfails.@user=User.find(:email=>"admin@fancy-startup.example")@user.is_admin=true@user.save!ende

  8. ruby - 通过 ruby​​ 进程共享变量 - 2

    我正在编写一个gem,我必须在其中fork两个启动两个webrick服务器的进程。我想通过基类的类方法启动这个服务器,因为应该只有这两个服务器在运行,而不是多个。在运行时,我想调用这两个服务器上的一些方法来更改变量。我的问题是,我无法通过基类的类方法访问fork的实例变量。此外,我不能在我的基类中使用线程,因为在幕后我正在使用另一个不是线程安全的库。所以我必须将每个服务器派生到它自己的进程。我用类变量试过了,比如@@server。但是当我试图通过基类访问这个变量时,它是nil。我读到在Ruby中不可能在分支之间共享类变量,对吗?那么,还有其他解决办法吗?我考虑过使用单例,但我不确定这是

  9. ruby - RuntimeError(自动加载常量 Apps 多线程时检测到循环依赖 - 2

    我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("

  10. ruby - 简单获取法拉第超时 - 2

    有没有办法在这个简单的get方法中添加超时选项?我正在使用法拉第3.3。Faraday.get(url)四处寻找,我只能先发起连接后应用超时选项,然后应用超时选项。或者有什么简单的方法?这就是我现在正在做的:conn=Faraday.newresponse=conn.getdo|req|req.urlurlreq.options.timeout=2#2secondsend 最佳答案 试试这个:conn=Faraday.newdo|conn|conn.options.timeout=20endresponse=conn.get(url

随机推荐