He leído esta cita (a continuación) varias veces, la más reciente aquí , y estoy continuamente desconcertado sobre cómo dd
se puede usar para parchear cualquier cosa, y mucho menos un compilador:
El sistema Unix que utilicé en la escuela, hace 30 años, era muy limitado en RAM y espacio en disco. Especialmente, el
/usr/tmp
sistema de archivos era muy pequeño, lo que generaba problemas cuando alguien intentaba compilar un programa grande. Por supuesto, no se suponía que los estudiantes escribieran "programas grandes" de todos modos; Los programas grandes eran típicamente códigos fuente copiados de "algún lugar". Muchos de nosotros copiado/usr/bin/cc
a/home/<myname>/cc
, y utilizadd
para parchear el binario para usar/tmp
en lugar de/usr/tmp
, que era más grande. Por supuesto, esto solo empeoró el problema: el espacio en disco ocupado por estas copias importaba esos días y ahora se/tmp
llenaba regularmente, evitando que otros usuarios incluso editaran sus archivos. Después de que descubrieron lo que sucedió, los administradores de sistemas hicieron unchmod go-r /bin/* /usr/bin/*
que "solucionó" el problema y eliminó todas nuestras copias del compilador de C.
(El énfasis es mío)
La dd
página del manual no dice nada acerca de los parches y no creo que se pueda cambiar el propósito de hacer esto de todos modos.
¿Podrían parchearse realmente los binarios dd
? ¿Hay algún significado histórico para esto?
od
un archivo para los códigos hexadecimales de bytes, halla el desplazamiento es necesario, decidir sobre su edición ybs=$patchsize count=1 seek=$((offset/bs)) conv=notrunc
su derecha parche en adelante.Respuestas:
Vamos a intentarlo. Aquí hay un programa trivial en C:
Construiremos eso en
test
:Si lo ejecutamos, imprime "/ usr / tmp".
Veamos dónde está "
/usr/tmp
" en el binario:-t d
imprime el desplazamiento en decimal en el archivo de cada cadena que encuentra.Ahora hagamos un archivo temporal con solo "
/tmp\0
" en él:Entonces, ahora tenemos el binario, sabemos dónde está la cadena que queremos cambiar, y tenemos un archivo con la cadena de reemplazo.
Ahora podemos usar
dd
:Esto lee los datos de
tmp
(nuestro "/tmp\0
" archivo), escribiéndolos en nuestro binario, usando un tamaño de bloque de salida de 1 byte, saltando al desplazamiento que encontramos antes antes de escribir cualquier cosa, y explícitamente no truncando el archivo cuando está hecho.Podemos ejecutar el ejecutable parcheado:
Se ha cambiado el literal de cadena que imprime el programa, por lo que ahora contiene "
/tmp\0tmp\0
", pero las funciones de cadena se detienen tan pronto como ven el primer byte nulo. Este parche solo permite hacer que la cadena sea más corta o de la misma longitud, y no más larga, pero es adecuada para estos fines.Entonces, no solo podemos parchear las cosas usando
dd
, sino que lo hemos hecho.fuente
/usr/tmp
cadena, reemplácela con/tmp
, don no olvide el\0
byte final , guarde el archivo y cruce los dedos ". O, mejor aún, un script de shell que primero verifica la cordura y luego llamadd
. Desafortunadamente, la necesidad de cosas como esta surge con frecuencia cuando un viejo software de un proveedor ahora desaparecido solo tiene que migrarse a un nuevo sistema.sed
es mejor para este tipo de cosas: no puede limitar de manera tan explícita y precisa las memorias intermedias de lectura / escritura de la manera que podría hacerlo, que es la razón por la que se utilizó para esto en primer lugar. Con usted puede colocar arbitrariamente un recuento arbitrario de bytes arbitrarios. Esto tampoco se puede decir de . Si se usa como un bisturí aquí, se aplicaría como una bola de demolición.sed
dd
dd
sed
dd
sed
Depende de lo que quieras decir con "parchear el binario".
A
dd
veces cambio los binarios . Por supuesto, no existe tal característicadd
, pero puede abrir archivos y leer y escribir cosas en desplazamientos específicos, por lo que si sabe qué escribir dónde, voila está su parche.Por ejemplo, tuve este binario que contenía algunos datos PNG. Úselo
binwalk
para encontrar el desplazamiento,dd
para extraerlo (generalmente binwalk también extrae cosas, pero mi copia tenía errores), edítelogimp
, asegúrese de que el archivo editado sea del mismo tamaño o más pequeño que el original (cambiar los desplazamientos no es algo que pueda hacer fácilmente ), y luego usedd
para volver a colocar la imagen modificada en su lugar.A veces también deseo reemplazar cadenas en binarios (como ruta o nombres de variables). Si bien esto también se puede hacer usando
dd
, es más simple hacerlo usandosed
. Solo debe asegurarse de que la cadena con la que reemplaza tenga la misma longitud que la cadena original para que no termine cambiando las compensaciones.o para recoger el ejemplo de @ MichaelHomer con un byte 0 agregado en:
Por supuesto, debe verificar si realmente funciona después.
fuente
sed
archivo que maneje bien los archivos binarios, lo que parece ser el caso con gnused
, pero no con muchos de lossed
s más antiguos que solo trabajaban en archivos ascii, se confundieron con cualquier otra cosa (especialmente\0
s en la entrada), y tenía restricciones en la longitud máxima de la línea.sed
parece poder cambiar bien los archivos binarios, pero no entiende\x00
en la cadena de reemplazo como losed
hace GNU . Requiere pruebas, pero aun así creo que vale la pena mencionarlo, ya que es mucho más simple quedd
, en algunos casos. Parchear binarios es un negocio flaky de cualquier manera.