Я читал эту цитату (ниже) несколько раз, совсем недавно здесь , и постоянно удивляюсь, как dd
можно использовать для исправления чего-либо, не говоря уже о компиляторе:
Система Unix, которую я использовал в школе 30 лет назад, была очень ограничена в оперативной памяти и дисковом пространстве. Особенно
/usr/tmp
файловая система была очень маленькой, что приводило к проблемам, когда кто-то пытался скомпилировать большую программу. Конечно, студенты не должны были писать «большие программы» в любом случае; большие программы обычно были исходными кодами, скопированными откуда-то. Многие из нас скопировали/usr/bin/cc
в/home/<myname>/cc
, и используютсяdd
для исправления двоичного файла использовать/tmp
вместо/usr/tmp
, который был больше. Конечно, это только усугубило проблему - дисковое пространство, занимаемое этими копиями, имело значение в те дни и теперь/tmp
регулярно заполнялось, не позволяя другим пользователям даже редактировать свои файлы. После того, как они узнали, что случилось, сисадмины сделалиchmod go-r /bin/* /usr/bin/*
которая "исправила" проблему, и удалила все наши копии компилятора C.
(Акцент мой)
На dd
странице руководства ничего не говорится о исправлении, и я не думаю, что в любом случае это можно изменить.
Могут ли быть исправлены двоичные файлы dd
? Есть ли в этом историческое значение?
od
файл для байт-шестнадцатеричных кодов, найдитеbs=$patchsize count=1 seek=$((offset/bs)) conv=notrunc
нужное смещение, решите, что вы хотите редактировать, и ваш патч прямо сейчас.Ответы:
Давай попробуем. Вот тривиальная программа на C:
Мы встроим это в
test
:Если мы запустим его, он напечатает «/ usr / tmp».
Давайте выясним, где находится "
/usr/tmp
" в двоичном файле:-t d
печатает смещение в десятичном виде в файл каждой найденной строки.Теперь давайте создадим временный файл с просто "
/tmp\0
" в нем:Итак, теперь у нас есть двоичный файл, мы знаем, где находится строка, которую мы хотим изменить, и у нас есть файл с замещающей строкой.
Теперь мы можем использовать
dd
:Он считывает данные из
tmp
(нашего "/tmp\0
" файла), записывает их в наш двоичный файл, использует размер выходного блока 1 байт, пропускает смещение, найденное ранее, прежде чем что-то записывает, и явно не обрезает файл, когда это будет сделано.Мы можем запустить пропатченный исполняемый файл:
Строковый литерал, который выводит программа, был изменен, поэтому теперь он содержит "
/tmp\0tmp\0
", но строковые функции останавливаются, как только они видят первый нулевой байт. Это исправление позволяет только сделать строку короче или одинаковой длины, а не длиннее, но этого вполне достаточно для этих целей.Так что мы можем не только исправлять вещи
dd
, но и делать это.источник
/usr/tmp
строку, заменить его/tmp
, дон не забудьте завершающий\0
байт, сохраните файл и скрестите пальцы ". Или, что еще лучше, сценарий оболочки, который сначала выполняет некоторую проверку работоспособности, а затем вызываетdd
. К сожалению, потребность в таких вещи , как это часто возникает , когда старая часть программного обеспечения на ныне несуществующим поставщик только должна быть перенесена на новую систему.sed
«S не лучше для такого рода вещи - вы не можете так expliciltly и точно пределsed
» s для чтения / записи буфера в том , как вы могли бы сdd
- что вся причина , она была когда - либо использовали для этого в первую очередь. Сdd
его помощью можно произвольно разместить произвольное количество произвольных байтов. Этого также нельзя сказать оsed
. Еслиdd
здесь используется как скальпель, вы бы применилиsed
как разрушающий шар.Это зависит от того, что вы подразумеваете под «патчем двоичного кода».
Я изменяю двоичные файлы, используя
dd
иногда. Конечно, такой функции нетdd
, но она может открывать файлы, читать и записывать вещи с определенными смещениями, поэтому, если вы знаете, что и куда писать, вуаля, есть ваш патч.Например, у меня был этот двоичный файл, который содержал некоторые данные PNG. Используйте,
binwalk
чтобы найти смещение,dd
чтобы извлечь его (обычно binwalk также извлекает вещи, но моя копия была глючная), отредактируйте егоgimp
, убедитесь, что отредактированный файл имеет тот же размер или меньше, чем исходный (изменение смещений - это не то, что вы можете легко сделать ), а затем используйте,dd
чтобы вернуть измененное изображение на место.Иногда я также хочу заменить строки в двоичных файлах (например, пути или имена переменных). Хотя это также может быть сделано с помощью
dd
, это проще сделать с помощьюsed
. Вам просто нужно убедиться, что строка, которую вы заменяете, имеет ту же длину, что и исходная строка, чтобы вы не меняли смещения.или взять пример @ MichaelHomer с добавленным 0-байтом в:
Конечно, вы должны проверить, действительно ли это работает потом.
источник
sed
файл, который хорошо обрабатывает двоичные файлы, что, похоже, имеет место с gnused
, но не со многими более старыми,sed
которые работали только с файлами ascii, перепутали с чем-то еще (особенно\0
с входными данными), и имел ограничения по максимальной длине линии.sed
Похоже, busybox может нормально изменять двоичные файлы, но\x00
в строке замены он не понимает, как это делает GNUsed
. Это требует тестирования, но, тем не менее, я думаю, что стоит упомянуть, поскольку это намного проще, чемdd
- в некоторых случаях. Исправление двоичных файлов в любом случае ненадежное дело.