Если функция имеет внешнюю связь и является общедоступной для библиотеки, использование имени функции в выражении приведет к адресу функции.
Если функция имеет внешнюю связь, но является закрытой для библиотеки, вы можете попытаться добавить свой собственный объект в библиотеку, и ваш код вернет адрес функции библиотеки.
Если функция статическая, стандартного способа не существует, если только адрес функции не сохраняется во внешне видимой переменной. Несколько различных хакерских способов:
- Если вам нужно вызвать функцию, вы можете просто создать свою реализацию. Если вам доступен источник файла, и лицензия на программное обеспечение допускает это, вы можете просто создать новую библиотеку, состоящую только из этой функции.
- Если вы хотите перекомпилировать саму оригинальную библиотеку, вы можете определить функцию с внешней связью, которая может вернуть вам адрес функции.
- Если вы можете вызвать сигнал (например, исключение с плавающей запятой или ошибку сегментации) во время вызова функции, вы можете попытаться захватить адрес функции путем сканирования в обратном направлении через стек вызовов из обработчика сигнала. .
Приведенные выше предложения предполагают, что ваша программа связана с библиотекой. Если ваша программа намеревается вызвать функцию из библиотеки, которая не была связана с вашей программой, то вы можете спросить о динамическом линковании. Опять же, функция должна иметь внешнюю связь и быть общедоступной для библиотеки. Если это так, в системах 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));