栈区数据被飞踩问题定位手段
1、栈溢出或者栈数据被踩时,继续运行就会出现segmentation fault。可以尝试着接管SIGSEGV信号,在信号处理函数中保存一些出现异常时候的信息。
2、基于栈溢出场景,栈空间被破坏,也就没法使用栈区,当然就没法执行SIGSEGV信号的处理函数。因此需要开辟额外的空间用于栈空间使用,系统提供了sigaltstack接口。
2.1、开辟第二栈区的代码
void create_alt_stack(void)
{stack_t sigstack;memset(&sigstack, 0x00, sizeof(stack_t));sigstack.ss_sp = malloc(SIGSTKSZ);if( !sigstack.ss_sp){printf("Err: malloc error\n");exit(EXIT_FAILURE);}sigstack.ss_size = SIGSTKSZ;sigstack.ss_flags = 0;if(sigaltstack(&sigstack, NULL) == -1){printf("Err: sigaltstack error\n");exit(EXIT_FAILURE);}printf("Now the alternate signal stack is successfully allocated\n");printf("The address of signal stack is : %10p - %10p\n",sigstack.ss_sp,(char*)sbrk(0)-1);return;
}
2.2、接管SIGSEGV信号
void sig_action(void)
{struct sigaction act;memset(&act, 0x00, sizeof(struct sigaction));act.sa_flags = SA_SIGINFO | SA_NODEFER | SA_ONSTACK;sigemptyset(&act.sa_mask);act.sa_sigaction = handler; //须挂在sa_sigaction 不应该挂在sa_handlersigaction(SIGSEGV, &act, NULL);
// sigaction(SIGABRT, &act, NULL);return;
}
信号处理函数handler不应该挂接到sa_handler,应该挂接到sa_sigaction,这样处理函数可以通过参数获取额外的信息,同时sa_flags需要增加SA_SIGINFO标志。
struct sigaction {union {__sighandler_t _sa_handler;void (*_sa_sigaction)(int, struct siginfo *, void *);} _u;sigset_t sa_mask;unsigned long sa_flags;void (*sa_restorer)(void);
};
2.3、当出现异常时,会运行到处理函数handler
static void handler(int sig, siginfo_t *info, void *cntxt)
{int i = 0;int *paddr = NULL;paddr = (int *)((((ucontext_t *)(cntxt))->uc_mcontext).gregs[REG_RSP]);printf("Waoh, caught signal %s, Stack addr = %p\n",strsignal(sig), paddr);for (i = -20; i < 20; i++) {printf("0x%x\n", *(paddr + i));}sleep(2);_exit(EXIT_FAILURE);
}
其中ucontext_t结构体定义如下:
typedef struct ucontext
{unsigned long int uc_flags;struct ucontext *uc_link; // 当前上下文执行完了,恢复运行的上下文 stack_t uc_stack; // 该上下文中使用的栈mcontext_t uc_mcontext; // 保存当前上下文,即各个寄存器的状态__sigset_t uc_sigmask; // 保存当前线程的信号屏蔽掩码struct _libc_fpstate __fpregs_mem;
} ucontext_t;typedef struct
{gregset_t gregs; //用于装载寄存器/* Note that fpregs is a pointer. */fpregset_t fpregs; //所有寄存器的类型__extension__ unsigned long long __reserved1 [8];
} mcontext_t;
2.4、打印出现异常时,异常栈区地址附近的数据,分析数据。根据被踩空间大小,适当调整打印范围。
其中红框的数据就是被踩的数据,黄框的数据保存着函数的地址。通过cat /proc/$pid/maps查看代码段的基地址,进而使用addr2line命令查看函数在代码中的位置。
从而可以缩小范围,在main->stack_funcAx这层调用路径下。同时通过红框中被踩的数据grep反推这些数据在代码中是否存在。
当然被踩的数据区域大小场景不一致,需要具体问题具体分析。
3、正常情况下会打开栈保护功能,-fstack-protector-all。注释demo程序sleep(8)前面初始化这几行,Makefile中增加-fstack-protector-all编译选项。
3.1、gdb挂载程序
3.2、直接运行程序,程序出现错误,查看当前的堆栈信息
查看__stack_chk_fail函数的上一层函数test_stack_overflow,应该是这一层的函数出现了问题。
3.3、退出gdb,重新进入gdb,给test_stack_overflow打断点,运行。查看附近的汇编指令
其中绿框中显示的汇编指令就是为了栈保护功能在栈区添加的canary魔鬼数字,在函数即将退出时,会比较canary魔鬼数字是否发生改变。假如被改写,会跳转到__stack_chk_fail函数运行。
3.4、使用n命令运行至绿框汇编指令后面,打印%rbp寄存器的值,获取存放canary魔鬼数字的地址。
3.5、查看地址的数据,同时watch命令对这一地址的数据监控起来,当地址数据被改写时,gdb会停留在改写的位置点。 对被改后的值1820209125数值转换成十六进制0x6F792065,对应着e yo字符串,被改后的值也是定位问题的参考证据。
3.6、查看此处的汇编指令和堆栈信息
从中可以看出是test_stack_overflow函数中strcpy代码处出现的问题。
4、增加-fstack-protector-all编译参数后,在函数的栈区会添加canary值,函数即将退出时通过判断canary的值是否被修改确定栈区数据有没有被破坏。
然而,栈区数据存在被破坏,但是偏偏没有在存放canary值的位置,此时也是无法通过上述方法定位。
可以周期性地打印栈区数据,比较栈区数据的差异,综合定位栈区数据被修改问题。
测试demo程序
GitHub - dyh-git/stack_overflow: 模拟栈空间被修改问题代码
栈区数据被飞踩问题定位手段相关推荐
- 内存飞踩问题的几点思考
1.程序编译,链接后生成二进制可执行程序.二进制可执行文件以elf格式实现排列.可以通过readelf -S xxxx查看具体section的划分,粗略划分如下图所示. 在这些section中,代码段 ...
- IOT物联网观察之物联网是器,大数据是魂,人工智能是手段!
未来大数据应该形成这样的产业形态,就是数据提供商,包括政府,运营商,大的服务商,他们产生大量的数据.然后由无数的内容加工商去进行二次开发,或者根据行业的需求,组织相应的数据采集,最后都需要两大工具,目 ...
- 运维专家:我在大数据项目中踩过的那些坑
一.主要讨论人员 提问:陈超,七牛云技术总监 回答:朱冠胤,百度资深大数据专家,连续两次百度最高奖得主. 二.引言 "坐而论道"是一个轮流问答的玩法.本文是大数据主题周中,几位国内 ...
- 怎么获取codeforces的数据_飞瓜数据5大功能盘点,帮你抓住2019抖音新一波涨粉红利期!...
在过去的一年中,短视频产业全面进入高速运作的模式,我们飞瓜数据为了更好的服务抖音短视频运营,覆盖抖音各个方面的数据,为抖音运营者提供从内容到电商运营整个产业链过程中所涉及的服务数据平台. 如何让更多用 ...
- 跳过数据准备,下秒数据让飞书维格表
随着业务场景的多元化发展,消费者需求的个性化,海量数据暴增.数字化时代,传统的生产工具已经无法跟上时代的步伐,传统办公软件也无法满足企业的多元化需求,能够提升业务效率的软件产品成了企业数智化转型的首选 ...
- 跳过数据准备,下秒数据让飞书维格表数据应用更高效
跳过数据准备,下秒数据让飞书&维格表数据应用更高效 随着业务场景的多元化发展,消费者需求的个性化,海量数据暴增.数字化时代,传统的生产工具已经无法跟上时代的步伐,传统办公软件也无法满足企业的多 ...
- 大数据鹏飞时代,这些商机你掌握了吗
大数据鹏飞时代,这些商机你掌握了吗 跟着智能手机以及可佩带设备的呈现,现在咱们的全部做法乃至是身体和生理反应都在变成可记载以及可剖析的数据.在此基础上,新的经济商业模式也在不断构成. 大数据之所以也许 ...
- 企业数据无忧 飞客功不可没
本文讲的是企业数据无忧 飞客功不可没,在信息高速发展的时代,数据安全是企业最关心的话题,数据丢失.数据泄密通常会对企业造成致命的损害,尽管很多企业加强了内部的管理制度,对重要数据严格管控,并不惜投入大 ...
- redis rdb文件恢复数据注意、踩坑
redis rdb文件恢复数据注意.踩坑 我是docker安装的redis,拷贝dump.rdb文件到挂在的目录下后 重启docker redis,数据并没有被恢复.dump.rdb文件竟然被覆盖掉了 ...
最新文章
- 2022-2028年中国数据中台行业深度调研及投资前景预测报告(全卷)
- 【转】第一类Stirling数和第二类Stirling
- 安装完python需要再安装编辑器-最好用的Python编辑器——Pycharm之安装与设置
- android s静态广播,重走android(3)广播 · sk600’s Studio
- 程序运行依赖的重要文件版本不对_Deno核心模块:灵活依赖amp;安全沙箱
- 牛客网 【每日一题】5月12日题目精讲 模拟战役
- 小G的项链(Manacher)
- java选择排序不稳定_选择排序就这么简单 - Java3y的个人空间 - OSCHINA - 中文开源技术交流社区...
- NeHe OpenGL教程 第四课:旋转
- WebApi系列(从.Net FrameWork 到 .Net Core)
- Word中将传统的复选框型窗体域选项插件 批量替换成 复选框内容控件
- java 测试磁盘io,详解三种Linux测试磁盘IO性能的方法总结,值得收藏
- 机器学习面试题之LR
- js 字符串编码与解码
- 金三银四,Android高级开发面试题目,帮你助力
- 数字电子技术基础(九):竞争—冒险现象成因及消除
- 写给非网工的CCNA教程(1)IP地址和MAC地址
- linux下 Wowza安装与ffmpeg测试
- winform打包应用程序-setup安装包
- Mybatis缓存实现原理