2017-02-10 85 views
1

我想在gcc中为我在x86 linux上运行的系统构建一个系统启用堆栈保护功能。有没有办法“超载”或重新实现__stack_chk_fail?

我想,如果它检测到堆栈溢出会打电话给我自己的功能,将处理的情况下,否则会叫我自己实现的功能__stack_chk_fail的,是有办法做到这一点?

到目前为止,我试图undef __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!"); 
    } 

我也使用LD_PRELOAD尝试,但那个砸堆栈时造成分段错误,但它也造成了分段故障。

+0

C(即在启动__stack_chk_guard值函数)不支持重载,它是一种不同的语言比C++。不要垃圾标签。 – Olaf

+0

@Olaf我知道C不支持方法重载,但我不为有更好的名字什么,我试图做 – omer12433

+0

因此,当你决定使用C,我仍然不知道为什么你使用的C++代码了。无论如何,我的评论都适用。回答你的问题:你的意思是“undef ...”,你不能“取消”一个变量或函数。这不是一个宏观。关于段错误:您调用未定义的行为并且您的代码行为未定义。我会说一切按预期工作,任务完成,没问题。 – Olaf

回答

2

经过一番研究后,我发现我可以使用链接器标记--wrap来包装__stack_chk_fail并插入我自己的hanlding,就像我想要的那样。

标志更改为__wrap___stack_chk_fail__stack_chk_fail每个呼叫和每次调用__real___stack_chk_fail__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; 
} 

要编译执行:

gcc -fstack-protector-strong -c test.c 
gcc -Wl,--wrap=__stack_chk_fail test.o 

的输出中是“我们的测试”,然后经常行为__stack_chk_fail

UPDATE:

另一种方式来做到这一点是从联动过程中排除libssp旗--exclude-libs,libssp和实施__stack_chk_failguard_setup你自己