我了解到,由于共享库不知道动态加载程序将它们放置在何处,因此它们必须依靠GOT来解析对全局数据的所有引用。例如,一个共享库有一个名为globe
的全局变量,假设mov eax,DWORD PTR [ecx-0x10]
包含GOT的地址和ecx
的偏移量是globe
。现在,可以说进程A使用了此共享库,紧随其后的是进程B。我知道共享库的代码可以在进程之间共享,但是数据不能共享,因为每个进程都可能根据其执行情况更改数据。因此,每个进程都会得到自己的GOT,这意味着,由于有了虚拟内存,地址0x10
将指向完全两个不同的GOT,具体取决于正在运行该代码段的进程。但是然后说,其中一个进程在其GOT中的偏移量ecx + 0x10
处加载了另一个具有不同全局数据成员的第二个共享库。如果两个库都位于相同的虚拟地址,那么使用这两个库的过程如何准确地访问每个库的全局数据?
答案 0 :(得分:0)
但是,然后说一个进程在其GOT中的偏移量0x10处加载了另一个具有不同全局数据成员的共享库。如果两个库都位于相同的虚拟地址,那么使用这两个库的过程如何准确地访问每个库的全局数据?
答案分为三个部分:
了解这一点的最好方法是编译两个简单的库和一个主要的二进制文件,然后检查各个GOT
节,并观察它们何时以及以何种方式更改。
您困惑的根源似乎是假设只有一个GOT
。事实并非如此:每个库都有自己的.got
节,编译器和运行时加载程序将对其进行排列,以使ecx
指向右边的.got
。
对于主要可执行文件,答案是“复制重定位”。
这是该主题的good article。