每个进程如何在共享库中拥有自己的全局数据副本

问题描述 投票:3回答:1

据我所知,由于共享库不知道动态加载器将在何处放置它们,因此它们必须依赖GOT来解析对全局数据的所有引用。例如,一个共享库有一个名为globe的全局变量,访问这个变量的可能方法就像这个mov eax,DWORD PTR [ecx-0x10],假设ecx包含GOT的地址,globe的偏移量是0x10。现在,假设进程A使用此共享库,紧接着是进程B.我知道共享库的代码可以在进程之间共享,但数据不能,因为每个进程都可能根据其执行情况更改数据。因此,每个进程都将获得它自己的GOT,这意味着,由于虚拟内存,地址ecx + 0x10将指向完全两个不同的GOT,具体取决于运行该段代码的进程。但随后说其中一个进程在其GOT中的偏移量0x10上加载了第二个共享库,其中包含一个不同的全局数据成员。如果两个库都在同一个虚拟地址,那么使用这两个库的进程究竟能够访问每个库的全局数据吗?

linux shared-libraries dynamic-linking got
1个回答
0
投票

但随后说其中一个进程在其GOT中的偏移量0x10处加载第二个共享库,其中包含不同的全局数据成员。如果两个库都在同一个虚拟地址,那么使用这两个库的进程究竟能够访问每个库的全局数据吗?

答案有三个部分:

  1. 每个库如何访问自己的全局变量?
  2. 每个库如何访问其他库的全局变量?
  3. 主可执行文件如何从两个库中访问全局变量?

理解这一点的最好方法是编译两个普通的库和一个主二进制文件,然后检查各种GOT部分,观察它们何时发生变化以及以何种方式变化。

您混淆的根源似乎是假设只有一个GOT。事实并非如此:每个库都有自己的.got部分,编译器和运行时加载器将安排它,以便ecx指向正确的.got

对于主可执行文件,答案是“复制重定位”。

这是关于这个主题的good article

© www.soinside.com 2019 - 2024. All rights reserved.