CPU异常与软件模拟异常调用流程与区别

异常与调试是紧密相连的。
异常记录:
1.要记录异常信息
2.异常是什么类型
3.异常是在什么位置发生的
异常的分发:
上面的信息记录下来以后,寻找处理异常的函数。
这个过程为异常的分发
异常处理:
最后找到异常处理函数并调用(异常处理)
异常记录,异常分发,异常处理。

异常的分类:
(本质上大体的分类)
1.CPU产生的异常
一定是CPU发现的
2.软件模拟产生的异常
高级语言模拟产生的异常
CPU异常的产生:
CPU指令检测到异常(例如:除0) --> 查IDT表,执行中断处理函数 --> CommonDispatchException(把异常相关的信息存到一个结构体) --> KIDispatchException
(3环进0环,先保存现场)
异常信息存储到了下面这个结构体里面:
typedef struct _EXCEPTION_RECORD {
DWORD ExceptionCode; //异常代码
DWORD ExceptionFlags; //异常状态
struct _EXCEPTION_RECORD *ExceptionRecord; //下一个异常
PVOID ExceptionAddress; //异常发生地址
DWORD NumberParameters; //附加参数个数
ULONG_PTR ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS]; //附加参数指针
} EXCEPTION_RECORD;
ExceptionFlags:
CPU产生的异常,这个值是0,软件产生的异常,这里存的值是1
_EXCEPTION_RECORD *ExceptionRecord:
通常是空的,出现嵌套异常的情况下,就是这个异常的处理程序执行的时候,又发生异常了,会通过这个指针指向下一个异常。
DWORD NumberParameters; //附加参数个数
ULONG_PTR ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS]; //附加参数指针
用来进一步描述异常的信息,用的不多。

在上面那个除0异常例子中:
CommonDispatchException(它要做的事就事把这些值存到在堆栈中构建的结构体)的反汇编中
Mov ebx,[ebp+68h]:
[ebp+68h]指向的是eip,eip记录的就是异常发生的地址ExceptionAddress
Mov eax,0C0000094h:
0C0000094h代表的是异常的类型,不同的异常有不同的值,这个值是微软定义的。
总结:
CPU异常执行的流程:
1.CPU指令检测到异常
2.查IDT表,执行中断处理程序(它并不会直接处理异常,把机会先留给程序员了)
3.调用CommonDispatchException(构建EXCEPTION_RECORD)
4.KIDispatchException(分发异常:目的找到异常处理的函数)
模拟异常的产生:
CxxThrowException -->
(KERNEL32.DLL)RaiseException(DWORD dwExceptionCode,DWORD dwExceptionFlags,DWORD nNumberOfArguments,const ULONG_PTR *lpArfuments) -->
NTDLL.DLL!RtlRaiseException() -->
NT!NtRaiseException -->
NT!KiRaiseException

(KERNEL32.DLL)RaiseException分析:
1.将参数中的值填充到EXCEPTION_RECORD这个结构体中
typedef struct _EXCEPTION_RECORD
{
DWORD ExceptionCode; //异常代码
DWORD ExceptionFlags; //异常状态
struct _EXCEPTION_RECORD *ExceptionRecord; //下一个异常
PVOID ExceptionAddress; //异常发生地址
DWORD NumberParameters; //附加参数个数
ULONG_PTR ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS]; //附加参数指针
} EXCEPTION_RECORD;
与CPU异常产生流程的两点不同:
1.CPU中ExceptionCode每种不同类型的异常,都对应不同的32位的值。软件模拟异常中的ExceptionCode 和当前的编译环境有关。相同编译环境下的值也是相同的。
2.CPU中ExceptionAddress异常会记录异常的位置,记录的是真正的异常时哪里发生的。软件模拟异常中的ExceptionAddress 存储的是一个固定的值,而这个值是RaiseException 这个函数的地址。
KiRaiseException分析:
1.EXCEPTION_RECORD.ExceptionCode 最高位清0(目的是区分CPU异常与软件模拟异常)
2.调用KIDispatchException ,开始分发异常

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值