2011-10-11 12 views
6

¿Por qué cuando ejecuto código desde gdb, obtengo las mismas direcciones para las variables declaradas, pero al ejecutar el binario no obtengo las mismas direcciones?¿Por qué la dirección de una variable local varía cuando se ejecuta varias veces, pero no al depurarla con GDB?

#include<stdio.h> 
void main() 
{ 
    int *x,q; 
    //I saw the address of the variable q in this program through gdb during the __1st__ execution. 
    //I re-compiled the program to make x to point to this address. 
    x=0x7fffffffe2bc; 
    *x=3; 
    printf("%d",(*x)); 
} 

Ejecuto el programa a través de gdb y nunca segfaulted.

$ gdb -q ./a.out 
Reading symbols from /home/eknath/needed2/a.out...done. 
(gdb) r 
Starting program: /home/eknath/needed2/a.out 
3 
Program exited normally. 
(gdb) q 
$ 

Pero la ejecución normal del programa siempre produce un SEGFAULT.

$ ./a.out 
Segmentation fault 

No sé si esta pregunta es un duplicado de Is this always the address for GDB debug program?

NOTA: No he apagado ASLR

Respuesta

2

La razón por la que siempre obtiene la misma dirección para las variables locales mientras se ejecuta en GDB es que GDB (para simplificar la mayoría de los escenarios de depuración) deshabilita la aleatorización del espacio de direcciones.

Puede pedir GDB a no hacer eso con set disable-address-randomization off.

Por curiosidad, la desactivación de la dirección de la aleatorización para el proceso actual no no requieren ningún privilegio, y se hace llamando personality(2). Aquí está el patch que agregó esta característica.

+0

Gran respuesta, gracias –

0

EDIT: Aclaro mi punto ya que puede no haber sido claro . GDB deshabilita ASLR de forma predeterminada, por lo que sus variables siempre tendrán la misma dirección (a menos que el código cambie, agregar variables o códigos antes o incluso después puede causar cambios en las direcciones asignadas y hacer que falle). De esta forma, su código tiene éxito porque las direcciones codificadas estarán en el mismo lugar mientras se ejecutan en GDB. Esto ayuda en la depuración porque las direcciones no cambiarán de la sesión de depuración a la de depuración.

+0

Entonces, efectivamente, gdb apaga ASLR? –

+0

Sí y algunas otras cosas también, pero para su pregunta ASLR es la parte importante. También solo permite dos hilos concurrentes (las versiones anteriores al menos no pueden hablar de las más nuevas) y tiene otras limitaciones. –

+0

Pero no entiendo cómo podría hacer eso. Quiero decir que ASLR solo se puede establecer/desarmar a través de sysctls u otros medios privilegiados, ¿verdad? ¿Cómo se las arregla gdb, sin los privilegios de root o setuid, para hacer esto? –

Cuestiones relacionadas