Вопрос или проблема
Насколько я понимаю, в /bin
у нас есть некоторые бинарные исполняемые файлы, которые являются просто скомпилированными программами на C. Из любопытства я решил поэкспериментировать с ними и открыл ls
с привилегиями sudo
, используя nano
, и добавил символ 0
в начале. Я сохранил файл и, к моему удовольствию, проверил, что действительно, выполнение команды ls
в терминале не работает.
Что я не ожидал, так это то, что после удаления этого символа, который я добавил, команда ls
все равно не работает и вызывает сегментационную ошибку.
Если файлы, содержащиеся в /bin
, не что иное, как машинный код из единиц и нулей, почему удаление символа, который мы добавили ранее, не приводит к программе, которая работает?
Редактирование бинарного файла с помощью текстового редактора может либо сработать, либо не сработать – на практике это обычно не срабатывает. Редактор может вносить различные изменения, такие как исправление окончаний строк (например, если последовательность байтов в файле содержала \r\n
, редактор может “исправить” это на \n
, или исправить вхождения только \n
на \r\n
), добавление завершающего перевода строки, если файл не заканчивался им, и т. д. Есть высокая вероятность того, что бинарный файл ls
был поврежден из-за некоторых из таких изменений. Вы можете сравнить вывод od -c
или hexdump
на оригинальных и измененных файлах, чтобы увидеть, что именно изменилось. И подумайте о том, чтобы использовать шестнадцатеричный редактор в будущем (Пожалуйста, порекомендуйте шестнадцатеричный редактор для оболочки) для редактирования не текстовых файлов.
Повторив ваш эксперимент и затем сравнив с оригиналом, используя binwalk
, показывает, что причина действительно заключается в преобразовании символа 0x0D
(CR) в 0x0A
(LF):
$ binwalk -Wi test /bin/ls OFFSET test /bin/ls -------------------------------------------------------------------------------- * 0x00000190 02 00 00 00 06 00 00 00 58 0D 02 00 00 00 00 00 |........X.......| \ 02 00 00 00 06 00 00 00 58 0A 02 00 00 00 00 00 |........X.......| * 0x000015B0 01 00 0D 00 03 00 03 00 03 00 03 00 03 00 03 00 |................| / 01 00 0A 00 03 00 03 00 03 00 03 00 03 00 03 00 |................| * 0x00001660 43 05 00 00 10 00 00 00 94 91 96 06 00 00 0D 00 |C...............| \ 43 05 00 00 10 00 00 00 94 91 96 06 00 00 0A 00 |C...............|
Вероятно, один из этих байтов был частью адреса памяти или инструкции, связанной с созданием адреса. Недопустимый адрес памяти затем приводит к сегментационной ошибке.
Когда вы открываете файл, nano
информирует об этом как (Преобразовано из формата Mac)
.
Вы можете отключить это преобразование и добавление завершающего перевода строки, используя параметры командной строки nano -LN
. С этими параметрами результат идентичен оригиналу, но редактирование бинарных файлов таким образом все равно подвержено повреждениям.
Ответ или решение
Корректная работа с двоичными файлами, такими как исполняемые программы в директории /bin
, требует особого внимания и использования специализированных инструментов. Вопрос, касающийся того, почему добавление и удаление символа в двоичном файле с использованием текстового редактора nano
вызывает сбои сегментации (segfault), привлекает к себе внимание, так как это имеет серьезные последствия для стабильности и безопасности системы.
Что происходит при редактировании двоичного файла?
Когда вы открываете двоичный файл, такой как ls
, в текстовом редакторе nano
, он предназначен для работы с текстом, а не с двоичными данными. Редактор может вносить непредвиденные изменения в файл, такие как:
-
Конвертация символов конца строки: Операционная система Windows использует комбинацию символов
CR
(Carriage Return, обозначается как0x0D
) иLF
(Line Feed, обозначается как0x0A
) для обозначения конца строки. Еслиnano
распознает двоичный файл как текстовый и он был создан на системе, использующей разные знаки конца строки, это может привести к нежелательной замене символа0x0D
на0x0A
, что и происходит в вашем случае. -
Добавление символа новой строки в конец файла: Если файл не заканчивается символом новой строки, редактор может добавить его, что также ведет к искажению данных.
Эти изменения могут не просто повредить структуру исполняемого файла, но также нарушить адресацию данных и инструкций. В результате программа, пытаясь обратиться к памяти по поврежденному адресу, вызывает сбой сегментации.
Почему удаление символа не восстанавливает работоспособность?
Когда вы изначально добавляете символ 0
в начало файла, это изменяет порядок байтов и структуру файла. Даже после удаления этого символа, вы рискуете оставить другие изменения, внесенные редактором, такие как замена CR
на LF
. Ваша исполняемая программа теперь может включать недопустимые последовательности байтов, которые могут быть восприняты как несуществующие или неверные адреса в памяти.
Исполняемые файлы, такие как ls
, имеют строгие ожидания в отношении структуры и порядка байтов. Малейшее искажение может привести к сбою при запуске, что вы и наблюдаете.
Рекомендации по работе с двоичными файлами
Вместо использования текстового редактора для изменения двоичных файлов, настоятельно рекомендуется:
-
Используйте шестнадцатеричные редакторы: Это специализированные инструменты, такие как
hexedit
илиbless
, которые позволяют редактировать двоичные файлы без ненужной интерпретации данных. -
Работайте с резервными копиями: Перед редактированием создавайте резервные копии исполняемых файлов, чтобы вы могли быстро восстанавливать их в случае повреждения.
-
Изучите побочные эффекты: Перед العمل с инструментами для редактирования изучите документацию, чтобы понять, как ваш выбор может повлиять на данные.
-
Используйте инструменты анализа: Такие утилиты, как
hexdump
,od
, иbinwalk
, помогут вам анализировать изменения в двоичных файлах и понять, какие изменения произошли.
Заключение
Редактирование исполняемых файлов должно выполняться с самим осторожностью и пониманием особых требований к структуре данных. Попытки изменять двоичные файлы текстовыми редакторами часто приводят к неработоспособности программ и сбоям сегментации. Важно использовать соответствующие инструменты и методики, чтобы избежать потери функциональности системы и обеспечить ее безопасное функционирование.