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

时间:2017-04-25 14:18:04

标签: windows pointers dll

我正在研究Windows系统内部,问题只是猜测。

我了解到DLL是一种共享库,因此至少使用它的进程之间共享同一DLL的代码部分。 (通过将相同的页面条目添加到这些进程的页面表中)代码部分通常具有类似跳转表的内容,需要重新定位(即编写运行时虚拟地址以修复指针),然后才能执行它

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

我是对的吗?

1 个答案:

答案 0 :(得分:1)

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