Использование dlopen() в исполняемом файле

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

dlopen([...]/testprogram, 1): no suitable image found. Did find: [...]/testprogram: can't map

Это не удивительно, поскольку dlopen предназначен для использования с библиотеками, а не с исполняемыми файлами. Есть ли способ получить dlopen и dlsym для работы с исполняемыми файлами? Если нет, есть ли альтернативный способ достижения одного и того же?

Ответ 1

Вы не можете открывать исполняемые файлы в качестве библиотек. Точка входа исполняемого файла попытается повторно инициализировать библиотеку C и взять на себя указатель brk. Это повредит вашу кучу malloc. Кроме того, исполняемый файл, вероятно, будет отображаться по фиксированному адресу без перестановки, и если этот адрес перекрывается с чем-либо уже загруженным, его также невозможно сопоставить по этой причине.

Вам нужно реорганизовать другую программу в библиотеку или добавить RPC-интерфейс в другую программу.

Обратите внимание, что это не обязательно относится к исполняемым файлам PIE. Однако, если исполняемый файл специально не предназначен для dlopen() ed, это небезопасно, поскольку main() не будет запущен, и любая инициализация, выполненная в main(), поэтому не будет выполняться.

Ответ 2

В некоторых ELF-системах (особенно Linux) вы можете dlopen() исполняемые файлы PIE. При использовании GCC просто скомпилируйте исполняемый файл с помощью -fpie или -fpie и привяжите его к -pie и экспортируйте соответствующие символы с помощью --dynamic-list или -rdynamic (более подробно объясняется в этот другой ответ SO.

Ответ 3

Чтобы добавить возможность загрузки исполняемых файлов через dlopen, зарегистрировано как отказавшееся glibc RFE (Request For Enhancement). Подробный взгляд на RFE и возможный подход для некоторых особых случаев можно найти на

[http://sourceware.org/bugzilla/show_bug.cgi?id=11754] [1]

Исключая PIE, для реализации такой функциональности было бы много проблем за кулисами.

Ответ 4

Инструмент здесь, чтобы сделать именно это, обрабатывает ASLR/PIE и не ASLR/PIE. Компиляция на x86, ARM и MIPS (только 32 бит). Отредактируйте Makefile для установки параметра ARCH.

http://rtfc.org.uk/cliapi.html

Это мой инструмент, но он, похоже, делает то, что вы хотите. Дайте мне знать, если это не сработает для вас.

Я ценю, как поздно я нахожусь на этой вечеринке, но эй.