确定哪个共享库调用我的共享

发布于 2024-09-27 03:58:51 字数 512 浏览 0 评论 0原文

我试图找到一种方法来了解哪个共享库正在调用我的共享库函数。场景是这样的。

我已经使用 LD_PRELOAD 来覆盖 malloc。在我的 malloc 中,我将调用直接转发到真正的 malloc,但如果调用来自特定的共享库,我想在转发调用之前进行一些处理。

现在,我想要处理的对 malloc 调用的共享库由某种插件架构中的外部可执行文件加载和调用。我可以通过检查全局的program_inspiration_short_name变量来判断哪个可执行文件调用了我的malloc,但我不想处理来自提供插件架构的可执行文件的malloc调用,而只想处理来自插件共享库的malloc调用。

我尝试使用 backtrace() 和 backtrace_symbols() 来查看是否可以从回溯中获取插件库名称或其一部分,但没有成功。我从来没有得到那里的名字。

有人可以建议如何做到这一点吗?

问候,

亚历克斯。

编辑:我忘了提及。这是在 Linux 上。我的错,我以为 LD_PRELOAD 泄露了这一点。

Am trying to find a way of knowing which shared lib is calling into my shared lib function. The scenario is like this.

I have used LD_PRELOAD to override malloc. Inside my malloc I forward the call directly to the real malloc but if the call came from a particular shared lib I want to do some processing before I forward the call.

Now, the shared lib whose calls to malloc I want to handle is loaded and called by an external executable in a kind of plugin architecture. I can tell which executable called my malloc by checking the global program_invocation_short_name variable, but I don't want to process malloc calls coming from the executable that provides the plugin architecture but only those that come from the plugin shared lib.

I have tried using backtrace() and backtrace_symbols() to see if I can get the plugin library name or part of it from the back trace but no luck with this. I never get the name there.

Could someone suggest how this can be done?

Regards,

Alex.

Edit: I forgot to mention. This is on Linux. My bad, I had assumed the LD_PRELOAD gave that away.

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

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

发布评论

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

评论(2

腻橙味 2024-10-04 03:58:51

没有简单的方法可以做到这一点,但这种方法可能适合您的需求。

我编写了 3 个小应用程序,以便您可以按照我的说明进行操作。它们是:

  • app:将在您的系统上运行的二进制文件。从 libmiddleman.so 调用一个函数,该函数尝试通过 malloc()

源代码分配一些内存:gcc app.c -o app -L。 -lmiddle_man

//File: app.c
#include "libmiddle_man.h"    
#include <stdio.h>

int main()
{
    do_something();

    return 0;
}
  • libmiddle_man.so:导出一个仅调用 malloc() 的函数源代码

gcc libmiddle_man.c -o libmiddle_man.so -shared

//File: libmiddle_man.c
void do_something()
{
    int* tmp = malloc(sizeof(int));
}

以及:

//File: libmiddle_man.h
void do_something();
  • libfake_malloc.so:实现并导出我们的 malloc() 版本,该版本在终端

源代码上打印一些内容:gcc lbfake_malloc.c -o libfake_malloc.so -shared

//File: libfake_malloc.c
#include <stdio.h>
#include <unistd.h>

void* malloc(size_t size)
{
    printf("fake malloc()\n");

    printf("Process ID: %d\n", getpid());

    while(1)
    {
    }

    return NULL;
}

当您执行时使用 LD_PRELOAD=libfake_malloc.so ./app 的应用程序将输出以下内容:

fake malloc()
Process ID: 14230    (the PID will be different each time you run the application)

并且应用程序将挂在那里,因为我们需要它。我们将检查进程内存映射并确保 app 已加载我们的两个库。

因此,暂时将其留在那里并打开另一个终端。当您在进程列表中搜索此 PID 时,它将显示哪个应用程序正在使用 libfake_malloc.so。这不是我们的目标,但这是一个有趣的信息。

ps -aux | grep 14230

输出:

karl     14230 97.3  0.0   1648   396 pts/9    R+   13:57  10:20 ./app

记住将 14230 更改为应用程序返回给您的任何数字。接下来,我们将检查进程内存并验证两个库是否已加载。

cat /proc/14230/maps

显示:

00110000-00263000 r-xp 00000000 08:06 2158492    /lib/tls/i686/cmov/libc-2.11.1.so
00263000-00264000 ---p 00153000 08:06 2158492    /lib/tls/i686/cmov/libc-2.11.1.so
00264000-00266000 r--p 00153000 08:06 2158492    /lib/tls/i686/cmov/libc-2.11.1.so
00266000-00267000 rw-p 00155000 08:06 2158492    /lib/tls/i686/cmov/libc-2.11.1.so
00267000-0026a000 rw-p 00000000 00:00 0 
00584000-00585000 r-xp 00000000 08:07 2921104    /home/karl/workspace/shared_libs/who_called_my_shared/libmiddle_man.so
00585000-00586000 r--p 00000000 08:07 2921104    /home/karl/workspace/shared_libs/who_called_my_shared/libmiddle_man.so
00586000-00587000 rw-p 00001000 08:07 2921104    /home/karl/workspace/shared_libs/who_called_my_shared/libmiddle_man.so
00605000-00606000 r-xp 00000000 08:07 2921103    /home/karl/workspace/shared_libs/who_called_my_shared/libfake_malloc.so
00606000-00607000 r--p 00000000 08:07 2921103    /home/karl/workspace/shared_libs/who_called_my_shared/libfake_malloc.so
00607000-00608000 rw-p 00001000 08:07 2921103    /home/karl/workspace/shared_libs/who_called_my_shared/libfake_malloc.so
007e6000-007e7000 r-xp 00000000 00:00 0          [vdso]
0096a000-00985000 r-xp 00000000 08:06 2142529    /lib/ld-2.11.1.so
00985000-00986000 r--p 0001a000 08:06 2142529    /lib/ld-2.11.1.so
00986000-00987000 rw-p 0001b000 08:06 2142529    /lib/ld-2.11.1.so
08048000-08049000 r-xp 00000000 08:07 2921106    /home/karl/workspace/shared_libs/who_called_my_shared/app
08049000-0804a000 r--p 00000000 08:07 2921106    /home/karl/workspace/shared_libs/who_called_my_shared/app
0804a000-0804b000 rw-p 00001000 08:07 2921106    /home/karl/workspace/shared_libs/who_called_my_shared/app
b77b0000-b77b2000 rw-p 00000000 00:00 0 
b77c9000-b77cc000 rw-p 00000000 00:00 0 
bfb69000-bfb7e000 rw-p 00000000 00:00 0          [stack]

您会注意到 libfake_malloc.so 的 inode 是 2921103,而加载它的库(即 libmiddle_man.so)的 inode 实际上是 2921103+1,即 2921104强>。

我有机会在几台机器和一些也运行 Linux 的嵌入式设备上进行测试。总而言之,通过解析 /proc/pid/maps 上的可用信息,似乎可以发现哪个库已加载您的库。

There is no easy way to do that, but this approach might work for your needs.

I have coded 3 small applications so you can follow my instructions. They are:

  • app: the binary that will run on your system. Calls a function from libmiddleman.so that tries to allocate some memory through malloc()

source code: gcc app.c -o app -L. -lmiddle_man

//File: app.c
#include "libmiddle_man.h"    
#include <stdio.h>

int main()
{
    do_something();

    return 0;
}
  • libmiddle_man.so: exports a function that simply calls malloc()

source code: gcc libmiddle_man.c -o libmiddle_man.so -shared

//File: libmiddle_man.c
void do_something()
{
    int* tmp = malloc(sizeof(int));
}

and also:

//File: libmiddle_man.h
void do_something();
  • libfake_malloc.so: implements and exports our version of malloc() that prints something on the terminal

source code: gcc lbfake_malloc.c -o libfake_malloc.so -shared

//File: libfake_malloc.c
#include <stdio.h>
#include <unistd.h>

void* malloc(size_t size)
{
    printf("fake malloc()\n");

    printf("Process ID: %d\n", getpid());

    while(1)
    {
    }

    return NULL;
}

When you execute the application with LD_PRELOAD=libfake_malloc.so ./app it will output the following:

fake malloc()
Process ID: 14230    (the PID will be different each time you run the application)

and the application will hang there because we need it so. We will examine the process memory map and make sure that app has both loaded both of our libraries.

So leave it there for now and open another terminal. When you search for this PID on the process list it will show which application is using libfake_malloc.so. It's not what we are aiming for, but it's an interesting information.

ps -aux | grep 14230

outputs:

karl     14230 97.3  0.0   1648   396 pts/9    R+   13:57  10:20 ./app

Remember to change 14230 for whatever number the application returned to you. Next, we will examine the process memory and verify that both of out libraries were loaded.

cat /proc/14230/maps

displays:

00110000-00263000 r-xp 00000000 08:06 2158492    /lib/tls/i686/cmov/libc-2.11.1.so
00263000-00264000 ---p 00153000 08:06 2158492    /lib/tls/i686/cmov/libc-2.11.1.so
00264000-00266000 r--p 00153000 08:06 2158492    /lib/tls/i686/cmov/libc-2.11.1.so
00266000-00267000 rw-p 00155000 08:06 2158492    /lib/tls/i686/cmov/libc-2.11.1.so
00267000-0026a000 rw-p 00000000 00:00 0 
00584000-00585000 r-xp 00000000 08:07 2921104    /home/karl/workspace/shared_libs/who_called_my_shared/libmiddle_man.so
00585000-00586000 r--p 00000000 08:07 2921104    /home/karl/workspace/shared_libs/who_called_my_shared/libmiddle_man.so
00586000-00587000 rw-p 00001000 08:07 2921104    /home/karl/workspace/shared_libs/who_called_my_shared/libmiddle_man.so
00605000-00606000 r-xp 00000000 08:07 2921103    /home/karl/workspace/shared_libs/who_called_my_shared/libfake_malloc.so
00606000-00607000 r--p 00000000 08:07 2921103    /home/karl/workspace/shared_libs/who_called_my_shared/libfake_malloc.so
00607000-00608000 rw-p 00001000 08:07 2921103    /home/karl/workspace/shared_libs/who_called_my_shared/libfake_malloc.so
007e6000-007e7000 r-xp 00000000 00:00 0          [vdso]
0096a000-00985000 r-xp 00000000 08:06 2142529    /lib/ld-2.11.1.so
00985000-00986000 r--p 0001a000 08:06 2142529    /lib/ld-2.11.1.so
00986000-00987000 rw-p 0001b000 08:06 2142529    /lib/ld-2.11.1.so
08048000-08049000 r-xp 00000000 08:07 2921106    /home/karl/workspace/shared_libs/who_called_my_shared/app
08049000-0804a000 r--p 00000000 08:07 2921106    /home/karl/workspace/shared_libs/who_called_my_shared/app
0804a000-0804b000 rw-p 00001000 08:07 2921106    /home/karl/workspace/shared_libs/who_called_my_shared/app
b77b0000-b77b2000 rw-p 00000000 00:00 0 
b77c9000-b77cc000 rw-p 00000000 00:00 0 
bfb69000-bfb7e000 rw-p 00000000 00:00 0          [stack]

You will notice that the inode for libfake_malloc.so is 2921103 and the inode of the library that loaded it (i.e. libmiddle_man.so) is actually 2921103+1, which is 2921104.

I had the opportunity to test this on a few machines and some embedded devices also running Linux. To summarize, it seems possible to discover which library has loaded yours by parsing the information available on /proc/pid/maps.

妄司 2024-10-04 03:58:51

在 Windows 上,您可以使用特殊的 API,例如 CreateToolhelp32Snapshot()Module32First() 来获取进程中加载​​的所有共享库的列表。

每个此类库都将驻留在由结构 MODULEENTRY32modBaseAddrmodBaseSize 成员指定的内存范围中。

通过检查调用者的返回地址(可以通过一些简单的内联汇编来完成),您可以将其与范围进行比较,这将准确识别调用者。

On Windows you could use special APIs like CreateToolhelp32Snapshot(), Module32First() to obtain the list of all the shared libraries loaded in your process.

Each such library will reside in a memory range, specified by modBaseAddr and modBaseSize members of the structure MODULEENTRY32 .

By checking the return address of the caller (can be done with some simple inline assembly) you can compare it with there ranges, that would identify exactly the caller.

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