dlsym——获取被覆盖的符号

发布于 2024-12-18 22:47:58 字数 239 浏览 1 评论 0原文

我有一个动态加载库的应用程序,它动态加载库......

在Windows中,我能够迭代所有加载的模块,寻找我感兴趣的符号。不知道如何在Unix/Linux中做到这一点环境。我知道我可以使用 dlsym(dlopen(0, flag))dlsym(RTLD_DEFAULT / RTLD_NEXT) 作为前两个符号,并知道要搜索的模块的顺序 - - 我怎样才能更深入并获得给定符号的所有定义?

I have an application dynamically loading libraries which dynamically load libraries which...

In Windows, I'm able to iterate over all loaded modules looking for the symbol I'm interested in. Don't know how to do that in Unix/Linux environment. I know I may use dlsym(dlopen(0, flag)) or dlsym(RTLD_DEFAULT / RTLD_NEXT) for first two symbols and know the order of the modules to search in -- just how may I get deeper and get all definitions of given symbol?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

屋顶上的小猫咪 2024-12-25 22:47:58

要在分片对象中查找符号,请使用 dlopen 打开它。

 void* foobar = dlopen ("/usr/local/lib/foobar.so", RTLD_NOW);
 void* mysymbol = dlsym (foobar, "mysymbol");

更新 这是一个迭代所有名为“foo”的符号的程序。这不是 POSIX,而是 GNU 库。我几乎可以肯定 POSIX 不提供这样的功能。

#define _GNU_SOURCE 
#include <link.h>
#include <dlfcn.h>
#include <stdio.h>

void doit (const char* s)
{
    void* obj = dlopen (s, RTLD_LAZY);
    void* fcn = dlsym (obj, "foo");
    if (fcn)
        printf ("Object %s has 'foo' at addr %p\n", *s ? s : "(exe)", fcn);
}    
int cb (struct dl_phdr_info *info, size_t size, void *data)
{
    doit (info->dlpi_name);
    return 0;
}    
int main ()
{
    dl_iterate_phdr (cb, 0);    
    return 0;
}

这是输出:

Object (exe) has 'foo' at addr 0xb76f8418
Object (exe) has 'foo' at addr 0xb76f8418
Object /tmp/libfoo.so has 'foo' at addr 0xb76f8418
Object /tmp/libfoo1.so has 'foo' at addr 0xb76f5418
Object /tmp/libfoo2.so has 'foo' at addr 0xb76f2418

有一些重复,但这是一个小问题。

To find a symbol in a shard object, open it with dlopen.

 void* foobar = dlopen ("/usr/local/lib/foobar.so", RTLD_NOW);
 void* mysymbol = dlsym (foobar, "mysymbol");

Update Here's a program that iterates over all symbols named "foo". This is not POSIX but GNU libs. I am almost sure POSIX does not provide such capabilities.

#define _GNU_SOURCE 
#include <link.h>
#include <dlfcn.h>
#include <stdio.h>

void doit (const char* s)
{
    void* obj = dlopen (s, RTLD_LAZY);
    void* fcn = dlsym (obj, "foo");
    if (fcn)
        printf ("Object %s has 'foo' at addr %p\n", *s ? s : "(exe)", fcn);
}    
int cb (struct dl_phdr_info *info, size_t size, void *data)
{
    doit (info->dlpi_name);
    return 0;
}    
int main ()
{
    dl_iterate_phdr (cb, 0);    
    return 0;
}

Here's the output:

Object (exe) has 'foo' at addr 0xb76f8418
Object (exe) has 'foo' at addr 0xb76f8418
Object /tmp/libfoo.so has 'foo' at addr 0xb76f8418
Object /tmp/libfoo1.so has 'foo' at addr 0xb76f5418
Object /tmp/libfoo2.so has 'foo' at addr 0xb76f2418

There are some duplicates but this is a minor problem.

丶视觉 2024-12-25 22:47:58

回答自己的问题,使人们寻找解决方案的生活变得更轻松。
没有统一的方法,想要迭代加载的模块应该搜索以下命令/数据类型(邀请专家对此发表评论):

Windows:
MODULEENTRY32、CreateToolhelp32Snapshot、Module32First、Module32Next

Linux:
as nm的答案中描述,当找到正确的模块时,从回调返回非零(结束循环)。

AIX:loadquery(L_GETINFO,缓冲区,大小),struct ld_info。

HP-UX:
dlget、dlgetname(如果需要模块路径)。

Solaris:
ldinfo、Link_map。

此外,我建议 dlopen 模块并从新句柄获取符号,以增加库的引用计数,从而防止其被卸载。至少在 AIX 上,它可能会产生再次加载和初始化库的副作用,但在大多数情况下,它比尝试从卸载的库调用函数要好。

Answering own question to make the life of people searching for the solution easier.
There's no unified way, one wanting to iterate on loaded modules should search for the following commands/data types (the experts are invite to comment on that):

Windows:
MODULEENTRY32, CreateToolhelp32Snapshot, Module32First, Module32Next

Linux:
as described in n.m.'s answer, return non-zero from the callback when proper module found (ends the loop).

AIX:
loadquery(L_GETINFO, buffer, size), struct ld_info.

HP-UX:
dlget, dlgetname (if you need the module path).

Solaris:
ldinfo, Link_map.

Additionally, I'd recommend to dlopen the modules and get the symbol from a new handle to have library's reference count incremented which prevents it from being unloaded. At least on AIX it may have a side effect of the library loaded and initialized once again, but it's in most cases better than attempting to call a function from the unloaded library.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文