debugging assembly x86

debugging - ¿Cómo garantizan los errores la corrección cuando se usa el punto de corte del software INT 3(0xCC) aunque se haya parcheado una instrucción?



assembly x86 (3)

Cuando desee continuar con la ejecución después de los incendios del punto de interrupción, tiene dos posibilidades: o bien se suponía que el punto de interrupción solo debía disparar una vez, o se suponía que era persistente. Si solo se supusiera disparar una vez, restaure el valor original que sobreescribió con su instrucción de punto de interrupción, ajuste manualmente la dirección a la dirección de esa instrucción (recuerde, independientemente de qué instrucción haya, lo que se ejecutó fue su punto de interrupción de un solo byte, el ajuste es siempre trivial). Luego continúas la ejecución.

Si se suponía que era un punto de interrupción persistente, hay una arruga añadida: antes de continuar con la ejecución, configura el bit de un solo paso (alias trampa) en los indicadores de la pila. Eso significa que solo se ejecutará la instrucción en la que se estableció el punto de interrupción, y luego obtendrá una interrupción de punto de interrupción nuevamente. Usted responde a eso restaurando el byte int 3 que acaba de parchear en el primer byte de la instrucción original y (nuevamente) continúa la ejecución.

He leído que INT 3 (0xCC) se usa para puntos de interrupción del software.

Se establece por (por ejemplo) un depurador sobrescribiendo el código de programa real en la memoria.

También he leído que INT 3 es una excepción de "trampa" y no de "falla", lo que significa que la dirección que se inserta en la pila es la dirección de la instrucción que sigue a la instrucción INT3.

¿Cómo garantiza el depurador la corrección si la instrucción parchada no se vuelve a ejecutar?


Ha pasado un tiempo desde que profundicé en ese tipo de cosas, pero suponiendo que tenga razón en que la siguiente dirección se inserta en la pila, el depurador puede mostrar la dirección de retorno y usarla para descubrir dónde estaba el punto de interrupción (el retorno dirección menos uno, ya que la instrucción INT 3 es de un byte de longitud) [editado].

En otras palabras, el depurador no necesariamente tiene que volver a la dirección en la pila. Puede restaurar la instrucción original y luego ejecutarla en la ubicación original. Si el punto de corte debe permanecer establecido, puede usar el "bit de captura" en los indicadores para ejecutar solo una instrucción única, la original que se sobrescribió, antes de que se genere otra trampa (creo que INT 3 nuevamente); luego la instrucción INT 3 puede restablecerse antes de continuar la ejecución correctamente.

La mayoría de las veces, sin embargo, los depuradores están operando bajo un sistema donde no están manejando directamente la trampa de todos modos; se les podría enviar una señal, por ejemplo, diciéndoles dónde ocurrió la trampa. Lo más probable es que todavía necesiten averiguar la dirección "real" (es decir, la dirección de la instrucción INT 3) de la dirección de la trampa, ya que el sistema operativo no tiene forma de hacerlo.

Las cosas se complican también, si hay múltiples hilos involucrados; en ese caso, restaurar la instrucción original "en su lugar" puede llevar al punto de ruptura que se pasa por alto si es golpeado por otro hilo. Una solución podría ser detener todos los otros hilos antes de restaurar las instrucciones (y reiniciarlas después).


La solución habitual es que el depurador modifique la dirección en la pila (y restaure la instrucción sobrescrita por la trampa), por lo que ejecuta las instrucciones parcheadas.