De ce post, il est montré qu'il FS:[0x28]
s'agit d'un empilement de canaris. Je génère ce même code en utilisant GCC sur cette fonction,
void foo () {
char a[500] = {};
printf("%s", a);
}
Plus précisément, je reçois cet assemblage ..
0x000006b5 64488b042528. mov rax, qword fs:[0x28] ; [0x28:8]=0x1978 ; '(' ; "x\x19"
0x000006be 488945f8 mov qword [local_8h], rax
...stuff...
0x00000700 488b45f8 mov rax, qword [local_8h]
0x00000704 644833042528. xor rax, qword fs:[0x28]
0x0000070d 7405 je 0x714
0x0000070f e85cfeffff call sym.imp.__stack_chk_fail ; void __stack_chk_fail(void)
; CODE XREF from 0x0000070d (sym.foo)
0x00000714 c9 leave
0x00000715 c3 ret
À quoi sert la valeur de fs:[0x28]
? Le noyau, ou GCC lance-t-il le code? Pouvez-vous afficher le code dans le noyau, ou compilé dans le binaire qui définit fs:[0x28]
? Le canari est-il régénéré - au démarrage, ou le processus d'apparition? Où est-ce documenté?
arch_prctl(ARCH_SET_FS..)
je ne vois pas cela dans l'exécutable? Est-ce du code noyau?ld-linux
lors de l'initialisation TLS.Ce que vous voyez s'appelle (dans GCC) le Stack Smashing Protector (SSP) , qui est une forme de protection contre le débordement de tampon générée par le compilateur. La valeur est un nombre aléatoire généré par le programme au démarrage et, comme le mentionne l'article Wikipédia, est placé dans Thread Local Storage (TLS) . D'autres compilateurs peuvent utiliser différentes stratégies pour implémenter ce type de protection.
Pourquoi stocker la valeur dans TLS? Comme la valeur s'y trouve, son adresse n'est pas accessible par les registres CS, DS et SS, ce qui rend la devinette de la valeur stockée très difficile si vous essayez de modifier la pile à partir d'un code malveillant.
la source