堆栈粉碎保护 (SSP) 是对 StackGuard 的改进。 SSP 首次在 gcc 4.1 中实现。
我想知道如何在 x86 Linux 系统上禁用 Stack Guard?
Use -fno-stack-protector
禁用用户态 SSP。
The --disable-stackguard-randomization
and --enable-stackguard-randomization
是 glibc 源代码的构建选项。
当我能够启用/禁用它时,我该如何设置,哪种类型
我想用金丝雀吗?
据我所知,这在 gcc 中是不可配置的。从 glibc 2.10 开始,堆栈金丝雀是在一个名为的函数中生成的_dl_setup_stack_chk_guard
。这是一部分its code https://github.com/lattera/glibc/blob/895ef79e04a953cac1493863bcae29ad85657ee1/sysdeps/generic/dl-osinfo.h#L24:
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
, 支票dl_random == NULL
将为 true,并且使用的金丝雀是终止符值,其中第一个和第二个最高有效字节初始化为 255 并且\n
, 分别。所有其他字节均为零。通常AT_RANDOM
由内核初始化,因此至少 7 个有效字节AT_RANDOM
被复制。金丝雀的最后一个字节设置为零。
因此,如果您想使用特定方法生成金丝雀,您可以更改此代码并构建您自己的 glibc。
作为替代方法,@PeterCordes 在评论中建议将您的金丝雀值写入内存位置%%fs:0x28
(见下面的代码)在顶部main
函数并在返回之前恢复运行时生成的金丝雀main
.
现在关于SSP(ProPolice),我知道,对于随机金丝雀我必须编译
与“fstack-protector-all”,但是终止符怎么样,它与
默认情况下在 Stack Guard 中?
所有变体-fstack-protector
选项使用 SSP。这些不会影响金丝雀的生成方式。
最后一个,如果你们有人能告诉我,在哪里可以找到随机的
记忆中的金丝雀。
金丝雀是在进程启动初期动态生成的;你不能使用readelf
得到金丝雀。根据this https://www.elttam.com.au/blog/playing-with-canaries/文章中,您可以使用以下代码在编译 i386 时获取金丝雀:
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;
}