共享库如何获得自己的基地址

Posted

技术标签:

【中文标题】共享库如何获得自己的基地址【英文标题】:how can shared library get its own base address 【发布时间】:2011-03-18 23:49:49 【问题描述】:

我有所有符号的偏移地址(通过 libelf 在其自己的二进制 .so 上执行获得)。现在,在运行时,我需要计算所有这些符号的绝对地址,为此我需要获取基地址(加载共享库的位置)并进行计算:

symbol_address = base_address + symbol_offset

?在 Windows 上我会使用传递给 DllMain 的参数,在 linux 中是否有一些等价物?

【问题讨论】:

您想要一个库函数来计算同一个库中对象的地址吗?您是否有理由不能像分配指针那样获取对象的地址? 我需要迭代二进制文件中的所有符号并获取它们的绝对地址以进行进一步计算,因此对于较大的二进制文件几乎不可能手动访问每个对象(更不用说来自 crt 的符号了)。所以现在我可以使用 libelf 获取所有符号的偏移量,只需要这个基地址来计算虚拟地址。 【参考方案1】:

在 Linux 上,dladdr() 在来自libfoo.so 的任何符号上都会给你

  void *dli_fbase;      /* Load address of that object */

更多信息here。

或者,dl_iterate_phdr can give 加载每个加载到当前进程中的 ELF 图像的地址。

两者都是GLIBC 扩展。如果您没有使用GLIBC,请告诉您使用的是什么,以便给出更合适的答案。

【讨论】:

【参考方案2】:

经过一番研究,我设法找到了通过描述符找到库加载地址的方法,该描述符由 dlopen() 函数返回。它是在这样的宏的帮助下执行的:

#define  LIBRARY_ADDRESS_BY_HANDLE(dlhandle) ((NULL == dlhandle) ? NULL :  (void*)*(size_t const*)(dlhandle))

【讨论】:

此答案不适用于预链接库。此外,最好表示为“((struct link_map *)dlhandle)->l_addr”

以上是关于共享库如何获得自己的基地址的主要内容,如果未能解决你的问题,请参考以下文章

如何在运行时读取共享库数据段开头的绝对加载地址?

如何获得IP地址?

虚拟地址

怎么查看笔记本电脑的ip地址

通过使用共享页面确定库地址绕过 Windows ASLR

微信支付开发 收货地址共享接口V2