Определите, какие разделяемые вызовы lib в мою общую - PullRequest
2 голосов
/ 14 октября 2010

Я пытаюсь найти способ узнать, какой разделяемый lib вызывает мою разделяемую функцию lib.Сценарий такой:

Я использовал LD_PRELOAD для переопределения malloc.Внутри моего malloc я перенаправляю вызов непосредственно в настоящий malloc, но если вызов поступил из определенной разделяемой библиотеки, я хочу выполнить некоторую обработку, прежде чем переадресовать вызов.

Теперь разделяемая библиотека, чьи вызовы malloc Iнагрузка для обработки загружается и вызывается внешним исполняемым файлом в виде архитектуры плагинов.Я могу определить, какой исполняемый файл вызвал мой malloc, проверив глобальную переменную program_invocation_short_name, но я не хочу обрабатывать вызовы malloc, поступающие из исполняемого файла, который предоставляет архитектуру плагина, а только те, которые поступают из общей библиотеки плагина.

* 1006Я пытался использовать backtrace () и backtrace_symbols (), чтобы посмотреть, смогу ли я получить имя библиотеки плагинов или ее часть из обратной трассировки, но не повезло с этим.Я никогда не получаю там имя.

Может кто-нибудь подсказать, как это можно сделать?

С уважением,

Алекс.

Редактировать: я забыл упомянуть,Это на Linux.Мой плохой, я предполагал, что LD_PRELOAD отдал это.

Ответы [ 2 ]

1 голос
/ 28 октября 2010

Нет простого способа сделать это, но этот подход может работать для ваших нужд.

Я написал 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 равен 2921103 , а индекс загружающей ее библиотеки (т.е. libmiddle_man.so) на самом деле равен 2921103 + 1, то есть 2921104 .

У меня была возможность проверить этона нескольких машинах и некоторых встроенных устройствах, также работающих под управлением Linux.Подводя итог, можно выяснить, какая библиотека загрузила вашу, проанализировав информацию, доступную в / proc / pid / maps .

0 голосов
/ 14 октября 2010

В Windows вы можете использовать специальные API, такие как CreateToolhelp32Snapshot(), Module32First(), чтобы получить список всех общих библиотек, загруженных в ваш процесс.

Каждая такая библиотека будет находиться в диапазоне памяти, заданном modBaseAddr и modBaseSize членами структуры MODULEENTRY32.

Проверяя адрес возврата вызывающей стороны (может бытьсделано с некоторой простой встроенной сборкой) вы можете сравнить ее с диапазонами, которые точно идентифицируют вызывающего.

...