首页 星云 工具 资源 星选 资讯 热门工具
:

PDF转图片 完全免费 小红书视频下载 无水印 抖音视频下载 无水印 数字星空

linux内核调试痛点之函数参数抓捕记

编程知识
2024年09月30日 12:51
1.linux内核调试工具crash并不能直接显示函数参数,而这个对调试又非常重要
下面是工作中一个实际的问题,我们的进程hang在如下一个内核栈中了,通过栈回溯可知是打开了一个nfs3的网盘文件或者目录,已知客户机器的NAS盘不可访问了,只要访问就会hang住,但我们的进程理论上是不会访问该NAS盘的,那么如何知道open打开的是什么文件呢,这时候就迫切的需要知道do_sys_open的filename参数了(此时多么希望VS, gdb能够出手相救)。
但在x64位linux系统中,前6个参数使用的是rdi, rsi, rdx, rcx, r8, r9寄存器来传递,超出的才会用栈来传递,filename是第2个参数,会用rsi来传递,这下就GG了,函数经过这么多层调用,到当前栈帧的时候rsi早就是n手货了,而且rsi又不是保留寄存器,下层函数不会给他提供VIP待遇做保存,绝望,绝望,就是这么的绝望。
 
 
 
2.希望之光:通过函数参数被局部变量缓存获取

1> 上帝关上了一扇门,必然会为你打开另一扇窗

虽然寄存器不会被缓存,但局部变量会啊,局部变量是用栈保存的,函数调用栈未返回之前,栈都会一直给你当宝一样存着,so换个思路,假设,我们假设这个函数参数filename传递给了某个路人局部变量,那么我们找到这个路人,不就相当于找到了filename么。
 

2> 思路打开,上帝就立马给你送来了这个路人。

我们看do_sys_open,开头就把filename丢给了tmp这个路人,因此我们只要去栈上把tmp逮捕归案就能收工下班。
 

3> 逮捕方案1:"-FF"

crash的bt命令提供了"-FF"参数,宣称可以打印局部变量。但是吗,往往宣称是一回事,实际又是另一回事。"bt -FF"一敲,甭说放大镜,用电子显微镜也找不到tmp在哪。

4> 逮捕方案2:速请汇编大仙

既然tmp是个局部变量,又会作为第二个参数传递给do_filp_open,那么我们找到汇编大仙call do_filp_open的地方,就能找到tmp了。
来吧,dis照妖镜,do_sys_open原形毕露如下,tmp是调用getname返回的,返回值rax立马给了r14(汇编里返回值都是用rax传递),不妙不妙,还是不给留栈上啊,难怪"bt -FF"瞎眼了。虽然但是呢,上帝又给留了一扇窗(PS: 这上帝给的有点多),r14是保留寄存器,享受终生大保健VIP待遇,下层函数调用一定会给留个位的,走,去do_filp_open栈上逛逛。
 
dis给do_filp_open一照,嘿,上帝对咱是true love了,第2个push就把r14留do_filp_open栈上了,下班收工指日可待了这不。
调转枪头再来看一眼前面让我们绝望的"bt -FF"的栈,根据汇编基础知识,linux x64调用函数先将返回地址压栈,调用do_filp_open后再将rbp压栈,最后就是我们朝思暮想的r14了,所以从do_filp_open栈底数第3个就是tmp了,抓!!!
原来是用的第三方库openssl里面会打开一个编译机上的openssl.cnf文件,刚好在编译机的/mnt目录下,而/mnt目录是NAS等网盘默认挂载路径,当NAS出现异常时(如在有文件被占用情况下卸载NAS),此时访问NAS文件目录都会hang住,导致进程hang。
 
3.后记
上面的例子上帝开的窗有点多,通过保存了函数参数的局部变量,咱们很快就真相大白了,但是如果万一万一非常点背,我们要找的函数参数就是没有在局部变量中保存,那怎么办呢。这种情况一般是不会有的,因为重要的参数只要有需要,就会传递到某一层函数局部变量中,耐心点找找就会有的,如果确实没有,可能就需要更耐心的分析整个调用栈,看看哪里会有些勾勾搭搭的局部变量,寄存器没有被破坏,也终究是可以抓出来的。
From:https://www.cnblogs.com/organic/p/18441685
本文地址: http://www.shuzixingkong.net/article/2417
0评论
提交 加载更多评论
其他文章 Js运算符(操作符)
算数运算符 a = 1 + 1 // 2 a = 10 - 5 // 5 a = 10 / 5 // 2 a = 10 / 0 // js中除以0不会报错,结果是Infinity a = 2*2 // 4 a = 2**2 // a = 10 % 4 // 取余,2 js中算数运算,除了字符串的加法
理解 Vue 的 setup 应用程序钩子
title: 理解 Vue 的 setup 应用程序钩子 date: 2024/9/30 updated: 2024/9/30 author: cmdragon excerpt: 摘要:本文详细介绍了Vue 3中setup函数的应用,包括其概念、特性、使用方法及重要性。setup函数作为组合API的
理解 Vue 的 setup 应用程序钩子 理解 Vue 的 setup 应用程序钩子
记一次Razor Pages无法编译问题及解决
解决方案写在前面:更新Visual Studio及相关组件,本人版本自17.8.0更新至17.11.4 缘起于公司的一个业务接口,在有一些信息需要在应用内嵌的webview中展示,信息不少,涉及的前端技术不复杂,但是拼字符串太罗嗦,所以想到了添加一个Razor页面,所以,常规逻辑,在服务上注册&#3
记一次Razor Pages无法编译问题及解决 记一次Razor Pages无法编译问题及解决 记一次Razor Pages无法编译问题及解决
PasteForm最佳CRUD实践,实际案例PasteTemplate详解之3000问(三)
作为“贴代码”力推的一个CRUD实践项目PasteTemplate,在对现有的3个项目进行实战后效果非常舒服!下面就针对PasteForm为啥我愿称为最佳CRUD做一些回答: 哪里可以下载这个PasteForm的项目案例 目前“贴代码”对外使用PasteForm的项目有"贴Builder(
PasteForm最佳CRUD实践,实际案例PasteTemplate详解之3000问(三) PasteForm最佳CRUD实践,实际案例PasteTemplate详解之3000问(三) PasteForm最佳CRUD实践,实际案例PasteTemplate详解之3000问(三)
五,MyBatis-Plus 当中的 “ActiveRecord模式”和“SimpleQuery工具类”(详细实操)
五,MyBatis-Plus 当中的 “ActiveRecord模式”和“SimpleQuery工具类”(详细实操) @目录五,MyBatis-Plus 当中的 “ActiveRecord模式”和“SimpleQuery工具类”(详细实操)1. ActiveRecord 模式2. ActiveRec
五,MyBatis-Plus 当中的 “ActiveRecord模式”和“SimpleQuery工具类”(详细实操) 五,MyBatis-Plus 当中的 “ActiveRecord模式”和“SimpleQuery工具类”(详细实操) 五,MyBatis-Plus 当中的 “ActiveRecord模式”和“SimpleQuery工具类”(详细实操)
只写后台管理的前端要怎么提升自己
本人写了五年的后台管理。每次面试前就会头疼,因为写的页面除了表单就是表格。抱怨过苦恼过也后悔过,但是站在现在的时间点回想以前,发现有很多事情可以做的更好,于是有了这篇文章。 本文首发在 https://juejin.cn/post/7360528073631318027 写优雅的代码 一道面试题 大
.Net 依赖注入深入探索,做一个DI拓展,实现一个简易灵活的 自动依赖注入框架
一、依赖注入相关知识 1.1、依赖注入的原理和优点 依赖注入(DI),是IOC控制反转思想 的实现。由一个DI容器,去统一管理所有的服务生命周期,服务的创建、销毁、获取,都是由DI容器去处理的。 依赖注入,很大程度解耦了服务之间的依赖关系,服务之间依赖的是抽象(依赖的是 服务/服务接口 的 “类型”
实时语音交互,打造更加智能便捷的应用
随着人工智能和自然语言处理技术的进步,用户对智能化和便捷化应用的需求不断增加。语音交互技术以其直观的语音指令,革新了传统的手动输入方式,简化了用户操作,让应用变得更加易用和高效。 通过语音交互,用户可以在不方便使用触屏操作例如驾驶、烹饪时通过语音指令进行操作;在需要输入大量文本时,通过语音输入,可以
实时语音交互,打造更加智能便捷的应用 实时语音交互,打造更加智能便捷的应用 实时语音交互,打造更加智能便捷的应用