J'ai lu cette citation (ci-dessous) à plusieurs reprises, dont la plus récente ici , et je suis toujours perplexe quant à la manière dont dd
on peut utiliser pour patcher n'importe quoi, sans parler d'un compilateur:
Le système Unix que j'avais utilisé à l'école, il y a 30 ans, était très limité en RAM et en espace disque. En particulier, le
/usr/tmp
système de fichiers était très petit, ce qui posait problème lorsque quelqu'un essayait de compiler un programme volumineux. Bien entendu, les étudiants n'étaient pas censés écrire de "gros programmes" de toute façon; les grands programmes étaient généralement des codes sources copiés "quelque part". Beaucoup d' entre nous copiés/usr/bin/cc
à/home/<myname>/cc
, et utilisédd
pour patcher le binaire à utiliser au/tmp
lieu de/usr/tmp
, qui était plus grande. Bien sûr, cela ne faisait qu'aggraver le problème: l'espace disque occupé par ces copies importait de nos jours et se/tmp
remplissait maintenant régulièrement, empêchant les autres utilisateurs de modifier leurs fichiers. Après avoir découvert ce qui s’est passé, les administrateurs système ont fait unechmod go-r /bin/* /usr/bin/*
qui "corrige" le problème et supprime toutes nos copies du compilateur C.
(Souligné par moi)
La dd
page de manuel ne dit rien sur les correctifs et ne pense pas qu'il pourrait être modifié pour le faire de toute façon.
Les binaires pourraient-ils vraiment être corrigés dd
? Y at-il une signification historique à cela?
od
un fichier pour les codes hexadécimaux, trouvez le décalage dont vous avez besoin, décidez de votre édition et debs=$patchsize count=1 seek=$((offset/bs)) conv=notrunc
votre correctif directement dans.Réponses:
Essayons. Voici un programme C trivial:
Nous allons construire cela dans
test
:Si nous l'exécutons, il affichera "/ usr / tmp".
Voyons où "
/usr/tmp
" se trouve dans le binaire:-t d
imprime le décalage en décimal dans le fichier de chaque chaîne trouvée.Créons maintenant un fichier temporaire contenant juste "
/tmp\0
":Nous avons maintenant le fichier binaire, nous savons où se trouve la chaîne à modifier et nous avons un fichier contenant la chaîne de remplacement.
Maintenant nous pouvons utiliser
dd
:Ceci lit les données de
tmp
(notre "/tmp\0
" fichier), les écrit dans notre binaire, en utilisant une taille de bloc de sortie de 1 octet, en sautant au décalage que nous avons trouvé précédemment avant qu’il n’écrive quoi que ce soit, et ne tronque pas explicitement le fichier lorsque cela est fait.Nous pouvons exécuter le fichier exécutable corrigé:
Le littéral de chaîne que le programme affiche a été modifié. Il contient donc maintenant "
/tmp\0tmp\0
", mais les fonctions de chaîne s'arrêtent dès qu'elles voient le premier octet nul. Ce patch permet uniquement de raccourcir ou de prolonger la longueur de la chaîne, mais cela convient parfaitement.Donc, non seulement nous pouvons corriger les choses en utilisant
dd
, nous venons de le faire.la source
/usr/tmp
chaîne, remplacez-la par/tmp
, don 'oubliez pas le dernier\0
octet, sauvegardez le fichier et croisez les doigts ". Ou, mieux encore, un script shell qui vérifie d'abord la cohérence, puis appelledd
. Malheureusement, le besoin de choses comme celle-ci se pose fréquemment lorsqu'un logiciel déjà développé par un ancien fournisseur doit maintenant être migré vers un nouveau système.sed
n'est pas mieux pour ce genre de chose - vous ne pouvez pas limitersed
les tampons de lecture / écriture de manière aussi explicite et précise, comme vous le feriez avecdd
- ce qui est la raison pour laquelle il a été utilisé pour cela à l'origine. Avecdd
vous pouvez placer arbitrairement un nombre arbitraire d'octets arbitraires. On ne peut pas en dire autant de celased
. Sidd
est utilisé ici comme un scalpel, vous appliqueriezsed
comme une boule de démolition.Cela dépend de ce que vous entendez par "patcher le binaire".
Je change les binaires en utilisant
dd
parfois. Bien sûr, cette fonctionnalité n’existe pasdd
, mais elle peut ouvrir des fichiers, lire et écrire des choses à des décalages spécifiques, donc si vous savez quoi écrire où, voila votre patch.Par exemple, j'avais ce fichier binaire contenant des données PNG. Utilisez
binwalk
pour trouver le décalage,dd
pour l'extraire (généralement binwalk extrait également des choses mais ma copie était boguée), éditez-le avecgimp
, assurez-vous que le fichier modifié est de la même taille ou plus petit que celui d'origine (modifier les décalages n'est pas quelque chose que vous pouvez faire facilement. ), puis utilisez-ledd
pour remettre l’image modifiée en place.Parfois, je souhaite également remplacer des chaînes dans des fichiers binaires (tels que des noms de chemins ou de variables). Bien que cela puisse également être fait en utilisant
dd
, il est plus simple de le faire en utilisantsed
. Vous devez simplement vous assurer que la chaîne que vous remplacez a la même longueur que la chaîne d'origine afin de ne pas modifier les décalages.ou pour prendre l'exemple de MichaelHomer avec un 0 octet ajouté dans:
Bien sûr, vous devez vérifier si cela fonctionne réellement après.
la source
sed
qui gère bien les fichiers binaires, ce qui semble être le cas avec gnused
, mais pas avec la plupart des ancienssed
s qui travaillaient uniquement sur des fichiers ascii, ont été confondus avec autre chose (en particulier\0
s dans l'entrée), et avait des restrictions sur la longueur maximale de la ligne.sed
semble être capable de changer les fichiers binaires sans problème, mais cela ne comprend pas\x00
la chaîne de remplacement comme le fait GNUsed
. Cela nécessite des tests, mais même dans ce cas, je pense que cela vaut la peine d'être mentionné car c'est beaucoup plus simple quedd
, dans certains cas. Corriger les fichiers binaires est une entreprise floconneuse dans les deux cas.