我对Stack Guard和SSP保护有一些疑问。如果我正确的话,第一个问题是关于Stack Guard及其三种类型的Canary-终止符,随机和随机XOR。
金丝雀不在。另外,我检查了 __stack_chk_fail 是否不存在,但是结果相同,我在那里看不到它。我从PLT/GOT获取stack_chk_fail的地址。
预先感谢您的答复和时间。
最佳答案
堆栈防砸保护(SSP)是对StackGuard的改进。 SSP最初是在gcc 4.1中实现的。
使用-fno-stack-protector
禁用用户态SSP。--disable-stackguard-randomization
和--enable-stackguard-randomization
是glibc源代码的构建选项。
据我所知,这在gcc中是不可配置的。从glibc 2.10开始,堆栈canary是通过称为_dl_setup_stack_chk_guard
的函数生成的。这是its code的一部分:
if (dl_random == NULL)
{
ret.bytes[sizeof (ret) - 1] = 255;
ret.bytes[sizeof (ret) - 2] = '\n';
}
else
{
memcpy (ret.bytes, dl_random, sizeof (ret));
ret.num &= ~(uintptr_t) 0xff;
}
dl_random
保留AT_RANDOM
的辅助向量条目的地址,它是内核在创建进程时初始化的16字节随机值。如果您在未初始化AT_RANDOM
的内核或仿真器上运行,则check dl_random == NULL
将为true,并且使用的canary是终止符值,其第一个和第二个最高有效字节分别被初始化为255和\n
。所有其他字节均为零。通常,AT_RANDOM
由内核初始化,因此AT_RANDOM
的至少7个有效字节被复制。金丝雀的最后一个字节设置为零。因此,如果要使用特定的方法生成金丝雀,则可以更改此代码并构建自己的glibc。
作为一种替代方法,@ PeterCordes在注释中建议将金丝雀值写入
%%fs:0x28
函数顶部的内存位置main
(请参见下面的代码),并在从main
返回之前恢复运行时生成的金丝雀。-fstack-protector
选项的所有变体都使用SSP。这些不会影响金丝雀的生成方式。金丝雀是在流程启动的早期动态生成的;您不能使用
readelf
来获取金丝雀。根据this的文章,在为i386进行编译时,可以使用以下代码来获取canary:int read_canary()
{
int val = 0;
__asm__("movl %%gs:0x14, %0;"
: "=r"(val)
:
:);
return val;
}
对于x86_64:
long read_canary()
{
long val = 0;
__asm__("movq %%fs:0x28, %0;"
: "=r"(val)
:
:);
return val;
}
关于gcc - Stack Guard和Stack Smashing Protection-金丝雀,内存,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/28020213/