有没有办法“重载”或重新实现 __stack_chk_fail?

ome*_*433 2 c gcc buffer-overflow

我想在 gcc 中为我正在构建的在 x86 linux 上运行的系统启用堆栈保护功能。

我希望如果它检测到堆栈粉碎,它会调用我自己的函数来处理这种情况,或者它会调用我自己的函数实现__stack_chk_fail,有没有办法做到这一点?

到目前为止,我试图民主基金__stack_chk_fail和__stack_chk_guard然后定义他们自己,但它没有工作,并试图利用缓冲区溢出时,导致分段错误。这是我所做的一个例子:

    #undef __stack_chk_guard
    #undef __stack_chk_fail
    uintptr_t __stack_chk_guard = 0xdeadbeef;

    void __stack_chk_fail(void)
    {
        printf("Stack smashing detected");
    }

   void foo(void)
   {
    char buffer[2];
    strcpy(buffer, "hello, I am smashing your stack!");
   }
Run Code Online (Sandbox Code Playgroud)

我也尝试使用,LD_PRELOAD但是在粉碎堆栈时导致分段错误,但它也导致分段错误。

ome*_*433 7

经过一些研究,我发现我可以使用链接器标志--wrap来包装__stack_chk_fail和插入我自己的处理方式,就像我想要的那样。

标志改变每次调用__stack_chk_failto__wrap___stack_chk_fail和每次调用__real___stack_chk_failto__stack_chk_fail

__stack_chk_fail如果我想,我什至可以跳过调用真实的

下面是名为 的文件中的示例代码test.c:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void __real___stack_chk_fail(void);

void __wrap___stack_chk_fail(void)
{
    printf("our test");
    __real___stack_chk_fail();
}
void func()
{
    char buffer[2];
    strcpy(buffer, "smashhhhhhhhhhhhhhhh");
}
int main(void)
{
    func();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

要编译它,请执行:

gcc -fstack-protector-strong -c test.c
gcc -Wl,--wrap=__stack_chk_fail test.o 
Run Code Online (Sandbox Code Playgroud)

输出将是“我们的测试”,然后是 __stack_chk_fail

更新:

另一种方法是从带有标志的链接过程中排除 libssp--exclude-libs,libssp并自行实现__stack_chk_fail和guard_setup(启动__stack_chk_guard值的函数)