linux - El uso de gdb para el código ensamblador de un solo paso fuera del ejecutable especificado provoca el error "no se pueden encontrar los límites de la función actual"
assembly x86 (3)
Estoy fuera del ejecutable objetivo de gdb y ni siquiera tengo una pila que corresponda a ese objetivo. De todos modos, quiero un solo paso, para poder verificar lo que está sucediendo en mi código de ensamblado, porque no soy un experto en ensamblaje x86. Desafortunadamente, gdb se niega a hacer esta simple depuración a nivel de ensamblaje. Me permite establecer y detenerme en el punto de interrupción apropiado, pero tan pronto como trato de avanzar en un solo paso, gdb informa el error "No se pueden encontrar los límites de la función actual" y el EIP no cambia.
Detalles adicionales:
El código máquina fue generado por las declaraciones gcc asm y lo copié a la ubicación de memoria del kernel donde se está ejecutando, desde la salida de objdump -d. No me importaría una forma simple de usar un cargador para cargar mi código de objeto en una dirección reubicada, pero tenga en cuenta que la carga tiene que hacerse en un módulo kernel.
Supongo que otra alternativa sería producir un módulo de kernel falso o un archivo de información de depuración para dar a gdb, para hacer creer que esta área está dentro del código del programa. gdb funciona bien en el ejecutable kernel mismo.
(Para aquellos que realmente quieran saber, estoy insertando código en tiempo de ejecución en el espacio de datos del kernel de Linux dentro de VMware VM y depurándolo de la depuración remota gdb del kernel mediante el resguardo gdb incorporado de VMware Workstation. Nota No estoy escribiendo kernel exploits; soy un estudiante graduado de seguridad escribiendo un prototipo.)
(Puedo establecer un punto de interrupción en cada instrucción dentro de mi ensamblado. Esto funciona pero se volvería bastante laborioso después de un tiempo, ya que el tamaño de las instrucciones de ensamblaje x86 varía y la ubicación del ensamblaje cambiará cada vez que reinicie).
En lugar de gdb
, ejecuta gdbtui
. O ejecuta gdb
con el conmutador -tui
. O presione Cx Ca luego de ingresar gdb
. Ahora estás en el modo TUI de GDB.
Ingrese el layout asm
para hacer que el ensamblaje de la ventana superior se muestre; esto seguirá automáticamente su puntero de instrucción, aunque también puede cambiar los marcos o desplazarse mientras se depura. Presione Cx s para ingresar al modo SingleKey, donde run continue up down finish
etc. se abrevia a una sola tecla, lo que le permite recorrer su programa muy rápidamente.
+---------------------------------------------------------------------------+ B+>|0x402670 <main> push %r15 | |0x402672 <main+2> mov %edi,%r15d | |0x402675 <main+5> push %r14 | |0x402677 <main+7> push %r13 | |0x402679 <main+9> mov %rsi,%r13 | |0x40267c <main+12> push %r12 | |0x40267e <main+14> push %rbp | |0x40267f <main+15> push %rbx | |0x402680 <main+16> sub $0x438,%rsp | |0x402687 <main+23> mov (%rsi),%rdi | |0x40268a <main+26> movq $0x402a10,0x400(%rsp) | |0x402696 <main+38> movq $0x0,0x408(%rsp) | |0x4026a2 <main+50> movq $0x402510,0x410(%rsp) | +---------------------------------------------------------------------------+ child process 21518 In: main Line: ?? PC: 0x402670 (gdb) file /opt/j64-602/bin/jconsole Reading symbols from /opt/j64-602/bin/jconsole...done. (no debugging symbols found)...done. (gdb) layout asm (gdb) start (gdb)
Lo más útil que puede hacer aquí es display/i $pc
, antes de usar stepi
como ya se sugirió en la respuesta de R. Samuel Klatchko. Esto le dice a gdb que desarme la instrucción actual justo antes de imprimir el aviso cada vez; entonces puedes seguir stepi
Enter para repetir el comando stepi
.
(Consulte mi respuesta a otra pregunta para obtener más detalles: el contexto de esa pregunta era diferente, pero el principio es el mismo).
Puede usar stepi
o nexti
(que se puede abreviar a si
o ni
) para recorrer su código de máquina.