#include <stdio.h> void func() {} int main() { printf("%p", &func); return 0; } Este programa 0x55c4cda9464a Suponiendo que func se almacenará en la sección .text , y de acuerdo con esta figura, desde CS:APP :
Supongo que la dirección de func estaría cerca de la dirección inicial de la sección .text , pero esta dirección está en algún punto intermedio. ¿Por qué es este el caso? Las variables locales almacenadas en la pila tienen direcciones cercanas a 2^48 - 1, pero traté de desensamblar diferentes códigos C y las instrucciones siempre estaban ubicadas en algún lugar alrededor de esa dirección 0x55...
gcc , cuando se configura con --enable-default-pie 1 (que es el predeterminado), produce Ejecutables independientes de posición (PIE) . Lo que significa que la dirección de carga no es la misma que la especificada por el enlazador en tiempo de compilación (0x400000 para x86_64). Este es un mecanismo de seguridad para que se pueda habilitar la aleatorización del diseño del espacio de direcciones (ASLR) 2 . Es decir, gcc compila con la opción -pie por defecto.
Si compila con la opción -no-pie ( gcc -no-pie file.c ), puede ver que la dirección de func está más cerca de 0x400000.
En mi sistema, obtengo:
$ gcc -no-pie tc $ ./a.out 0x401132 También puede verificar la dirección de carga con readelf :
$ readelf -Wl a.out | grep LOAD LOAD 0x000000 0x0000000000400000 0x0000000000400000 0x000478 0x000478 R 0x1000 LOAD 0x001000 0x0000000000401000 0x0000000000401000 0x0001f5 0x0001f5 RE 0x1000 LOAD 0x002000 0x0000000000402000 0x0000000000402000 0x000158 0x000158 R 0x1000 LOAD 0x002e10 0x0000000000403e10 0x0000000000403e10 0x000228 0x000230 RW 0x1000 1 puede verificar esto con gcc --verbose .
2 También puede notar que la dirección impresa por su programa es diferente en cada ejecución. Eso es debido a ASLR. Puedes desactivarlo con:
$ echo 0 | sudo tee /proc/sys/kernel/randomize_va_spaceASLR está habilitado en Linux de forma predeterminada.