INT3断点

INT3断点是利用0Xcc指令实现的,cpu在执行0xcc指令时会引发断点异常调试器会捕捉这个异常。

INT3断点引发的异常属于陷阱型异常,在执行完0xcc指令后eip指向下一条指令。但是系统对int3有特殊处理,当异常第一次分发时如果调试器没有处理那么第二次异常分发之前系统会令eip-1。

下面写个调试程序来看一下。

#include <Windows.h>
#include <iostream>using namespace std;
int flag = 0; //标志是第一次断点异常,还是第二次断点异常
int main()
{
char a[256] = {0};
cout<<"请输入需要调试的目标程序的路径:";
cin>>a;
PROCESS_INFORMATION pi; //接受新进程的一些有关信息
STARTUPINFO si; //指定新进程的主窗体如何显示
DEBUG_EVENT devent; //消息事件
CONTEXT stContext; //线程信息块 GetStartupInfo(&si); CreateProcessA(
a,
NULL,
NULL,
NULL,
FALSE, // 不可继承
DEBUG_ONLY_THIS_PROCESS | DEBUG_PROCESS, // 调试模式启动
NULL,
NULL,
&si,
&pi );
cout<<"创建进程成功"<<endl; while(TRUE)
{
if(WaitForDebugEvent(&devent, INFINITE))
{
switch(devent.dwDebugEventCode)
{
case EXCEPTION_DEBUG_EVENT:
switch(devent.u.Exception.ExceptionRecord.ExceptionCode)
{
case EXCEPTION_BREAKPOINT: //断点异常 if(devent.u.Exception.dwFirstChance == 1) //第一次异常分发
{
cout<<"第一次异常。 ";
cout<<"eip:";
stContext.ContextFlags = CONTEXT_FULL;
GetThreadContext(pi.hThread, &stContext);
int n1 = GetLastError();
cout<<stContext.Eip<<endl;
flag = 1;
}
if(devent.u.Exception.dwFirstChance == 0) //第二次异常分发
{
cout<<"第二次异常。 ";
cout<<"eip:";
GetThreadContext(pi.hThread, &stContext);
cout<<stContext.Eip<<endl;
flag = 0;
}
break;
}
break;
} }
if(flag == 1) //如果是第一次碰见int3断点异常,我们不处理他,让他直接继续进行第二次异常分发
ContinueDebugEvent(devent.dwProcessId, devent.dwThreadId, DBG_EXCEPTION_NOT_HANDLED);
else //如果是第二次碰见int3断点异常或者是其他调试事件我们直接返回让程序继续运行
{
flag = 0;
ContinueDebugEvent(devent.dwProcessId, devent.dwThreadId, DBG_CONTINUE);
}
}
return 0;
}

将一个不存在异常处理的程序第一条指令变为int3指令。

用上方程序作为例子进行调试,因为我们在第二次异常分发的时候返回DBG_CONTINUE来让系统认为我们处理了异常所以eip又会指向int3指令处,至此以后一直循环产生异常

OD中对int3的处理

我们把刚才的例子程序在od中运行并设置int3异常不交给程序处理



运行程序发现eip指向int3的下一条指令,这说明OD在int3异常第一次分发时因为eip指向了下一条指令,这时od返回DBG_CONTINUE意思是异常不交给程序处理直接返回。

如果设置忽略int3异常,即int3异常传递给程序处理。

因为程序没有异常处理所以第一次异常传给程序后,异常又会进行二次分发。我们运行程序发现eip依然指向int3指令处,继续运行发现程序依然指向int3处,这说明od默认第二次异常返回DBG_CONTINUE然后一直循环产生int异常(和我们文章开始写的那个调试程序一样)。

如果第二次异常时od没有返回DBG_CONTINUE来向系统说明异常已处理,而返回DBG_EXCEPTION_NOT_HANDLED的话异常将不会继续分发,程序将会被终止运行。(异常传到顶层异常处理处,执行了默认的异常处理函数结束运行)

我们把文章开始的调试器修改一下,把让第二次异常处理时返回DBG_EXCEPTION_NOT_HANDLED。


if(flag == 1) //如果是第一次碰见int3断点异常,我们不处理他,让他直接继续进行第二次异常分发
ContinueDebugEvent(devent.dwProcessId, devent.dwThreadId, DBG_EXCEPTION_NOT_HANDLED);
else //如果是第二次碰见int3断点异常或者是其他调试事件我们直接返回让程序继续运行
{
flag = 0;
ContinueDebugEvent(devent.dwProcessId, devent.dwThreadId,DBG_EXCEPTION_NOT_HANDLED);
}

再次拿原来的那个程序当例子进行调试,我们发现在第二次异常调试器返回DBG_EXCEPTION_NOT_HANDLED后调试程序结束运行。

开始调试前

开始调试后,异常第二次分发后异常没有继续分发,并且程序结束运行

关于调试器中int3断点引发异常的思考的更多相关文章

  1. ssis package 在调试状态中设置断点,程序 不进入断点 的解决方案

    原文:ssis package 在调试状态中设置断点,程序 不进入断点 的解决方案 针对 SSIS intergation 项目 > 属性 > Debug >Run64bITRunt ...

  2. 在Visual Studio调试器中显示Unreal的数据类型的值

    转自:https://blog.csdn.net/witton/article/details/5977766 在Unreal引擎中大量使用了自定义的数据类型如:FName,FString,TArra ...

  3. 用DebuggerDisplay在Visual Studio的调试器中定制类的显示方式

    博客搬到了fresky.github.io - Dawei XU,请各位看官挪步.最新的一篇是:用DebuggerDisplay在Visual Studio的调试器中定制类的显示方式.

  4. 在VisualStudio调试器中使用内存窗口和查看内存分布

    调试模式下内存窗口的使用 在调试期间,"内存"窗口显示应用使用的内存空间.调试器窗口(如"监视"."自动"."局部变量" ...

  5. 在 Visual Studio 调试器中指定符号 (.pdb) 和源文件

    查找并指定符号文件和源文件:指定符号加载行为.使用符号和源服务器上:加载符号自动或在要求.   内容 查找符号 (.pdb) 文件 查找源文件   查找符号 (.pdb) 文件 说明 在之前的 Vis ...

  6. @清晰掉 GDB调试器中的战斗机

    GDB 的命令很多,本文不会全部介绍,仅会介绍一些最常用的.在介绍之前,先介绍GDB中的一个非常有用的功能:补齐功能.它就如同Linux下SHELL中的命令补齐一样.当你输入一个命令的前几个字符,然后 ...

  7. 自定义Visual Studio调试器中的对象显示方式

    你有没有盯着调试器窗口中的对象,并希望你可以通过其他类型的东西来查看这些对象?我当然有!扩展项目以确定每个人的身份可能会非常快速.理想情况下,通过特定的属性值快速定位它们会很棒.对我们来说幸运的是,V ...

  8. 在Chrome调试器中引入jQuery

    在Console中输入以下代码并回车,Console显示"function (a,b){return new m.fn.init(a,b)}"说明导入成功,就可以在Console中 ...

  9. xcode 调试器 LLDB

    本文完全转载,转载地址:点击这里 你是否曾经苦恼于理解你的代码,而去尝试打印一个变量的值? NSLog(@"%@", whatIsInsideThisThing); 或者跳过一个函 ...

随机推荐

  1. Django1和2的区别

    一.路由的区别 1.Django1中的url from django.conf.urls import url # 使用url关键字 urlpatterns = [ url('article-(\d+ ...

  2. 使用Webpack构建多页面程序

    使用webpack搭建单页面程序十分常见,但在实际开发中我们可能还会有开发多页面程序的需求,因此我研究了一下如何使用webpack搭建多页面程序. 原理 将每个页面所在的文件夹都看作是一个单独的单页面 ...

  3. Amundsen在REA Group公司的应用实践

    REA Group是一家专门面向房地产与实业资产的跨国数字广告公司. 他们主要为消费者提供房地产购买.出售与租赁服务,同时发布各类房产新闻.装修技巧以及生活方式层面的内容.每一天,都有数百万消费者访问 ...

  4. vue 快速入门 系列 —— 侦测数据的变化 - [基本实现]

    其他章节请看: vue 快速入门 系列 侦测数据的变化 - [基本实现] 在 初步认识 vue 这篇文章的 hello-world 示例中,我们通过修改数据(app.seen = false),页面中 ...

  5. CPU 权限划分

    Intel的CPU将特权级别分为4个级别:RING0,RING1,RING2,RING3.Windows只使用其中的两个级别RING0和RING3,RING0只给操作系统用,RING3谁都能用.如果普 ...

  6. CrashLoopBackOff的解决办法之一

    问题来源 # kubectl get pods -n assembly NAME READY STATUS RESTARTS AGE alertmanager-858b7749c5-6jsfh 0/1 ...

  7. [Fundamental of Power Electronics]-PART I-2.稳态变换器原理分析-2.4 Cuk变换器实例

    2.4 Cuk 变换器 作为第二个示例,考虑图2.20(a)的变换器.该变换器执行类似于降压-升压变换器的直流转换功能:它可以增加或减小直流电压的幅值,并且可以反转极性.使用晶体管和二极管的实际实现如 ...

  8. [Fundamental of Power Electronics]-PART II-7. 交流等效电路建模-7.5 状态空间平均 7.6 本章小结

    7.5 状态空间平均 现有文献中已经出现了很多变换器交流建模的方法,其中包括电流注入法,电路平均和状态空间平均法.尽管某种特定方法的支持者可能更愿意使用该方法去建模,但所有方法的最终结果都是等效的.并 ...

  9. SpringCloudAlibaba—微服务概念及SpringCloudAlibaba介绍

    目录 1.1 系统架构演变 1.1.1 单体应用架构 1.1.2垂直应用架构 1.1.3 分布式架构 1.1.4 SOA架构 1.1.5 微服务架构 1.2 微服务架构介绍 1.2.1 微服务架构的常 ...

  10. 批处理文件设置IP以及DNS

    先附上批处理文件代码(批处理文件怎么创建自己另行百度,这里不再赘述) Echo offecho ==============请输入序号修改办公区===========echo *********1.家 ...