我想在.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-
[...]
上面我只显示了程序头
,但是我要查找的地址不在可用部分的任何地址范围内。如您所见,使用的地址与 0x7210b0
一样大,但我的地址不在我看到的任何范围内。
由于链接器使用mmap
来加载.so
文件的内容,我假设知道内存中的偏移量就相当于知道文件中的偏移量。显然这是错误的。谁能帮助我理解它是如何工作的?有没有一种简单的方法将内存地址映射到文件地址?
最佳答案
如果您使用的是 GNU libc 的 Linux 系统,并且如果该变量是某些 dynamically linked 的动态符号表中的已知名称图书馆,即 ELF共享对象,如果您可以更改主程序的代码(或由它动态链接的某些共享对象,也许玩 LD_PRELOAD
技巧),您可以使用 dladdr(3)函数(给定一个指针,dladdr
为您提供一个 Dl_info
结构,其中符号和共享对象名称接近给定指针)。
由于动态链接的共享对象库通常是mmap(2) -ed 在不可预测的地址(例如,由于 ASLR ),您需要在运行时执行此操作。 (另请参阅进程内部的 /proc/self/maps
;阅读 proc(5) 等...)
阅读Drepper's paper: How to write Shared Libraries ;请注意VDSO ...
请注意,给定的 *.so
文件具有多个 mmap
编辑段,并且其某些(文件)数据不是 mmap
编辑!使用pmap(1)来找出答案。
关于linux - 查找共享库中变量的地址,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21236263/