【GDB】__stack_chk_fail 栈溢出问题定位

本文详细解析了进程收到SIGABRT信号时的异常退出,聚焦于__stack_chk_fail异常。通过分析C代码和使用GDB定位,展示了如何通过反汇编追踪canary,揭示了不同.so依赖的lua.h头文件不一致导致的栈溢出问题。同时介绍了如何利用GCC的fstack-protector选项加强栈保护。

一、问题描述

进程收到SIGABRT信号异常退出,异常调用栈显示__stack_chk_fail

二、原因分析和定位思路

原因分析: __stack_chk_fail说明发生了缓冲区溢出,canary被破坏。这说明代码设置GCC编译选项fstack-protector,开启了栈保护机制canary

定位思路:

  • 先通过反汇编找到canary在栈上的存放地址。
  • 用GDB对canary的存放地址打数据断点,定位出导致栈破坏的指令,再结合C代码具体分析。

三、定位过程

以下给出一个简化案例:一个可执行程序test, 依赖两个.so:libcomp1.so, libcomp2.so。执行test程序后会异常退出,调用栈显示__stack_chk_fail

├── CMakeLists.txt			—— 可执行程序 test, 依赖libcomp1.so, libcomp2.so
├── comp1					
│   ├── CMakeLists.txt		—— libcomp1.so
│   ├── comp1.c
│   ├── lua.h
├── comp2
│   ├── CMakeLists.txt		-- libcomp2.so
│   ├── comp2.c
│   ├── lua.h
├── main.c

C代码如下:

// main.c
extern void func1();	// defined in libcomp1.so
void main() {
    func1();
}

// comp1/comp1.c
#include "lua.h"
extern func2(struct lua_Debug *a, char *b, int c); // defined in libcomp2.so
void func1() {
    struct lua_Debug a = {0};
    char *b = 0x12345678;
    int c = 0xFFFFFFFF;
    func2(&a, b, c);
    return;
}

// comp2/comp2.c
#include "lua.h"
void func2(struct lua_Debug *a, char *b, int c) {
    a->i_ci = 1;
    return;
}

用GDB调试test程序,出现如下的异常调用栈

(gdb) bt
#0  __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
#1  0x00007ffff7e1c535 in __GI_abort () at abort.c:79
#2
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

pcj_888

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值