randn - ¿Por qué esta dirección de memoria% fs: 0x28(fs[0x28]) tiene un valor aleatorio?
rand matlab español (2)
He escrito un fragmento de código C y lo desarmé, así como también leí los registros para comprender cómo funciona el programa en ensamblaje.
int test(char *this){
char sum_buf[6];
strncpy(sum_buf,this,32);
return 0;
}
La parte de mi código que he estado examinando es la función de prueba. Cuando desmonto la salida mi función de prueba me sale ...
0x00000000004005c0 <+12>: mov %fs:0x28,%rax
=> 0x00000000004005c9 <+21>: mov %rax,-0x8(%rbp)
... stuff ..
0x00000000004005f0 <+60>: xor %fs:0x28,%rdx
0x00000000004005f9 <+69>: je 0x400600 <test+76>
0x00000000004005fb <+71>: callq 0x4004a0 <__stack_chk_fail@plt>
0x0000000000400600 <+76>: leaveq
0x0000000000400601 <+77>: retq
Lo que me gustaría saber es qué está haciendo mov %fs:0x28,%rax
?
En x86_64, el direccionamiento segmentado ya no se usa, pero los registros FS
y GS
se pueden usar como direcciones de puntero de base para acceder a estructuras de datos especiales del sistema operativo. Entonces, lo que está viendo es un valor cargado en un desplazamiento desde el valor contenido en el registro del servicio FS
, y no la manipulación de bits del contenido del registro del servicio FS
.
Específicamente, lo que está ocurriendo es que FS:0x28
en Linux está almacenando un valor especial de protección de pila centinela, y el código está realizando una comprobación de protección de pila. Por ejemplo, si busca más en su código, verá que el valor en FS:0x28
se almacena en la pila, y luego se recuperan los contenidos de la pila y se realiza un XOR
con el valor original en FS:0x28
. Si los dos valores son iguales, lo que significa que el bit cero se ha establecido porque XOR
''ing a dos de los mismos valores resulta en un valor cero, luego saltamos a la rutina de test
, de lo contrario saltamos a una función especial que indica que la pila estaba corrompida de alguna manera, y se cambió el valor de centinela almacenado en la pila.
Si usa GCC, esto se puede desactivar con
-fno-stack-protector
Mirando http://www.imada.sdu.dk/Courses/DM18/Litteratur/IntelnATT.htm , creo que %fs:28
es en realidad un desplazamiento de 28 bytes de la dirección en %fs
. Así que creo que está cargando un tamaño de registro completo desde la ubicación %fs + 28
en% rax.