Предупреждение execve ошибка формата выполняемого файла

Обновлено: 04.07.2024

Хотя это не должно происходить при использовании официальных репозиториев apt-get, если вы загружаете программное обеспечение из Интернета и запускаете его, есть вероятность, что вы увидите страшные bash: ./nameOfProgram: невозможно выполнить двоичный файл: ошибка формата Exec. Эта ошибка, за которой обычно следует bash: ./nameOfProgram.sh: В доступе отказано или что-то в этом роде означает, что Ubuntu не может правильно взаимодействовать с загруженным вами двоичным файлом. Это потому, что, хотя это, по-видимому, допустимый двоичный файл Linux, он разработан для набора микросхем, отличного от того, который поддерживает ваше ядро.

Способ 1: использование команды arch

Если вы не знакомы с типом микропроцессора, который вы установили на своем компьютере, то сначала вы захотите использовать команду arch из командной строки. После выполнения этой команды вы увидите только одну строку вывода. Во многих случаях вы увидите i686, что означает, что вы используете 32-разрядный процессор и, следовательно, не можете запускать двоичные файлы x86_64. Если вместо этого вы видите amd64 или что-то подобное, то вы работаете на процессоре x86_64 и, по крайней мере, теоретически должны быть в состоянии запустить большинство 32-битных и 64-битных двоичных файлов. В отличие от Microsoft Windows, Ubuntu Linux фактически содержит надлежащие инструменты, позволяющие пользователям 644-битных наборов микросхем запускать 16-битные программы Windows в своей операционной системе во многих случаях.

Вы можете увидеть некоторые другие типы вывода, которые могут еще больше ограничить ваши возможности, когда дело доходит до запуска программного обеспечения. Ubuntu долгое время поддерживала архитектуру PowerPC, которая встречается на некоторых рабочих станциях, а также на многих компьютерах Classic Macintosh и более старых машинах OS X Macintosh. На самом деле вы все еще можете найти репозитории Ubuntu для этих архитектур, хотя сегодня они получают небольшую поддержку. Однако в этом случае вы, скорее всего, не сможете запустить много бинарных файлов Linux, которые вы загружаете из Интернета, за пределами официальных репозиториев. Это не означает, что Ubuntu не работает на этих машинах, хотя вы, возможно, захотите взглянуть на более легкий дистрибутив Lubuntu.

Способ 2: с помощью команды файла

Команда file определяет, какие файлы содержатся, и она обычно очень точная. Попробуйте определить нужный файл, набрав file nameOfProgram чтобы увидеть, если вы получите ELF 32-бит или ELF 64-бит в качестве вывода. Если он говорит вам, что это 64-битный двоичный файл ELF, и вы получили i686 в качестве вывода из команды arch, то вы не сможете разумно запустить его на своем компьютере. Если вы используете 64-битный микропроцессор, работающий под управлением 32-битной Ubuntu, то вы можете технически переустановить операционную систему, хотя это немного экстремальный шаг для запуска одной программы.


Существует также очень реальная возможность, хотя и незначительная, что вы можете вместо этого наткнуться на двоичный файл, который при попытке запустить его выдает ненужные символы в терминал, даже если вы запускаете сканирование вредоносных программ на нем. Эти символы обычно принимают форму блоков в форме ромба или, альтернативно, прямоугольных кубов с числовыми значениями в них. Некоторые компьютерные ученые называют последнее тофу и представляют значения символов Unicode, которые установленные вами шрифты не смогут отображать. Если терминал отображает их таким образом, то вы можете быть уверены, что это не ошибка шрифта или что-либо, имеющее отношение к вредоносному ПО. Скорее, это просто потому, что скомпилированный код операции микропроцессора внутри двоичного кода настолько чужд вашей системе, что он не знает, как интерпретировать часть кода.


В операционной системе Linux при запуске скаченного файла, либо при запуске самостоятельно скомпилированного файла вы можете столкнуться с ошибкой:


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

В самой ошибке вместо /путь/до/файла и ./program будет указан путь до файла программы, который вы хотите запустить.

Причинами данной ошибки могут быть:

  • попытка запустить 64-битный файл на 32-битной системе
  • файл скомпилирован для другой архитектуры (например, для ARM, а вы пытаетесь запустить его на ПК)
  • вы пытаетесь выполнить не исполнимый файл, а ссылку
  • файл размещён в совместной (shared) папке

Чтобы получить информацию о файле, который вы пытаетесь запустить, можно использовать утилиту file, после которой укажите путь до файла:

Здесь мы видим, что файл предназначен для 64-битной системы, об этом говорит запись 64-bit, для процессора с архитектурой x86-64.

Ещё один пример:

Этот файл для 32-битных систем, для процессора с архитектурой ARM EABI4.

Если вы не знаете, какой битности ваша система, то выполните команду:

Для 64-битных систем будет выведено x86_64, а для 32-битных – x86.

О разрядности дистрибутивов Linux и о программ

На компьютер с 32-битным процессором вы можете установить только 32-битную операционную систему и в ней запускать только 32-битные программы.

На компьютер с 64-битным процессором вы можете установить как 64-битную ОС, так и 32-битный Linux. В случае, если вы установили 64-битный дистрибутив Linux, то в нём вы можете запускать и 64-битные программы и 32-битные. А если вы установили 32-битный дистрибутив, то в нём возможно запускать только 32-битные программы.

Итак, если у вас 32-битная система, а файл для 64-битной системы или даже для ARM архитектуры, то у вас следующие варианты:

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

Запуск ARM файлов в Linux

Часто можно запустить исполнимые образы ARM на amd64 системах если установить пакеты binfmt-support, qemu, и qemu-user-static:

Заключение

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

int execve(const char * filename , char *const argv [], char *const envp []);

ОПИСАНИЕ

argv -- это массив строк, аргументов новой программы. envp -- это массив строк в формате key=value , которые передаются новой программе в качестве окружения (environment). Как argv , так и envp завершаются нулевым указателем. К массиву аргументов и к окружению можно обратиться из функции main (), которая объявлена как int main(int argc, char *argv[], char *envp[]) .

execve() не возвращает управление при успешном выполнении, а код, данные, bss и стек вызвавшего процесса перезаписываются кодом, данными и стеком загруженной программы. Новая программа также наследует от вызвавшего процесса его идентификатор и открытые файловые дескрипторы, на которых не было флага закрыть-при-exec (close-on-exec, COE). Сигналы, ожидающие обработки, удаляются. Переопределённые обработчики сигналов возвращаются в значение по умолчанию. Обработчик сигнала SIGCHLD (когда установлен в SIG_IGN) может быть сброшен или не сброшен в SIG_DFL.

Если текущая программа выполнялась под управлением ptrace, то после успешного execve() ей посылается сигнал SIGTRAP .

Если на файле программы filename установлен setuid-бит, то фактический идентификатор пользователя вызывавшего процесса меняется на идентификатор владельца файла программы. Точно так же, если на файле программы установлен setgid-бит, то фактический идентификатор группы устанавливается в группу файла программы.

Если исполняемый файл является динамически-скомпонованным файлом в формате a.out, содержащим заглушки для вызова разделяемых библиотек, то в начале выполнения этого файла вызывается динамический компоновщик ld.so (8), который загружает библиотеки и компонует их с исполняемым файлом.

Если исполняемый файл является динамически-скомпонованным файлом в формате ELF, то для загрузки разделяемых библиотек используется интерпретатор, указанные в сегменте PT_INTERP. Обычно это /lib/ld-linux.so.1 для программ, скомпилированных под Linux libc версии 5, или же /lib/ld-linux.so.2 для программ, скомпилированных под GNU libc версии 2.

ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ

При успешном завершении execve() не возвращает управление, при ошибке возвращается -1, а значение errno устанавливается должным образом.

КОДЫ ОШИБОК

EACCES Интерпретатор файла или скрипта не является обычным файлом. EACCES Нет прав на выполнение файла, скрипта или ELF-интерпретатора. EACCES Файловая система смонтирована с флагом noexec . EPERM Файловая система смонтирована с флагом nosuid , пользователь не является суперпользователем, а на файле установлен бит setuid или setgid. EPERM Процесс работает под отладчиком, пользователь не является суперпользователем, а на файле установлен бит setuid или setgid. E2BIG Список аргументов слишком велик. ENOEXEC Исполняемый файл в неизвестном формате, для другой архитектуры, или же встречены какие-то ошибки, препятствующие его выполнению. EFAULT filename указывает за пределы доступного адресного пространства. ENAMETOOLONG filename слишком длинное. ENOENT Файл filename , или интерпретатор скрипта или ELF-файла не существует, или же не найдена разделяемая библиотека, требуемая файлу или интерпретатору. ENOMEM Недостаточно памяти в ядре. ENOTDIR Компонент пути filename , или интерпретатору скрипта или ELF-интерпретатору не является каталогом. EACCES Нет прав на поиск в одном из каталогов по пути к filename , или имени интерпретатора скрипта или ELF-интерпретатора. ELOOP Слишком много символьных ссылок встречено при поиске filename , или интерпретатора скрипта или ELF-интерпретатора. ETXTBSY Исполняемый файл открыт для записи одним или более процессами. EIO Произошла ошибка ввода-вывода. ENFILE Достигнут системный лимит на общее количество открытых файлов. EMFILE Процесс уже открыл максимально доступное количество открытых файлов. EINVAL Исполняемый файл в формате ELF содержит более одного сегмента PT_INTERP (то есть, в нем указано более одного интерпретатора). EISDIR ELF-интерпретатор является каталогом. ELIBBAD ELF-интерпретатор имеет неизвестный формат.

СООТВЕТСТВИЕ СТАНДАРТАМ

ЗАМЕЧАНИЯ

SUID и SGID процессы не могут быть оттрассированы ptrace() d.

Linux игнорирует SUID и SGID биты на скриптах.

Результат монтирования файловой системы с опцией nosuid различается в зависимости от версий ядра Linux: некоторые ядра будут отвергать выполнение SUID/SGID программ, когда это должно дать пользователю те возможности, которыми он уже не обладается (и возвращать EPERM), некоторые ядра будут просто игнорировать SUID/SGID биты, но успешно производить запуск программы.

Я пытаюсь запустить программу, но ошибка происходит так:

Результатом file program было:

Я использую Ubuntu 14.04.2 (amd64) с VMware. Я тоже пробовал с Ubuntu i386, но результат был таким же.

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

Вы пытаетесь запустить исполняемый файл, скомпилированный для архитектуры ARM на архитектуре x86-64, что очень похоже на запрос вашего процессора, который говорит только по-английски, указывать направление на китайском.

Если вам нужно запустить этот исполняемый файл, у вас есть два варианта:

Получить версию исполняемого файла x86-64 (любым способом; если вам не удается получить версию исполняемого файла x86-64, но вы можете получить его исходный код, вы можете попытаться перекомпилировать его на виртуальной машине );

Установите Ubuntu Server for ARM вместо Ubuntu 14.04.2 (amd64). Для этого требуется либо физическая машина, работающая на архитектуре ARM, либо программное обеспечение для виртуализации, которое может эмулировать ее.

Это также может произойти, если вы попытаетесь запустить исполняемый файл x86-64 на 32-разрядной платформе.

В одном конкретном случае я скачал код Visual Studio и попытался запустить его на своей установке Ubuntu, но я не понял, что я установил 32-битную Ubuntu в эту виртуальную машину. Я получил эту ошибку, но после загрузки 32-разрядной версии, он работал без проблем.

Часто можно запустить исполняемый образ ARM в системе amd64, если вы установите пакеты binfmt-support , qemu и qemu-user-static :

qemu затем выполнит эмуляцию syscall при запуске исполняемого файла. Это работает для большинства двоичных файлов ARM, но есть некоторые, которые могут работать неправильно.

sudo apt-get install binfmt-support qemu qemu-user-static

Такая ошибка может возникнуть, если выполняются все следующие условия:

  • Исполняемый файл - это не файл, а ссылка
  • Вы запускаете запустить его внутри ВМ
  • Файл находится в общей папке
  • Ваш хост - Windows.

Если вы получили этот файл, скажем, в архиве - попробуйте распаковать его внутри виртуальной машины, в какой-то каталог внутри виртуального диска, а не в папку, сопоставленную, например, с жестким диском хост-машины. /myNewDir/

Это очень полезно. Для меня я создал ярлык (ссылку) на этот исполняемый файл, а затем вызвал ярлык ошибки.

Вы должны скомпилировать свой файл, используя соответствующую архитектуру ЦП (например, x86), и скопировать файл .exe на свой компьютер с Linux. Затем вы можете установить mono на вашем Linux-компьютере и выполнить следующую команду:

Если java в системе установлено более одного, это может произойти и не будет установлено по умолчанию. На Ubuntu14.04 LTS я мог решить ее, выполнив следующее и выбрав java нужное.

Я выбираю 2 и устанавливаю openjdk-8 по умолчанию. Который не показал Exec format error .

Это также может произойти, если двоичный файл использует реализацию libc, которая не является libc, например, musl. В эти дни эта конкретная проблема, скорее всего, встречается при попытке запуска двоичного файла с libc в контейнере Docker с изображением, основанным на alpine. Ничто не может быть сделано с самим двоичным файлом для поддержки обеих сред, потому что реализация libc всегда должна быть статически связана, то есть встроена непосредственно в двоичный файл, по причинам.

Читайте также: