软件调试学习笔记(四)—— 异常的处理流程
软件调试学习笔记(四)—— 异常的处理流程
- 要点回顾
- 异常的处理流程
- 实验1:理解调试器与异常的关系
- 未处理异常:最后一道防线
- 实验2:理解UnhandledExceptionFilter执行流程
- 实验3:利用UnhandledExceptionFilter实现反调试
要点回顾
调试事件有多重类型、例如DLL加载、进程创建、线程创建等等。
其中最关键的调试事件是”异常“。
在调试过程中,不论是软件断点、硬件断点还是INT 3断点,都是通过异常来实现的。
异常的处理流程
流程图:
实验1:理解调试器与异常的关系
1)编译并运行以下代码:
#include <stdio.h>
#include <windows.h>int main ()
{int x = 100;int y = 0;int z;_try{z = x / y; //除0异常printf("无法执行的代码 \n");}_except(1){printf("SEH异常处理代码 \n");}return 0;
}
执行结果:
2)设置调试器选项
3)使用调试器运行程序
程序停在40104E处,由于调试器没有除0异常处理代码,因此无法继续向下执行。
4)手动模拟异常处理,将[ebp-0x20]的值改为1,继续运行
程序成功向下运行。
思考:会不会存在某种异常没人处理的情况
答案:不存在,因为有UnhandledExceptionFilter(未处理异常)
未处理异常:最后一道防线
描述:在前面异常相关章节已经学习,任何一个线程,在启动时都会先布置最后一道防线。
__try
{}
__except(UnhandledExceptionFilter(GetExceptionInformation())
{//终止线程//终止进程
}
UnhandledExceptionFilter执行流程:
1)通过NtQueryInformationProcess查询当前进程是否正在被调试,如果是,返回EXCEPTION_CONTINUE_SEARCH,此时会进入第二轮分发。
2)如果没有被调试:
- 查询是否通过SetUnhandledExceptionFilter注册处理函数,如果有就调用。
- 如果没有通过SetUnhandledExceptionFilter注册处理函数,弹出窗口,让用户选择终止程序还是启动即时调试器。
- 如果用户没有启用即时调试器,那么该函数返回EXCEPTION_EXECUTE_HANDLER。
实验2:理解UnhandledExceptionFilter执行流程
1)编译以下代码
#include <stdio.h>
#include <windows.h>int main ()
{int x = 100;int y = 0;int z;_try{z = x / y; //除0异常printf("无法执行的代码 \n");}_except(0){printf("SEH异常处理代码 \n");}getchar();return 0;
}
2)双击运行程序
结论:
1)由于当前进程并未处于调试状态,因此不会调用UnhandledExceptionFilter。
2)由于当前程序并未使用SetUnhandledExceptionFilter注册处理函数,因此会让用户选择是否启动调试器。
通过UnhandledExceptionFilter的这个性质,可以借此实现反调试。
实验3:利用UnhandledExceptionFilter实现反调试
1)编译并运行以下代码:
#include <stdio.h>
#include <windows.h>DWORD g_Test = 0;LONG NTAPI TopLevelExcepFilter(PEXCEPTION_POINTERS pExcepInfo)
{printf("顶级异常处理器修复异常 \n");g_Test = 1;return EXCEPTION_CONTINUE_EXECUTION;
}int main ()
{int r = 0;int x = 100;SetUnhandledExceptionFilter(&TopLevelExcepFilter);r = x / g_Test; //除0异常printf("正常逻辑开始执行 \n");for(int i=0; i<10; i++){Sleep(1000);printf("%d \n", i);}getchar();return 0;
}
编译器运行结果:
双击运行结果:
由于调试器不会触发SetUnhandledExceptionFilter设置的顶层异常,因此程序处于被调试状态时无法回归到正常逻辑;且调试器在处理异常时,若处理结果与程序所需不符,程序也将无法得以正常执行。
软件调试学习笔记(四)—— 异常的处理流程相关推荐
- 软件调试学习笔记(三)—— 调试事件的处理
软件调试学习笔记(三)-- 调试事件的处理 要点回顾 调试事件的处理 实验一:实现简单调试器(创建进程) 实验二:分析异常来源 实验三:实现简单调试器(附加进程) 实验四:分析NtDebugActiv ...
- 软件调试学习笔记(七)—— 单步步入单步步过
软件调试学习笔记(七)-- 单步步入&单步步过 单步步入 设置单步异常 处理单步异常 实验1:单步异常的设置与处理 单步步过 实现思路 实验2:实现单步步过 单步步入 描述: 单步步入的实现依 ...
- 软件调试学习笔记(六)—— 硬件断点
软件调试学习笔记(六)-- 硬件断点 硬件断点 设置硬件断点 触发硬件断点 处理硬件断点 实验:硬件断点的设置与处理 硬件断点 描述: 与软件断点与内存断点不同,硬件断点不依赖被调试程序,而是依赖于C ...
- 软件调试学习笔记(五)—— 软件断点内存断点
软件调试学习笔记(五)-- 软件断点&内存断点 调试的本质 软件断点 软件断点的执行流程 分析INT 3执行流程 实验:处理软件断点 内存断点 内存断点的执行流程 实验:处理内存断点 调试的本 ...
- 软件调试学习笔记(二)—— 调试事件的采集
软件调试学习笔记(二)-- 调试事件的采集 要点回顾 调试事件的种类 调试事件采集函数 例:分析PspUserThreadStartup 例:分析PspExitThread 总结 要点回顾 调试器与被 ...
- 软件调试学习笔记(一)—— 调试对象
软件调试学习笔记(一)-- 调试对象 准备工作 调试器与被调试程序 DebugActiveProcess 连接调试器 分析kernel32!DebugActiveProcess 分析ntdll!Dbg ...
- TDDFT计算软件Octopus学习笔记(四):带隙优化方法
密度泛函理论是一种基态的理论,然而能带结构和带隙属于物质的激发态特性.因此DFT的固有缺点就是会低估带隙能量.这一缺点可以通过不同的方式加以修正.本文介绍两种方法. (一) DFT+U方法 (以ZnO ...
- 敏捷软件开发学习笔记(四)之结构型设计模式
PHP结构型设计模式 参考 设计模式 PHP 设计模式全集 2018 什么是结构型是设计模式 结构型模式讲的是如何将类和对象按照某种布局组成更大的结构.它分为类结构型模式和对象结构型模式,其中类结构型 ...
- Windows软件调试学习笔记(1)
--WINDBG中的表达式 WINDBG接受两种表达式,C++表达式和MASM表达式. 1. MASM表达式中的数值: MASM表达式中的数值可以基于16,10,8,2四种进制.用n命令可以设置WIN ...
最新文章
- (017)java后台开发之客户端通过HTTP获取接口Json数据
- turbo c图形方式下编程小技巧
- boost::intrusive::bucket_traits用法的测试程序
- HDU4911 Inversion 解题报告
- JDK8新特性(十)之Stream流的map和reduce组合使用、mapToInt()、concat()方法
- 简洁/易用/灵活/高效-RecyclerView适配器封装
- Python-密码字典生成
- 米字格图片可打印_练字本米字格模板可打印行楷书
- Spring Boot 集成maven和Spring boot的profile功能
- MATLAB基础知识零基础到入门(第一期 基础内容)
- android闹铃唤醒软件,温柔唤醒闹钟app_温柔的闹钟铃声有哪些_华为智能闹钟智能唤醒-多特软件站安卓网...
- Fiddler数据抓包试玩改包工具使用畅享
- 利用阿里大鱼发送短信验证
- 28 电子商务风险控制
- 2021 ICPC 四川省赛 L - Spicy Restaurant(多源BFS,DP)
- 怎样编写html购物车结算页面,原生JS实现购物车结算功能
- 这9道软件测试面试题,就能刷掉90%的软件测试员
- SSH + Lucene + 分页 + 排序 + 高亮 模拟简单新闻网站搜索引擎
- java tcp 心跳机制_Java实现心跳机制的方法
- 2012年北航研究生入学考试机试题
热门文章
- Blockchain:《Blockchain applications in insurance》Deloitte—德勤区块链技术研究报告正文版—听课记录
- SQL:使用备份向导、SQL命令、导出数据三种方式对已建立的数据库进行备份
- 关于ML.NET v0.7的发布说明
- Python基础教程【读书笔记】 - 2016/7/5
- ubuntu14.04LS中安装sogouPingyin
- STM32F系列USART的IDLE中断要注意了
- STM32的CAN总线的接收双FIFO使用方法
- 原野小年总共拍了多少_开一家羽毛球馆大概需要投资多少钱
- Keras学习代码—github官网examples
- stdthread(1)thread概述