【发布时间】: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 等等。