【发布时间】:2014-01-20 14:15:22
【问题描述】:
我想在 .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 文件的内容,我假设知道内存中的偏移量相当于知道文件中的偏移量。显然这是错误的。谁能帮我理解它是如何工作的?有没有简单的方法将内存地址映射到文件地址上?
【问题讨论】:
-
如果您甚至不知道该变量的名称,那么您将很难找到它。这有点像说“有这个东西,我想找到它。它是红色的,但我不知道它叫什么。你能帮我找到它吗?”。说真的,您不能通过调整再次构建和链接库吗?你为什么要在图书馆里找到它呢?
-
@Phil_12d3 当然我不能构建和链接它——一些库是二进制的。问题不在于找到 something red:我确实知道链接后变量在内存中的地址。我不知道链接器实际上是如何加载库的,以及地址映射到文件的哪个物理部分。
-
@angainor 对不起,但你没有说你不能——这只是一个想法。我有很多库,也有它们的代码。
nm也不太可能有帮助,因为它只会显示地址、部分和名称。尽管可能是什么,但您也许可以做出有根据的猜测。 -
cat /proc/<pid>/maps的输出? -
@ninjalj Bingo - 这确实帮助我得到了我想要的东西。动态库被多次映射,其中一个内存范围确实包含我正在寻找的地址。谢谢!
标签: linux linker gdb shared-libraries