Как я могу получить доступ к адресу инструкции, указанной в общей библиотеке, из файла, использующего библиотеку? - PullRequest
0 голосов
/ 19 ноября 2018

Я создал общую библиотеку с именем libSum.so и двумя c именами файлов file1.c и file2.c и использую libsum в обоих файлах c. Внутри libsum.so есть функция sum, которая выполняет операцию сложения. используя отладчик, я получил адрес инструкции по сборке функции sum. Теперь я хочу прочитать этот адрес из моего c-кода. Как я могу получить доступ к этому адресу?

1 Ответ

0 голосов
/ 19 ноября 2018

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

Если функция имеет внешнюю связь, но является закрытой для библиотеки, вы можете попытаться добавить свой собственный объект в библиотеку, и ваш код вернет адрес функции библиотеки.

Если функция статическая, стандартного способа не существует, если только адрес функции не сохраняется во внешне видимой переменной. Несколько различных хакерских способов:

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

Приведенные выше предложения предполагают, что ваша программа связана с библиотекой. Если ваша программа намеревается вызвать функцию из библиотеки, которая не была связана с вашей программой, то вы можете спросить о динамическом линковании. Опять же, функция должна иметь внешнюю связь и быть общедоступной для библиотеки. Если это так, в системах POSIX (то есть, в Linux) вы можете вызывать dlopen, чтобы открыть общую библиотеку, и dlsym, чтобы разрешить адрес открытого символа в библиотеке.

void *handle = dlopen("libSum.so", RTLD_LAZY);
void *sym = dlsym(handle, "sum");
void (*sum)();
_Static_assert(sizeof sym == sizeof sum);
memcpy(&sum, &sym, sizeof(sum));
...