【问题标题】:When a C application uses a shared library, is it possible to retrieve the bss and data sections of that shared library当 C 应用程序使用共享库时,是否可以检索该共享库的 bss 和数据部分
【发布时间】:2021-06-12 01:04:41
【问题描述】:

用 C 编写的应用程序,在 Ubuntu 18.04 上运行。
此应用程序与几个共享库链接,比如说 shared_lib1_external.so, 和 shared_lib1_internal.so。

我有这个独特的场景,最初使用 shared_lib1_external(在应用程序期间 启动),因此一些全局变量在这个 shared_lib1_external 中被初始化。
但随后启动完成后,需要使用shared_lib1_internal进行后续使用。 现在这给我们留下了 shared_lib1_internal,它没有正确初始化全局变量。

澄清一下,当我说全局符号时,我只对获取全局变量感兴趣, 不是库中的全局函数。 例如:
int global_counter = 0;
int global_array[10];

现在启动完成后,我确实可以选择使用 dlopen(打开 shared_lib_external.so),然后使用 dlsym(shared_lib_external 的句柄,“global_symbol_name”)来获取全局符号。
但这可能很乏味,因为有几个全局变量,但更重要的是,还有一些静态变量,它们是库本地的,但在启动期间被初始化,并在运行时使用。现在我们无法通过 dlsym 获取静态符号,这是另一个问题。
例如,静态变量如下:
静态 int local_counter;

当我进行对象转储时:
objdump -t shared_lib1_internal.so,
静态符号和全局符号都显示在 .data 部分的 .bss (OR) 中,具体取决于变量是否已初始化。

所以问题是,是否有一种编程方式可以在我的 C 应用程序中执行以下步骤:
应用程序启动完成后,C应用程序要执行的步骤如下:
Step1-> 将 shared_lib1_external.so 的整个 .bss 和 .data 部分检索到应用程序的内存中。
Step2-> 将在 Step1 中检索到的整个 .bss 和 .data 部分复制到相应的
shared_lib1_internal.so 中的部分

【问题讨论】:

  • 我想你是在问一个 Linux 进程是否可以偷偷窥探另一个 Linux 进程的内存。否 :) 如果您问:我能否以编程方式获取 objdump 显示给我的有关对象模块的相同信息:是的。
  • 你可能误会了什么;当您第一次dlopen 一个库时,它的全局变量会“正确初始化”。也许您希望使用dlmopen(LM_ID_NEWLM,...),它允许一个共享对象的多个独立实例。
  • @paulsm4,试图以编程方式获取相同的信息,objdump 显示。至于 API,除了 dlsym,还有 dladdr 和 dlinfo,但不知道如何获取整个 .bss 和 .data 部分。假设 .bss 和 .data 部分是连续的而不是分布的。或者,是否有其他方式,我不需要手动将符号名称传递给 dlsym,而是查询并获取符号的链接列表。在我的用例中,调用这些 API 以获取 .bss 和 .data 信息的过程也将链接到这些相同的共享对象。是否有任何 API 可以帮助获取此信息
  • @user3622275 - 明白了。强烈建议:“使用源代码”。下载“binutils”源代码,适配objdump.c:ftp.gnu.org/gnu/binutils。这是 objdump.c:github.com/CyberGrandChallenge/binutils/blob/master/binutils/…。你会注意到它依赖于很多其他的东西,比如DWARF。但是你绝对可以实现你的目标。祝你好运!
  • @paulsm4,感谢您的意见。快速浏览了代码,似乎有相当多的代码需要理解。将需要一些时间和精力来弄清楚如何使用它来实现我的目标。有趣的是,在 objdump.c 中,他们没有使用 apis like-> dlopen、dlsym、dladdr、dlinfo 等等。

标签: linux shared dlsym


【解决方案1】:

正如我上面所说的:

强烈建议:“使用源代码”。

下载“binutils”源代码,并适配objdump.c: ftp.gnu.org/gnu/binutils.

这是 objdump.c: https://github.com/CyberGrandChallenge/binutils/blob/master/binutils/objdump.c.

你会注意到它依赖于很多其他的东西,比如 DWARF。但是你可以 绝对实现你的目标。

我并不是要求你一定理解所有的 binutils。这个想法是您的应用可以使用与 objdump.c 相同的 API。

碰巧主要是 binutils API(与 dlopen 等 API 相比)。换句话说:

  1. 下载binutils源码,验证能否成功构建。至少,您需要一些 binutils 头文件。
  2. 确保您的 Linux 发行版上安装了 binutils(以便您可以根据需要在自己的应用中使用 binutils 库)。
  3. 创建一个小的 C 语言“hello world”,它可以读取目标文件的 .bss 和 .data 部分,就像您希望您的应用执行的那样。
  4. 成功构建并运行您的“hello world”。
  5. 最后,将您学到的知识应用到您的应用中。

祝你好运!请发回您找到的内容!

【讨论】:

  • 感谢您列出这些步骤,这很有帮助。 dl* apis 的参考代码很容易找到,例如 dlopen、dlsym..etc,并且我使用过 dl* apis,所以有一些熟悉。在这种情况下,需要弄清楚objdump.c,并找出api来检索每个符号。同样对于我的项目,我们不能使用 GPL 代码,并且 objdump.c 具有 GPL 许可证。我们更喜欢 APACHE 或 BSD 许可证。无论如何,我也在考虑另一种方法。如果我尝试您描述的选项,将发布我的发现。
猜你喜欢
  • 1970-01-01
  • 2011-08-27
  • 1970-01-01
  • 2015-09-30
  • 1970-01-01
  • 2011-12-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多