Когда я могу редактировать строки в исполняемом двоичном файле?

11

У меня есть исполняемый двоичный файл; давайте назовем это a.out. Я вижу, что бинарный файл содержит строки

$ strings a.out
...
/usr/share/foo
....

Мне нужно изменить строку /usr/share/fooна /usr/share/bar. Могу ли я просто заменить строку на sed?

sed -i 's@/usr/share/foo@/usr/share/bar@' a.out

Это выглядит как безопасная вещь. Будет ли это работать, когда строки не одинаковой длины?

Мартин Вегтер
источник

Ответы:

17

Я не знаю, будет ли ваша версия sedочищена в двоичном формате или если она захлебнется тем, что она считает действительно длинными строками ввода, но, исключая эти проблемы, редактирование строки на месте должно работать. Чтобы увидеть, работает ли это, сравните старую и новую версии с cmp -l. Он должен сказать вам, являются ли единственные три различия между этими двумя файлами эти 3 байта.

Редактирование строк в скомпилированном исполняемом файле действительно будет работать, если строки имеют одинаковую длину, но почти всегда будет работать и при сокращении строки из-за способа, которым строки работают в C. В строках C все после NULтерминатора не считается, поэтому, если вы напишите новый NULтерминатор перед позицией старого, вы фактически сократите строку.

В общем, вы не можете удлинить строку с помощью этого хака.

Celada
источник
Как насчет сокращения строки чем-то вроде sed -i 's@longstring@foo@' a.out? Это сделает весь двоичный файл меньше на 7 байтов. Разве это не повредит двоичный файл?
Мартин Вегтер
Да, это повредит двоичный файл. Вот почему вы должны перевести строку на одну точно такую ​​же длину, но установить NULтерминатор на более раннюю позицию, как я объяснил (хотя, может быть, слишком кратко). Проблема в том, что у вас не может быть NULбайта в командной строке, поэтому вы должны поместить свою sedпрограмму в файл и обратиться к нему с помощью -f. С другой стороны, безопаснее было бы использовать инструмент, предназначенный для работы с двоичными данными, а sedне для работы с текстовыми данными.
Селада
2
Хороший ответ. sed может делать много вещей, но, в общем, для этого и были придуманы бинарные редакторы. Их может быть сложно использовать при навигации по большому двоичному файлу, но они позволят вам менять вещи побайтно. Я использую, hexeditкогда мне нужно проверить или изменить двоичный файл. Вы можете использовать, strings -t x file | lessчтобы найти смещения (для печати) строк, которые вы хотите изменить, прежде чем переходить в редактор.
Джо
Допустим, в моей C-программе есть строка: «Меня зовут Mr Robot», и я хочу заменить «was» на «is», тогда заполнение \0должно быть выполнено осторожно, потому что, если замена делает это: «Мое имя is \ 0 Mr Robot ", то при выполнении операций со строкой символ '\ 0' создаст проблемы, так как длина будет непреднамеренно уменьшаться.
Нехал Дж Вани
@NehalJWani нет, в этом случае вам придется сдвигать всю оставшуюся часть строки вперед на один байт, чтобы ваш новый, дополнительный завершающий NULконец шел рядом с существующим NUL.
Селада