查找共享库中变量的地址 [英] Finding address of variable in shared library

查看:247
本文介绍了查找共享库中变量的地址的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



要在 .so file我使用 objdump 来查看它:
$ b

  $ objdump -x /path/to/lib.so 
程序标题:
LOAD off 0x0000000000000000 vaddr 0x0000000000000000 paddr 0x0000000000000000 align 2 ** 21
filesz 0x0000000000505fa9 memsz 0x0000000000505fa9标志rx
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--
堆栈关闭0x0000000000000000 vaddr 0x00000000000000 00 paddr 0x0000000000000000 align 2 ** 3
filesz 0x0000000000000000 memsz 0x0000000000000000 flags rw-
[...]

以上我只显示了程序头,但我正在查找的地址不在可用部分的任何地址范围内。正如你所看到的,使用的地址与 0x7210b0 一样大,但我的地址不在我看到的任何范围内。



由于链接器使用 mmap 来加载 .so 文件的内容,我假设知道偏移量在内存中相当于知道文件中的偏移量。显然这是错误的。任何人都可以帮我理解这是如何工作的?有没有一种简单的方法可以将内存地址映射到文件地址?

解决方案

一个href =http://www.gnu.org/software/libc/ =nofollow> GNU libc ,如果该变量是某个动态链接库,即 ELF 共享对象,并且如果您可以更改主程序的代码(或由它动态链接的某个共享对象,可能会播放 LD_PRELOAD 技巧),您可以使用 dladdr(3)功能(给定一个指针, dladdr 为您提供了一个 Dl_info 结构,符号和共享对象名称接近给定的指针) / p>

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

阅读 Drepper的论文:如何编写共享库 ;注意 VDSO ...



注意给定的 *。so 文件有几个 mmap -ed段,并且它的一些(文件) data not mmap -ed!使用 pmap(1)找出答案。


I would like to find the address in the .so file of a variable. I do not know the name of if, I only know that it is an integer, and I know the value of it. I also know that once the library is loaded and linked by the dynamic linker the address in the memory is 0x6416A0 relative to the library address. This offset is larger than the size of the dynamic library itself. I only have the binary, compiled version of the library.

To find the address of the variable in the .so file I looked at it using 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-
[...]

Above I only showed the Program Header, but the address I am looking for is not in any address range of the available sections. As you see, addresses used are as large as 0x7210b0, but my address is not in any of the ranges I see.

Since the linker uses mmap to load the contents of the .so file, I assumed that knowing the offset in the memory is equivalent to knowing the offset in the file. Apparently this is wrong. Could anyone help me understand how that works? Is there a simple way to map the memory address onto the file address?

解决方案

If you are on a Linux system with a GNU libc, and if the variable is a known name inside the dynamic symbol table of some dynamically linked library, i.e. ELF shared object, and if you can change the code of the main program (or some shared object dynamically linked by it, perhaps playing LD_PRELOAD tricks) you could use the dladdr(3) function (given a pointer, dladdr gives you a Dl_info structure with symbol and shared object names close to the given pointer).

Since dynamically linked shared object libraries are often mmap(2)-ed at non predictable addresses (e.g. because of ASLR) you need to do that at runtime. (See also /proc/self/maps from inside your process; read proc(5) etc...)

Read Drepper's paper: How to write Shared Libraries; be aware of VDSO...

Notice that a given *.so file has several mmap-ed segments, and that some of its (file) data is not mmap-ed! Use pmap(1) to find out.

这篇关于查找共享库中变量的地址的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆