windows - 是否保证在每个使用它的进程中将相同的 DLL 映射到相同的虚拟地址?

标签 windows pointers dll

我正在研究 Windows 系统内部结构,这个问题只是一个猜测。

我了解到 DLL 是一种共享库形式,因此至少同一 DLL 的代码部分在使用它的进程之间共享。 (通过在这些进程的页表中添加相同的页条目)代码部分通常有类似跳转表的东西,需要在准备执行之前重新定位(即写入运行时虚拟地址以修复指针) .

假设相同的 DLL aa.dll映射到不同虚拟地址的两个不同进程中。 (例如 a.exe 0x00400000 b.exe 0x00410000)相同的指针(在 .text+0x100 处)将被固定到不同的地址。 (例如 a.exe 0x00400100 b.exe 0x004100100)。因此,我们必须复制代码部分并对其进行更改以适应一个过程。那么代码段如何共享呢?

我对吗?

最佳答案

回答我自己的问题。第一次加载 DLL 时,Windows 会尝试将它加载到不需要重定位的首选地址(即由于代码段位于 x 处而修复地址)。如果无法在首选地址加载它,则会在由 DLL 文件本身(不是交换文件)备份的空闲地址分配虚拟页面,但标记为 Copy-On-Write。现在 Windows 必须使用重定位表修复汇编代码。希望只需要修复一小部分代码,并且每个更改的代码段都会在写入时复制并放入物理内存中的某处。
每次进程无法在首选地址加载 DLL 时,我相信这个过程会发生。这就是为什么有时需要重新定位流行的 DLL 以便它们的首选地址不会冲突的原因。

关于windows - 是否保证在每个使用它的进程中将相同的 DLL 映射到相同的虚拟地址?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43613245/

相关文章:

windows - 是否有必要在所有 Windows 操作系统及其所有版本上测试我的应用程序?

c++ - IGraphBuilder::RenderFile() 因 VFW_E_BAD_KEY 失败 - 0x800403f2

c++ - 危险类型转换?

c++ - 将 NuGet Boost DLL 自动复制到输出目录

c# - Unity 内部编译器错误与自定义 dll

c++ - InternetReadFile 填充缓冲区,但返回读取的零字节

html - 从 html 文件中删除 br 标签

c - * 和 & 符号的含义

c - 链表插入节点什么都不显示

c# - C# 库是否有 OnLoad 事件?