Yee*_*eez 7 random x86 gcc protection linux-kernel
我对Stack Guard和SSP保护有一些疑问。如果我正确的话,第一个问题是关于Stack Guard及其三种类型的Canary-终止符,随机和随机XOR。
我想知道,如何在x86 Linux系统上禁用Stack Guard?在我读过的某个地方,可以使用此命令进行操作,同时使用gcc'-disable-stackguard-randomization ' 进行编译,就像使用该命令启用' -enable-stackguard-randomization '一样,两者均无效。如果需要,我的gcc版本是4.8.2。
关于Stack Guard的下一个问题,何时可以启用/禁用它,如何设置,要使用哪种类型的金丝雀?我读到的内容是,默认情况下使用终结器金丝雀,对于随机性,我必须使用' -enable-stackguard-randomization ' 进行编译,但是随机XOR又如何呢?(或为空0x00000000)
现在关于SSP(ProPolice),我知道,对于随机的金丝雀,我必须使用' fstack-protector-all ' 进行编译,但是终止符如何呢?默认情况下,它与Stack Guard中的一样吗?
最后一个,如果你们中的任何一个都可以告诉我,我在哪里可以找到内存中的随机金丝雀。例如,我有这种情况-编译的C程序,例如' gcc -g example.c -o example -fstack-protector-all ',因此具有随机金丝雀。假设,每次执行后,我都能获得金丝雀的地址。因此,我有:Canary = 0x1ae3f900。从不同的论文中,我得到了一些信息,即金丝雀位于.bss段中。因此,我使用readelf获取.bss段的地址:' readelf -a ./example | grep bss '。是080456c9。在gdb中,我设置了一些断点,以获取金丝雀的地址,但是当我检查.bss地址x / 20x 0x080456c9时,我看到的只是0x00000000地址,而金丝雀却无处可寻。另外,我检查了__stack_chk_fail如果它不存在,但是结果相同,我看不到它。我从PLT / GOT获取stack_chk_fail的地址。
预先感谢您的答复和时间。
堆栈粉碎保护 (SSP) 是对 StackGuard 的改进。SSP 首次在 gcc 4.1 中实现。
我想知道如何在 x86 Linux 系统上禁用 Stack Guard?
用于-fno-stack-protector
禁用用户态 SSP。
和--disable-stackguard-randomization
是--enable-stackguard-randomization
glibc 源代码的构建选项。
当我能够启用/禁用它时,我该如何设置我想使用哪种类型的金丝雀?
据我所知,这在 gcc 中是不可配置的。从 glibc 2.10 开始,堆栈金丝雀是在名为 的函数中生成的_dl_setup_stack_chk_guard
。这是其代码的一部分:
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;
}
Run Code Online (Sandbox Code Playgroud)
dl_random
保存 的辅助向量条目的地址AT_RANDOM
,它是内核在创建进程时初始化的 16 字节随机值。如果您在未初始化的内核或模拟器上运行AT_RANDOM
,则检查dl_random == NULL
将为 true,并且使用的金丝雀是终止符值,其中第一个和第二个最高有效字节\n
分别初始化为 255 和 。所有其他字节均为零。通常由内核初始化,因此会复制AT_RANDOM
至少 7 个有效字节。AT_RANDOM
金丝雀的最后一个字节设置为零。
因此,如果你想使用特定的方法来生成金丝雀,你可以更改此代码并构建你自己的 glibc。
作为替代方法,@PeterCordes 在注释中建议将您的金丝雀值写入函数%%fs:0x28
顶部的内存位置(请参阅下面的代码)main
,并在从main
.
现在关于 SSP(ProPolice),我知道,对于随机金丝雀,我必须使用“fstack-protector-all”进行编译,但是终止符怎么样,默认情况下它与 Stack Guard 中的相同吗?
该选项的所有变体都-fstack-protector
使用 SSP。这些不会影响金丝雀的生成方式。
最后一个,如果你们有人能告诉我,我可以在内存中找到随机的金丝雀。
金丝雀是在进程启动初期动态生成的;你不能用来readelf
获取金丝雀。根据这篇文章,在为 i386 编译时,可以使用以下代码来获取金丝雀:
int read_canary()
{
int val = 0;
__asm__("movl %%gs:0x14, %0;"
: "=r"(val)
:
:);
return val;
}
Run Code Online (Sandbox Code Playgroud)
对于 x86_64:
long read_canary()
{
long val = 0;
__asm__("movq %%fs:0x28, %0;"
: "=r"(val)
:
:);
return val;
}
Run Code Online (Sandbox Code Playgroud)