Действие по загрузке библиотеки исполняемого файла - PullRequest
0 голосов
/ 08 ноября 2019

Допустим, у меня есть исполняемый файл a.out. Он имеет общие библиотеки libcrypto.so, libmylib.so. Я хотел бы сделать некоторые действия при каждой загрузке этих библиотек. Есть ли какая-нибудь функция, к которой я могу добавить свой код? Поэтому я определю некоторую функцию внутри моего исполняемого файла, и она будет вызываться дважды для этого примера.

Я знаю __attribute__ ((constructor)), но она должна быть определена специально для каждой библиотеки, что невозможно.

Спасибо.

1 Ответ

1 голос
/ 08 ноября 2019

Я бы хотел предпринять некоторые действия при каждой загрузке этих библиотек. Есть ли какая-нибудь функция, к которой я могу добавить свой код?

Ваш код, нет. Но вы можете LD_PRELOAD a dlopen interposer.

Пример:

// foo.c
#include <stdio.h>

__attribute__((constructor))
void ctor()
{
  printf("In %s:%d\n", __FILE__, __LINE__);
}
// main.c
#include <dlfcn.h>
#include <stdio.h>

int main()
{
  printf(">>> main\n");
  dlopen("./foo.so", RTLD_LAZY);
  dlopen("./bar.so", RTLD_LAZY);
  printf("<<< main\n");

  return 0;
}
gcc -shared -fPIC -o foo.so foo.c
gcc -shared -fPIC -o bar.so foo.c
gcc main.c -ldl
./a.out
>>> main
In foo.c:6
In foo.c:6
<<< main

Теперь давайте добавим dlopen interposer:

// dlopen_preload.c
#define _GNU_SOURCE
#include <stdio.h>
#include <dlfcn.h>

typedef void* (*FN)(const char *, int);

void *dlopen(const char *fname, int flags)
{
  FN real_dlopen = (FN)dlsym(RTLD_NEXT, "dlopen");
  void *ret = real_dlopen(fname, flags);

  printf("my dlopen(%s, 0x%x) -> %p\n", fname, flags, ret);

  return ret;
}
gcc -shared -o dlopen_preload.so dlopen_preload.c
LD_PRELOAD=./dlopen_preload.so ./a.out
>>> main
In foo.c:6
my dlopen(./foo.so, 0x1) -> 0x565039670690
In foo.c:6
my dlopen(./bar.so, 0x1) -> 0x565039670c90
<<< main

Вуаля.

...