Przeczytałem ten cytat (poniżej) kilka razy, ostatnio tutaj , i ciągle zastanawiam się, jak dd
można go użyć do łatania czegokolwiek, nie mówiąc już o kompilatorze:
System uniksowy, z którego korzystałem w szkole 30 lat temu, był bardzo ograniczony pod względem pamięci RAM i miejsca na dysku. Szczególnie
/usr/tmp
system plików był bardzo mały, co spowodowało problemy, gdy ktoś próbował skompilować duży program. Oczywiście studenci i tak nie powinni pisać „dużych programów”; duże programy były zwykle kodami źródłowymi kopiowanymi „gdzieś”. Wielu z nas kopiowane/usr/bin/cc
do/home/<myname>/cc
i używanedd
załatać binarny do używania/tmp
zamiast/usr/tmp
, który był większy. Oczywiście tylko pogorszyło to problem - przestrzeń dyskowa zajmowana przez te kopie miała znaczenie w tych dniach, a teraz/tmp
regularnie się zapełnia, uniemożliwiając innym użytkownikom nawet edytowanie swoich plików. Po dowiedzeniu się, co się stało, sysadmins zrobilichmod go-r /bin/* /usr/bin/*
co „naprawiło” problem i usunęło wszystkie nasze kopie kompilatora C.
(Moje podkreślenie)
dd
Człowiek-strona nie mówi nic o łatanie i nie sądzę, żeby to mogło być ponownie postanowił zrobić to w każdym razie.
Czy naprawdę można załatać pliki binarne dd
? Czy ma to jakieś znaczenie historyczne?
od
plik bajtowych kodów szesnastkowych, znajdź potrzebne przesunięcie, zdecyduj o swojej edycji ibs=$patchsize count=1 seek=$((offset/bs)) conv=notrunc
Odpowiedzi:
Spróbujmy. Oto trywialny program C:
Zbudujemy to w
test
:Jeśli go uruchomimy, wyświetli „/ usr / tmp”.
Dowiedzmy się, gdzie „
/usr/tmp
” znajduje się w pliku binarnym:-t d
wypisuje przesunięcie dziesiętne do pliku każdego znalezionego ciągu.Teraz zróbmy plik tymczasowy z po prostu „
/tmp\0
”:Teraz mamy plik binarny, wiemy, gdzie znajduje się ciąg, który chcemy zmienić, i mamy plik z ciągiem zastępującym.
Teraz możemy użyć
dd
:Odczytuje dane z
tmp
(naszego „/tmp\0
” pliku), zapisuje je do naszego pliku binarnego, używając rozmiaru bloku wyjściowego 1 bajt, przeskakując do przesunięcia, które znaleźliśmy wcześniej, zanim coś zapisuje, i jawnie nie obcinając pliku, gdy jest gotowy.Możemy uruchomić załatany plik wykonywalny:
Dosłowny ciąg znaków, który program wypisuje, został zmieniony, więc zawiera teraz „
/tmp\0tmp\0
”, ale funkcje ciągów zatrzymują się, gdy zobaczą pierwszy bajt zerowy. Ta łatka pozwala tylko na skrócenie lub taką samą długość łańcucha, ale nie dłużej, ale jest wystarczająca do tych celów.Więc nie tylko możemy łatać rzeczy za pomocą
dd
, ale właśnie to zrobiliśmy.źródło
/usr/tmp
ciąg, zamień go na/tmp
, don nie zapomnij końcowego\0
bajtu, zapisz plik i trzymaj kciuki ". Lub nawet lepiej, skrypt powłoki, który najpierw sprawdza poprawność poczytalności, a następnie wywołujedd
. Niestety, potrzeba takich rzeczy pojawia się często, gdy stare oprogramowanie nieistniejącego już dostawcy musi zostać migrowane do nowego systemu.sed
„s nie lepiej dla tego rodzaju rzeczy - nie można więc expliciltly i precyzyjnie granicased
” s odczytu / zapisu buforów w sposób, w jaki może zdd
- co jest przyczyną tego, że cały kiedykolwiek użyto w tym w pierwszej kolejności. Za pomocądd
możesz dowolnie umieścić dowolną liczbę dowolnych bajtów. Tego też nie można powiedziećsed
. Jeślidd
użyjesz go tutaj jak skalpela, zastosujesz sięsed
jak kula rozbijająca.Zależy to od tego, co rozumiesz przez „łatanie pliku binarnego”.
dd
Czasami zmieniam pliki binarne . Oczywiście nie ma takiej funkcjidd
, ale może otwierać pliki oraz czytać i pisać rzeczy z określonymi przesunięciami, więc jeśli wiesz, gdzie pisać, voila jest łatka.Na przykład miałem ten plik binarny, który zawierał pewne dane PNG. Użyj,
binwalk
aby znaleźć odsunięcie,dd
aby go wyodrębnić (zwykle binwalk również wyodrębnia rzeczy, ale moja kopia była wadliwa), edytuj za pomocągimp
, upewnij się, że edytowany plik ma taki sam rozmiar lub jest mniejszy niż oryginalny (zmiana przesunięcia nie jest czymś, co możesz zrobić łatwo ), a następnie użyj,dd
aby przywrócić zmieniony obraz na swoim miejscu.Czasami chcę również zastąpić ciągi w plikach binarnych (takich jak nazwy ścieżek lub zmiennych). Chociaż można to również zrobić za pomocą
dd
, łatwiej jest to zrobić za pomocąsed
. Musisz tylko upewnić się, że łańcuch, który zamieniasz, ma taką samą długość jak łańcuch oryginalny, abyś nie zmienił przesunięć.lub pobrać przykład @ MichaelHomer z dodanym 0-bajtem:
Oczywiście musisz sprawdzić, czy to rzeczywiście działa później.
źródło
sed
dobrą obsługę plików binarnych, co wydaje się mieć miejsce w przypadku GNUsed
, ale nie w przypadku wielu starszychsed
s, które działały tylko na plikach ASCII, pomylił się z czymkolwiek innym (szczególnie\0
s na wejściu), i miał ograniczenia dotyczące maksymalnej długości linii.sed
wydaje się być w stanie dobrze zmieniać pliki binarne, ale\x00
w łańcuchu zastępującym nie rozumie tak, jaksed
robi to GNU . Wymaga testowania, ale myślę, że warto o tym wspomnieć, ponieważ jest o wiele prostsze niżdd
- w niektórych przypadkach. Łatowanie plików binarnych to i tak płatna sprawa.