【问题标题】:How to get a pointer to a specific section of a dynamic library (Linux ELF)?如何获取指向动态库(Linux ELF)特定部分的指针?
【发布时间】:2012-11-14 01:33:56
【问题描述】:

second answer for this question 中可以看出,使用节的名称从程序内部获取指向程序特定节的指针非常简单。使用libelf,只需打开程序自己的文件,循环其中的所有部分(由Elf64_Shdr 结构表示),当部分名称与您想要的匹配时停止并使用存储在sh_addr 元素中的指针Elf64_Shdr 结构的。在这种情况下,获取想要的指针非常简单,因为它是在 ELF 可执行文件中定义的。

但是,假设您有一个使用动态库的程序,并且您需要获取指向该动态库的某个部分的指针。既然它的section的地址是在运行时定义的,那么如何获得指向动态库section的指针呢?

顺便说一句,动态库和主程序本身都有一个同名的部分(这是我需要获得指针的部分)。那么,在这种情况下,这两个具有相同名称的部分是否有可能在内存中相邻存储,所以我只需要获取指向主文件部分的指针(正如我在第一段中解释的那样)并添加一个偏移量到达动态库部分?

【问题讨论】:

  • 你可以从/proc//maps中获取起始地址,然后添加偏移量即可。
  • @Nick 好的,但是偏移量使用什么值?考虑到我可以使用libelf 获取起始地址,难道没有更优雅的方法吗?
  • 我什至不确定两个同名的部分,一个是主文件,另一个是库,是否相邻存储(它们肯定不是)。所以我什至不知道使用偏移量是否会起作用......
  • 你为什么要问?有时,使用dladdr 就足够了......

标签: c linux memory elf dynamic-library


【解决方案1】:

从程序内部获取指向程序特定部分的指针非常简单

不一定。段表在运行时实际上并不需要,并且可以完全剥离(只有段重要,而不是段)。

由于其节的地址是在运行时定义的,如何获得指向动态库节的指针?

该库与主可执行文件完全不同。主要区别在于库通常链接在地址0(主可执行文件不是),并且由运行时加载程序重定位到其他一些常量偏移量。

一旦您知道该偏移量,只需将其添加到节开头(您可以从 readelf -S foo.so 或 libelf 中找到),瞧:您已经获得了该节的运行时地址。

那么如何找到给定共享库的重定位?

不优雅的解决方案(Nick 已经建议)是解析/proc/self/maps

更好的解决方案是使用(glibc-specific)dl_iterate_phdr。文档here。你会想要使用dlpi_addr

【讨论】:

  • 太棒了,伙计!非常感谢您谈论dl_iterate_phdr。我会尝试使用它,因为它似乎正是我所需要的。但是,谈到您的第一个观察结果(“节表可以完全剥离”),所以您的意思是 Elf64_Shdr 结构的 sh_addr 元素并不总是保证是可用于到达节的指针,主文件?
  • @LuisAntonioBotelhoO.Leite 整个.shstrtab 部分可以被剥离。没有它,您将无法知道这些部分的名称是什么(或者更确切地说,曾经是)。
【解决方案2】:

很简单,这里举个例子:

#include <stdio.h>

int i __attribute__((section("my_section"))) = 2;
int j __attribute__((section("my_section"))) = 3;
int k __attribute__((section("my_section"))) = 5;

extern int __start_my_section;
extern int __stop_my_section;

int main(void)
{
    int *p = &__start_my_section;

    printf("%d\n", *p++); /* print k value */
    printf("%d\n", *p++); /* print j value */
    printf("%d\n", *p);   /* print i value */

   return 0;
}   

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-18
    • 1970-01-01
    • 1970-01-01
    • 2013-05-26
    • 2016-03-02
    • 1970-01-01
    相关资源
    最近更新 更多