我正在编写我自己的Windows Loader版本(虽然是一个非常简单的版本),到目前为止,事情已经相当顺利。但是,在递归遍历已加载模块的Import表时,我遇到了一些麻烦。
对于大多数依赖项,事情很顺利,我可以简单地递归加载模块。但是,对于某些依赖项,这只会破坏目标进程。经过进一步调查,我意识到这是因为Windows并排组件。本质上,加载的PE中的依赖关系是目标进程中使用的模块的不同SxS版本。
在一种情况下,我加载的DLL引用了msvcr90.dll,但目标进程使用的是早期版本的运行时:msvcr71.dll。
现在,Windows加载器可以处理这个问题,所以显然有一种“正确”的方法可以做到这一点。我已经阅读了一些有关激活上下文的内容,但它们并没有真正帮助我理解这个问题。
调用LoadLibrary本身并不能将dll解析为正确的版本
LoadLibraryW(L"msvcr90.dll");
简单地返回0.有谁知道
a)如何检测导入是否为SxS程序集
b)如何解决导入过程的正确SxS版本。
我真的很难过如何做到这一点。我现在知道大部分PE文件格式,但我很确定SxS超出了PE结构的范围。
如果您需要更多信息,请发表评论。可执行文件没有外部清单,其嵌入式清单未指定运行时版本。但是,它确实在其工作目录中包含msvcr71.dll的副本,如果这对任何人都有帮助的话。
干杯。
答案 0 :(得分:2)
事实上,SxS依赖关系是PE结构的范围!如您所知,PE的导入表枚举依赖关系名称,但不包括其版本。处理这些依赖关系表时,Loader还会查看PE依赖图像的清单。如果清单记录了一个或多个库(例如msvcr90,advapi32,....),则加载程序会在winsxs文件夹中查找依赖项。 Here an article概述了此程序集以及如何使用C ++收集这些信息。