Pregunta

Tengo un archivo ejecutable (C ++, i386, compilado bajo MacOS / X Tiger, si es importante) que contiene un error. La solución para el error es sencilla: hay un lugar en el código donde se llama fork () y no debería. Debido a que la solución es simple, y porque recompilar el ejecutable desde cero sería difícil en este punto (no pregunte), me gustaría simplemente parchear el archivo ejecutable / binario directamente.

Como primer paso hacia eso, ejecuté " otool -tV MyExecutableName " en mi ejecutable y listo, encontré esto en la salida de desmontaje:

./MyExecutableName:
(__TEXT,__text) section
[... many lines omitted ...]
0002ce0d        subl    <*>x10,%esp
0002ce10        calll   0x0051adac
0002ce15        movzbl  0x14(%ebp),%esi
0002ce19        calll   0x00850ac9      ; symbol stub for: _fork
0002ce1e        cmpl    <*>x00,%eax
0002ce21        jll     0x0002cf02
0002ce27        jle     0x0002ce34
[... many more lines omitted ...]

Entonces, lo que me gustaría hacer es reemplazar el código de operación en la línea 0002ce19, de modo que en lugar de llamar a _fork, simplemente salte incondicionalmente al caso de falla (es decir, debería actuar como si fork () hubiera devuelto -1 )

Desafortunadamente, soy un novato completo en el desmontaje / parche binario, así que no estoy seguro de cómo hacerlo. En particular, mis preguntas son:

1) ¿Qué bytes debo escribir en las ubicaciones 0002ce19 a 0002xe1d para obtener lo que quiero? Supongo que sería el equivalente ensamblado de " jmp 0x0002cf02 " ;, pero ¿cómo calculo cuáles son esos bytes?

2) Las compensaciones impresas por " otool -tV " parecen estar desplazados en el segmento __TEXT del ejecutable. ¿Cómo puedo calcular el byte-delta entre los desplazamientos impresos y la parte superior del archivo, para poder editar / parchear los bytes correctos dentro del archivo?

¡Gracias por cualquier consejo que pueda dar!

¿Fue útil?

Solución

No estoy familiarizado con MacOS / X, pero puedo darte algunas pistas.

La forma correcta de solucionarlo es utilizar un desensamblador para parchear su archivo.

0002ce19        calll   0x00850ac9

se puede reemplazar con

0002ce19        movl   eax, -1 ; mov eax, 0xFFFFFFFF

Los desplazamientos que ve son relativos, por lo que no puede encontrarlos en el archivo.
Por ejemplo, jll 0x0002cf02 es en realidad jll 0x000000DF

Si estoy en lo correcto, el siguiente bloque de código

0002ce19        calll   0x00850ac9      ; symbol stub for: _fork
0002ce1e        cmpl    
0x  E8   AB3C8200
    83F8 00
    0F8C DF000000
    0F84 0B000000
x00,%eax 0002ce21 jll 0x0002cf02 0002ce27 jle 0x0002ce34

tendrá este formulario ensamblado (20 bytes):

<*>

Si esa secuencia es única en el archivo, puede intentar cambiar el E8AB3C8200 a B8FFFFFFFF , si no puede usar un desensamblador.

Otros consejos

Probablemente lo más fácil sería poner mov $ -1,% eax en lugar de la llamada. Puede averiguar a qué bytes corresponde al colocarlo en un archivo .s, compilarlo y volcar el resultado, rellenando con nops si es más corto que la ubicación del parche. Obtengo "b8 ff ff ff ff", que simplemente encaja.

Puede encontrar el inicio de __TEXT ejecutando otool -l y buscando el desplazamiento.

otx y Hex Fiend serán tus amigos. otx le dará un desmontaje con compensaciones relativas a los archivos, y Hex Fiend le permitirá reparar el salto. Recuerde que 0x90 es el código de operación (x86) para NOP, por lo que 9090909090 es un reemplazo apropiado para la llamada fork (). (Solo tenga en cuenta que no generará un valor de retorno, por lo que algo extraño puede terminar en eax).

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top