Как динамически вставлять функции C из Python в Linux (без LD_PRELOAD)?

Как я, во время выполнения (no LD_PRELOAD), перехватывает/подключает функцию C, например fopen() в Linux, a la Detours for Windows? Я хотел бы сделать это с Python (следовательно, я предполагаю, что программа уже запускает CPython VM), а также перенаправляет код Python. Я в порядке, просто подключая общие библиотечные функции. Я также хотел бы сделать это, не изменяя способ запуска программы.

Одна идея состоит в том, чтобы свернуть собственный инструмент на основе ptrace() или переписать код, найденный с помощью dlsym() или в PLT, и настроить таргетинг на ctypes -генерированные функции C-вызова, но я думал, что попрошу здесь сначала. Спасибо.

Ответ 1

google-perftools имеет собственную реализацию Detour в src/windows/preamble_patcher *. В настоящий момент это только окна, но я не вижу причин, чтобы он не работал на какой-либо машине x86, за исключением того, что он использует функции win32 для поиска адресов символов.

Быстрое сканирование кода, и я вижу эти используемые функции win32, все из которых имеют версии Linux:

  • GetModuleHandle/GetProcAddress: получить адрес функции. dlsym может это сделать.
  • VirtualProtect: разрешить модификацию сборки. mprotect.
  • GetCurrentProcess: getpid
  • FlushInstructionCache (по-видимому, nop в соответствии с комментариями)

Не похоже, чтобы это скомпилировано и было связано с python, но я отправил сообщение разработчикам perftools и посмотрю, что они думают.

Ответ 2

Вы можете найти у одного из разработчиков ltrace возможность сделать это. См. этот пост, который включает полный патч, чтобы поймать динамически загруженную библиотеку. Чтобы вызвать его из python, вам, вероятно, понадобится создать модуль C.