Kiedy mogę edytować ciągi w wykonywalnym pliku binarnym?

11

Mam wykonywalny plik binarny; nazwijmy to a.out. Widzę, że plik binarny zawiera ciągi

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

Muszę zmienić ciąg /usr/share/foona /usr/share/bar. Czy mogę po prostu zastąpić ciąg sed?

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

To wygląda na bezpieczne. Czy to zadziała również, gdy struny nie będą tej samej długości?

Martin Vegter
źródło

Odpowiedzi:

17

Nie wiem, czy twoja wersja sedbędzie binarnie czysta, czy też zadławi się tym, co uważa za naprawdę długie linie na wejściu, ale pomijając te problemy, edycja łańcucha w miejscu powinna działać. Aby zobaczyć, czy tak jest, porównaj starą i nową wersję z cmp -l. Powinien powiedzieć, czy jedyne trzy różnice między tymi dwoma plikami to te 3 bajty.

Edycja łańcuchów w skompilowanym pliku wykonywalnym rzeczywiście będzie działać, jeśli łańcuchy będą miały tę samą długość, ale prawie zawsze zadziała również, jeśli skrócisz łańcuch ze względu na sposób, w jaki łańcuchy działają w C. W łańcuchach C wszystko po NULzakończeniu terminatora nie ma znaczenia, więc jeśli napiszesz nowy NULterminator przed pozycją starego, skutecznie skrócisz łańcuch.

Ogólnie rzecz biorąc, nie ma możliwości przedłużenia łańcucha za pomocą tego hacka.

Celada
źródło
A co ze skracaniem sznurka czymś takim sed -i 's@longstring@foo@' a.out? Spowoduje to zmniejszenie całego pliku binarnego o 7 bajtów. Czy nie spowoduje to uszkodzenia pliku binarnego?
Martin Vegter,
Tak, spowoduje to uszkodzenie pliku binarnego. Dlatego musisz przetłumaczyć ciąg na dokładnie taką samą długość, ale ustaw NULterminator na wcześniejszej pozycji, jak wyjaśniłem (choć może zbyt krótko). Problem polega na tym, że nie możesz mieć NULbajtu w wierszu poleceń, więc musisz umieścić swój sedprogram w pliku i odwołać się do niego -f. Z drugiej strony bezpieczniejszym rozwiązaniem byłoby użycie narzędzia zaprojektowanego do pracy z danymi binarnymi, zamiast takiego, sedktóre jest przeznaczone do pracy z danymi tekstowymi.
Celada,
2
Dobra odpowiedź. sed może robić wiele rzeczy, ale generalnie do tego właśnie opracowano edytory binarne. Mogą być trudne w użyciu podczas nawigacji w dużym pliku binarnym, ale pozwolą ci zmieniać bajt po bajcie. Używam, hexeditgdy muszę sprawdzić lub zmienić plik binarny. Możesz użyć strings -t x file | lessdo zlokalizowania przesunięć (drukowalnych) ciągów, które chcesz zmienić przed skokiem do edytora.
Joe
Powiedzmy, że mam ciąg w moim programie C: „Nazywałam się Pan Robot” i chcę zastąpić „był” na „jest”, wtedy dopełnianie \0będzie musiało zostać wykonane ostrożnie, ponieważ jeśli zamiana zrobi to: „Nazywam się to \ 0 Mr Robot ”, a następnie podczas wykonywania operacji na łańcuchu znak„ \ 0 ”spowoduje problemy, ponieważ długość zostanie przypadkowo zmniejszona.
Nehal J Wani,
@NehalJWani nie, w takim przypadku musisz przesunąć całą resztę ciągu o jeden bajt, aby nowe, dodatkowe zakończenie NULkończyło się na końcu, przylegając do istniejącego NUL.
Celada