解析 PE SxS 导入窗口

Resolving PE SxS imports Windows

本文关键字:窗口 导入 SxS PE 解析      更新时间:2023-10-16

我正在编写自己的Windows加载程序版本(尽管是一个非常简单的版本),到目前为止,事情进展得相当顺利。但是,在递归地浏览加载模块的导入表时,我遇到了一个小障碍。

对于大多数依赖项,事情进展顺利,我可以简单地递归加载模块。但是,对于某些依赖项,这只会破坏目标进程。经过进一步调查,我意识到这是因为Windows并行程序集。实质上,加载的 PE 中的依赖项是目标进程中使用的模块的不同 SxS 版本。

在一个案例中,我加载的 DLL 引用了 msvcr90.dll,但目标进程使用的是早期版本的运行时:msvcr71.dll。

现在,Windows加载程序可以很好地处理这个问题,所以显然有一种"正确"的方法可以做到这一点。我已经阅读了一些关于激活上下文的内容,但它们并没有真正帮助我掌握这个问题。

调用加载库本身也不会将 dll 解析为正确的版本

LoadLibraryW(L"msvcr90.dll");

只需返回 0。有谁知道

a) 如何检测导入是否为 SxS 程序集

b) 如何将导入解析为正确的 SxS 版本以进行该过程。

我真的不知道该怎么做。我现在从研究中知道大部分 PE 文件格式,但我很确定 SxS 超出了 PE 结构的范围。

如果您需要更多信息,请发表评论。可执行文件没有外部清单,其嵌入的清单未指定运行时版本。但是,它确实在其工作目录中包含 msvcr71.dll 的副本,如果这对任何人有帮助的话。

干杯。

事实上,SxS 依赖项属于 PE 结构的范围!如您所知,PE 的导入表枚举了依赖项名称,但不枚举其版本。处理这些依赖项表时,加载程序还会查看 PE 相关映像的清单。如果清单记录了一个或多个库(例如 msvcr90、advapi32,....),加载程序会在 winsxs 文件夹中查找依赖项。这里有一篇文章概述了此程序集以及如何在C++中收集这些信息。