Я понимаю, что скрипт не может быть запущен, если он не читается (даже если он исполняемый), потому что его должен прочитать читатель.
Но почему на linux можно запустить нечитаемый двоичный файл (я использую gcc, чтобы скомпилировать мой код в ./my_exe
и установить для него разрешение 0100)? Выполнение двоичного файла всегда вызывает некоторое чтение, верно? Тогда я читаю это Можно ли прочитать исполняемый файл? , но у меня все еще есть некоторые вопросы.
execve (2) говорит мне, что ядро вызовет /lib/ld-linux.so.2
для запуска программы (я использую readelf для проверки, у него есть сегмент INTERP, который равен /lib64/ld-linux-x86-64.so.2
), поэтому я думаю, /lib64/ld-linux-x86-64.so.2
- загрузчик ELF пользовательского пространства (который выполняет динамическое связывание и mmap ELF в память). Так как я не могу читать ELF, я думаю, что я не должен быть в состоянии запустить его, потому что для запуска требуется чтение GOT, чтобы выполнить динамическое связывание. Оказывается, я действительно не могу запустить его как /lib64/ld-linux-x86-64.so.2 my_exe
. Я просто получаю сообщение, что он не может загрузить общий объект. Но когда я запускаю его прямо из bash, например ./my_exe
, он запускается успешно.
Мой вопрос: поскольку выполнение ELF включает ld-linux-x86-64.so.2
, почему моя скомпилированная программа с разрешением 0100 может быть запущена напрямую? ld-linux-x86-64.so.2
не должен быть в состоянии прочитать его, поэтому он не должен уметь читать GOT и выполнять динамическое связывание. Так почему же я запустил его напрямую?