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


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термінатор перед позицією старого, ви ефективно вкоротите рядок.

Взагалі, ви не можете подовжити рядок, використовуючи цей хак.


А як із скороченням струни чимось на кшталт sed -i 's@longstring@foo@' a.out? Це зробить весь двійковий на 7 байт, чи це не пошкодить двійкове?
Мартін Вегтер

Так, це зіпсує двійкове. Ось чому ви повинні перевести рядок на одну і ту ж довжину, але встановити NULтермінатор на більш ранній позиції, як я пояснив (хоча, можливо, занадто коротко). Проблема полягає в тому, що ви не можете мати NULбайт у командному рядку, тому вам доведеться помістити свою sedпрограму у файл і звернутися до неї -f. З іншого боку, більш безпечним є використання інструменту, призначеного для роботи з бінарними даними, замість sedяких призначений для роботи з текстовими даними.
Селада

2
Гарна відповідь. sed може робити багато речей, але, загалом, саме для цього були винайдені двійкові редактори. Вони можуть бути складними для використання під час навігації у великому двійковому файлі, але вони дозволять вам змінити байт на байт. Я використовую, hexeditколи мені потрібно перевірити або змінити двійковий файл. Ви можете використовувати strings -t x file | lessдля зміщення рядків (для друку) рядків, які ви хочете змінити, перш ніж перейти до редактора.
Джо

Скажімо, у моїй програмі C є рядок: "Мене звали містер Робот", і я хочу замінити "було" на "є", тоді накладку \0доведеться робити обережно, тому що якщо заміна робить це: "Моє ім'я є \ 0 Містер Робот ", тоді під час виконання операцій зі рядком символ" \ 0 "створюватиме проблеми, оскільки довжина ненавмисно зменшиться.
Nehal J Wani

@NehalJWani ні, у такому випадку вам доведеться змістити весь решту рядка вперед на один байт, щоб ваш новий, додатковий, закінчуючий, NULішов на кінець, прилеглий до існуючого NUL.
Селада
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.