在共享库中查找变量的地址

时间:2014-01-20 14:15:23

标签: linux linker gdb shared-libraries

我想在变量的.so文件中找到该地址。我不知道if的名字,我只知道它是一个整数,我知道它的价值。我也知道,一旦动态链接器加载并链接了库,内存中的地址相对于库地址为0x6416A0。此偏移量大于动态库本身的大小。我只有库的二进制编译版本。

要查找.so文件中变量的地址,我使用objdump查看了它:

$ objdump -x /path/to/lib.so
Program Header:
LOAD off    0x0000000000000000 vaddr 0x0000000000000000 paddr 0x0000000000000000 align 2**21
     filesz 0x0000000000505fa9 memsz 0x0000000000505fa9 flags r-x
LOAD off    0x0000000000506000 vaddr 0x0000000000706000 paddr 0x0000000000706000 align 2**21
     filesz 0x00000000000db8f0 memsz 0x00000000001764c0 flags rw-
DYNAMIC off    0x00000000005210b0 vaddr 0x00000000007210b0 paddr 0x00000000007210b0 align 2**3
     filesz 0x00000000000003e0 memsz 0x00000000000003e0 flags rw-
EH_FRAME off    0x0000000000476898 vaddr 0x0000000000476898 paddr 0x0000000000476898 align 2**2
     filesz 0x0000000000014674 memsz 0x0000000000014674 flags r--
STACK off    0x0000000000000000 vaddr 0x0000000000000000 paddr 0x0000000000000000 align 2**3
     filesz 0x0000000000000000 memsz 0x0000000000000000 flags rw-
[...]

上面我只显示Program Header,但我要查找的地址不在可用部分的任何地址范围内。如您所见,使用的地址与0x7210b0一样大,但我的地址不在我看到的任何范围内。

由于链接器使用mmap加载.so文件的内容,我假设知道内存中的偏移量等于知道文件中的偏移量。显然这是错的。谁能帮助我理解它是如何工作的?有没有一种简单的方法将内存地址映射到文件地址?

1 个答案:

答案 0 :(得分:1)

如果您使用的是GNU libc的Linux系统,并且该变量是某个dynamically linked库的动态符号表中的已知名称,即ELF共享对象,并且如果你可以改变主程序的代码(或者由它动态链接的某个共享对象,可能正在播放LD_PRELOAD技巧)你可以使用dladdr(3)函数(给定一个指针,dladdr给出你是一个Dl_info结构,其符号和共享对象名称靠近给定的指针。)

由于动态链接的共享对象库通常mmap(2) - 在不可预测的地址(例如,因为ASLR),您需要在运行时执行此操作。 (另请参阅流程内的/proc/self/maps;阅读proc(5)等...)

阅读Drepper's paper: How to write Shared Libraries;注意VDSO ...

请注意,给定的*.so文件包含多个mmap个ed段,而且其某些(文件)数据 mmap - 编辑!使用pmap(1)查找。