有没有办法 "overload" 或重新实现 __stack_chk_fail?
Is there a way to "overload" or reimplement __stack_chk_fail?
我想在 gcc 中为我在 x86 linux 上构建的 运行 系统启用堆栈保护功能 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!");
}
我也试过使用LD_PRELOAD
,但是在粉碎堆栈时导致了分段错误,但它也导致了分段错误。
经过一些研究,我发现我可以使用链接器标志 --wrap
来包装 __stack_chk_fail
并按照我的需要插入我自己的处理。
标志将 __stack_chk_fail
的每次调用更改为 __wrap___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
输出将是 "our test",然后是 __stack_chk_fail
的常规行为
更新:
另一种方法是使用标志 --exclude-libs,libssp
从链接过程中排除 libssp 并实现 __stack_chk_fail
和 guard_setup
(启动 __stack_chk_guard
值的函数) 靠自己
我想在 gcc 中为我在 x86 linux 上构建的 运行 系统启用堆栈保护功能 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!");
}
我也试过使用LD_PRELOAD
,但是在粉碎堆栈时导致了分段错误,但它也导致了分段错误。
经过一些研究,我发现我可以使用链接器标志 --wrap
来包装 __stack_chk_fail
并按照我的需要插入我自己的处理。
标志将 __stack_chk_fail
的每次调用更改为 __wrap___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
输出将是 "our test",然后是 __stack_chk_fail
更新:
另一种方法是使用标志 --exclude-libs,libssp
从链接过程中排除 libssp 并实现 __stack_chk_fail
和 guard_setup
(启动 __stack_chk_guard
值的函数) 靠自己