在没有标准库的情况下实现自定义堆栈金丝雀处理
Implement custom stack canary handling without the standard library
我正在尝试在没有标准库的情况下手动实现堆栈金丝雀。因此,我在 OSDev wiki 的 this guide 的帮助下创建了一个简单的 PoC。文章建议一个简单的实现必须提供 __stack_chk_guard
变量和 __stack_chk_fail()
处理程序。
然而,当我使用 GCC 编译并提供 -fstack-protector-all
标志时,可执行文件根本不包含任何堆栈金丝雀检查。我缺少什么让 GCC 包含堆栈金丝雀逻辑?
gcc -Wall -nostdlib -nodefaultlibs -fstack-protector-all -g -m64 -o poc main.c customlib.h
main.c
#include "customlib.h"
#define STACK_CHK_GUARD (0xDEADBEEFFFFFFFF & ~0xFF)
uintptr_t __stack_chk_guard = STACK_CHK_GUARD;
__attribute__((noreturn)) void __stack_chk_fail()
{
__exit(123);
while(1);
}
int main()
{
__attribute__((unused)) char buffer[16];
for (size_t index = 0; index < 32; index++)
{
buffer[index] = 'A';
}
return 0;
}
customlib.h
这段代码大部分是无关紧要的,只是程序可以正确编译和链接所必需的。
typedef unsigned long int size_t;
typedef unsigned long int uintptr_t;
size_t __syscall(size_t arg1, size_t arg2, size_t arg3, size_t arg4, size_t arg5, size_t arg6)
{
asm("int [=12=]x80\n"
: "=a"(arg1)
: "a"(arg1), "b"(arg2), "c"(arg3), "d"(arg4), "S"(arg5), "D"(arg6));
return arg1;
}
void _exit(int exit_code)
{
__syscall(1, exit_code, 0, 0, 0, 0);
while(1);
}
extern int main();
void _start()
{
main();
_exit(0);
}
GCC 版本 10.2.0,Linux 5.10.36-2-MANJARO GNU/Linux
它看起来像 Arch gcc 包(Manjaro 包基于它)is turning off -fstack-protector
when building without the standard library (Done for Arch bug 64270)。
这种行为显然也存在于 Gentoo 中。
我没试过这个,但我相信你应该能够使用 gcc -dumpspecs
将 GCC 规范转储到一个文件中,只保留部分 *cc1_options
,删除 %{nostdlib|nodefaultlibs|ffreestanding:-fno-stack-protector}
从它,并通过 gcc -specs=your_spec_file
.
将其传递给 gcc
或者,您可以在删除此补丁的情况下重建 gcc 包。
我正在尝试在没有标准库的情况下手动实现堆栈金丝雀。因此,我在 OSDev wiki 的 this guide 的帮助下创建了一个简单的 PoC。文章建议一个简单的实现必须提供 __stack_chk_guard
变量和 __stack_chk_fail()
处理程序。
然而,当我使用 GCC 编译并提供 -fstack-protector-all
标志时,可执行文件根本不包含任何堆栈金丝雀检查。我缺少什么让 GCC 包含堆栈金丝雀逻辑?
gcc -Wall -nostdlib -nodefaultlibs -fstack-protector-all -g -m64 -o poc main.c customlib.h
main.c
#include "customlib.h"
#define STACK_CHK_GUARD (0xDEADBEEFFFFFFFF & ~0xFF)
uintptr_t __stack_chk_guard = STACK_CHK_GUARD;
__attribute__((noreturn)) void __stack_chk_fail()
{
__exit(123);
while(1);
}
int main()
{
__attribute__((unused)) char buffer[16];
for (size_t index = 0; index < 32; index++)
{
buffer[index] = 'A';
}
return 0;
}
customlib.h
这段代码大部分是无关紧要的,只是程序可以正确编译和链接所必需的。
typedef unsigned long int size_t;
typedef unsigned long int uintptr_t;
size_t __syscall(size_t arg1, size_t arg2, size_t arg3, size_t arg4, size_t arg5, size_t arg6)
{
asm("int [=12=]x80\n"
: "=a"(arg1)
: "a"(arg1), "b"(arg2), "c"(arg3), "d"(arg4), "S"(arg5), "D"(arg6));
return arg1;
}
void _exit(int exit_code)
{
__syscall(1, exit_code, 0, 0, 0, 0);
while(1);
}
extern int main();
void _start()
{
main();
_exit(0);
}
GCC 版本 10.2.0,Linux 5.10.36-2-MANJARO GNU/Linux
它看起来像 Arch gcc 包(Manjaro 包基于它)is turning off -fstack-protector
when building without the standard library (Done for Arch bug 64270)。
这种行为显然也存在于 Gentoo 中。
我没试过这个,但我相信你应该能够使用 gcc -dumpspecs
将 GCC 规范转储到一个文件中,只保留部分 *cc1_options
,删除 %{nostdlib|nodefaultlibs|ffreestanding:-fno-stack-protector}
从它,并通过 gcc -specs=your_spec_file
.
或者,您可以在删除此补丁的情况下重建 gcc 包。