我想在变量的.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
文件的内容,我假设知道内存中的偏移量等于知道文件中的偏移量。显然这是错的。谁能帮助我理解它是如何工作的?有没有一种简单的方法将内存地址映射到文件地址?
答案 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)查找。