Windows异常学习笔记(二)—— 内核异常处理流程用户异常的分发
Windows异常学习笔记(二)—— 内核异常处理流程&用户异常分发
- 用户层与内核层异常
- 内核异常
- 分析 KiDispatchException
- 分析 RtlDispatchException
- _EXCEPTION_REGISTRATION_RECORD
- 用户异常的分发
- 用户异常
- 分析 KiDispatchException
- 总结:用户异常处理流程
用户层与内核层异常
描述:
- 异常可以发生在用户空间,也可以发生在内核空间
- 无论是CPU异常还是模拟异常,是用户层异常还是内核异常,都要通过 KiDispatchException 函数进行分发,理解这个函数是学好异常的关键
内核异常
分析 KiDispatchException
声明:
VOID KiDispatchException(ExceptionRecord,ExceptionFrame,TrapFrame,PreviousMode,FirstChance);
处理逻辑:
- 调用 _KeContextFromKframes,由于操作系统不知道分发的异常到底是3环的异常还是0环的异常,如果是3环的异常,进0环前的环境会被备份到Trap_Frame中,如果要在中途回到3环的话,就需要将 Trap_frame 备份到 context,为返回3环做准备
- 判断先前模式,0是内核调用,1是用户层调用,此时能够知道要分发的异常来自哪里。
- 是否是第一次调用
- 是否有内核调试器
- 如果没有或者内核调试器不处理,调用RtlDispatchException,寻找异常处理函数
- 如果RtlDispatchException返回FALSE,也就是0
- 再次判断是否有内核调试器,有就调用,没有会直接蓝屏
分析 RtlDispatchException
作用:
- 遍历异常链表,调用异常处理函数,如果异常被正确处理了,该函数返回
- 如果当前异常处理函数不能处理该异常,那么调用下一个,以此类推
- 如果到最好也没有人处理这个异常,返回0
反汇编:
可以发现,RtlDispatchException 调用了 RtlpGetRegistrationHead,RtlpGetRegistrationHead的唯一作用就是获取fs寄存器的值给eax
当程序位于0环是,FS寄存器指向KPCR,而KPCR的第一个成员又指向_EXCEPTION_REGISTRATION_RECORD这样一个结构体
_EXCEPTION_REGISTRATION_RECORD
声明:
typedef struct _EXCEPTION_REGISTRATION_RECORD {struct _EXCEPTION_REGISTRATION_RECORD *Next;PEXCEPTION_ROUTINE Handler;
} EXCEPTION_REGISTRATION_RECORD;
描述:
- _EXCEPTION_REGISTRATION_RECORD位于当前线程的堆栈中
- Next指向下一个结构体,Handler指向异常处理函数,是一个链表结构
- 当调用RtlDispatchException时,按顺序执行异常处理函数,若其中一个异常处理函数返回结果为真,就不再继续向下执行
- 若执行完所有异常处理函数后,异常仍然没有被处理,那么就返回FALSE
用户异常的分发
描述:
异常如果发生在内核层,处理起来比较简单,因为异常处理函数也在0环,不用切换堆栈,但是如果异常发生在3环,就意味着必须要切换堆栈,回到3环执行处理函数
切换堆栈的处理方式与用户APC的执行过程几乎是一样的,惟一的区别就是执行用户APC时返回3环后执行的函数是KiUserApcDispatcher,而异常处理时返回3环后执行的函数是KiUserExceptionDispatcher
理解用户APC的执行过程是理解3环异常处理的关键
用户异常
描述:当异常发生时,无论是CPU异常还是模拟异常,最终在0环都要通过一个函数进行分发处理,这个函数就是KiDispatchException
VOID KiDispatchException(ExceptionRecord,ExceptionFrame,TrapFrame,PreviousMode,FirstChance);
注意:需先掌握用户APC执行过程
分析 KiDispatchException
- 将Trap_frame被分到context为返回3环做准备,因为目前不确定是从0环进来还是从3环进来
- 判断先前模式,0是内核调用,1是用户层调用
3. 从loc_42590B向下分析,是在为TRAP_FRAME结构体赋值,准备结束
总结:用户异常处理流程
- _KeContextFromKframes将Trap_frame被分到context为返回3环做准备
- 判断席安全模式,0是内核调用,1是用户层调用
- 是否都是第一次机会
- 是否有内核调试器
- 发送给3环调试
- 如果3环调试器没有处理这个异常,修正EIP为KiUserExceptionDispatcher
- KiUserExceptionDispatcher函数执行结束:CPU异常与模拟异常返回地点不同
CPU异常:CPU检测到异常→查IDT执行处理函数→CommonDispatchException→KiDispatchException通过IRETD返回3环 模拟异常:CxxThrowException→RaiseException→RtlRaiseException→NT!NtRaiseException→NT!KiRaiseException→KiDispatchException通过系统调用返回3环
Windows异常学习笔记(二)—— 内核异常处理流程用户异常的分发相关推荐
- Windows异常学习笔记(五)—— 未处理异常
Windows异常学习笔记(五)-- 未处理异常 要点回顾 最后一道防线 实验一:理解最后一道防线 实验二:新线程的最后一道防线 总结 UnhandledExceptionFilter 实验三:理解U ...
- Windows异常学习笔记(四)—— 编译器扩展SEH
Windows异常学习笔记(四)-- 编译器扩展SEH 要点回顾 编译器支持的SEH 过滤表达式 实验一:理解_try_except 实验二:_try_except 嵌套 拓展SEH结构体 scope ...
- Windows异常学习笔记(一)—— CPU异常记录模拟异常记录
Windows异常学习笔记(一)-- CPU异常记录 基础知识 异常的分类 CPU异常 分析中断处理函数 _KiTrap00 分析 CommonDispatchException 总结 软件模拟异常 ...
- Windows APC学习笔记(二)—— 挂入过程执行过程
Windows APC学习笔记(二)-- 挂入过程&执行过程 基础知识 挂入过程 KeInitializeApc ApcStateIndex KiInsertQueueApc Alertabl ...
- Windows系统调用学习笔记(二)—— 3环进0环
Windows系统调用学习笔记(二)-- 3环进0环 要点回顾 基本概念 _KUSER_SHARED_DATA 0x7FFE0300 实验:判断CPU是否支持快速调用 第一步:修改EAX=1 第二步: ...
- Windows系统调用学习笔记(三)—— 保存现场
Windows系统调用学习笔记(三)-- 保存现场 要点回顾 基本概念 Trap Frame 结构 线程相关的结构体 ETHREAD KTHREAD CPU相关的结构体 KPCR _NT_TIB KP ...
- Windows消息机制学习笔记(三)—— 消息的接收与分发
Windows消息机制学习笔记(三)-- 消息的接收与分发 要点回顾 消息循环 消息队列 消息的接收 GetMessage 实验1:理解GetMessage 第一步:编译并运行程序A 第二步:编译并运 ...
- Windows APC学习笔记(一)—— APC的本质备用APC队列
Windows APC学习笔记(一)-- APC的本质&备用APC队列 基础知识 APC的本质 APC队列 APC结构 分析 KiServiceExit 总结 备用APC队列 挂靠环境下Apc ...
- Windows系统调用学习笔记(四)—— 系统服务表SSDT
Windows系统调用学习笔记(四)-- 系统服务表&SSDT 要点回顾 系统服务表 实验:分析 KiSystemService 与 KiFastCallEntry 共同代码 SSDT 实验: ...
最新文章
- 博客已经迁移至 http://barretlee.com/entry/,时而同步分享到这里
- 开始报名丨CCF C³-05@亚马逊云科技:未来云计算之旅
- 公式编辑公式总是偏上怎么办?
- js ajax上传图片到服务器
- Android 监控网络状态
- html中post语句,html中post乱码的解决方法
- android 对话框 重复,如何在Android上重复使用AlertDialog for Yes / No?
- codevs 5958 无
- 自增主键为什么不是连续的?
- paip.invalid conversion from FormWdg* to SOCKET {aka unsigned int}
- 网易云音乐歌曲带时间轴歌词的提取
- servlet的九大内置对象和四大作用域
- 我们的青春已落幕,用 Python 分析韦德职业生涯数据
- 服务器右键文件夹不显示共享,右键不出现共享菜单 文件或文件夹不能共享怎么办?...
- PLUS模型教程2:数据前期准备和土地利用数量预测
- 集线器,交换机与路由器
- 1.3 guessing game
- 大数据中一些常用软件
- 已解决:出现了自己签名的证书。 错误: 证书通用名 “www.doctorcom.com” 与所要求的主机名 “raw.githubusercontent.com” 不符。
- 敏捷开发中如何写好用户故事?
热门文章
- Interview:算法岗位面试—上海某公司算法岗位(偏图像算法,互联网科技行业)技术面试考点之区块链的TPS等问题
- ModelFileType:XML、Hdf5、dat等不同模型文件后缀文件的简介、使用方法之详细攻略
- ML与math:机器学习与高等数学基础概念、代码实现、案例应用之详细攻略——进阶篇
- 成功解决Remix Mock compiler: Source not found
- 深度学习中常用的误差方法
- Using Preferences(Beginning Android)
- utf-8 字符串转为Unicode编码格式
- HaoheDI让ETL变得简单
- Laravel的console使用方法
- MySQL中用decimal的原因