学逆向论坛

找回密码
立即注册

只需一步,快速开始

发新帖

450

积分

0

好友

15

主题
发表于 2021-1-25 20:47:28 | 查看: 7610| 回复: 1
本帖最后由 Print动 于 2021-1-25 20:50 编辑

****************本帖为个人学习笔记,若有错误内容,请各位大佬指点***************
异常与调试是紧密相连的。
异常记录:
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]指向的是eipeip记录的就是异常发生的地址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 ,开始分发异常
总结:
异常类型不同,仅仅是异常记录过程不同,异常进入分发阶段,就完全相同了
CPU异常                                软件模拟异常                       
|                                                                                                        |
IDT表,执行中断处理函数                         CxxThrowException
|                                                                                                         |
CommonDispatchException                                                            (KERNEL32.DLL)RaiseException
(填充ExceptionRecord结构体)                                                                                    (填充ExceptionRecord结构体)
             |                                                                                             |
             |                                                                                           NTDLL.DLL!RtlRaiseException()
             |                                                                                            |
             |                                                                                           NT!NtRaiseException
             |                                                                                           |
             |                                                                                          NT!KiRaiseException
             |                                                                                          ExceptionCode 最高位清0
               \                            /-------------------------------------/
                 \                        /
                    \                   /
                       \              /
                         \          /
                           \      /
                             \   /
                               \/
                       KIDispatchException ,开始分发异常


温馨提示:
1.如果您喜欢这篇帖子,请给作者点赞评分,点赞会增加帖子的热度,评分会给作者加学币。(评分不会扣掉您的积分,系统每天都会重置您的评分额度)。
2.回复帖子不仅是对作者的认可,还可以获得学币奖励,请尊重他人的劳动成果,拒绝做伸手党!
3.发广告、灌水回复等违规行为一经发现直接禁言,如果本帖内容涉嫌违规,请点击论坛底部的举报反馈按钮,也可以在【投诉建议】板块发帖举报。

    发表于 2021-1-26 17:36:45
    每天都有1次免费给楼主评分送学币的机会!

    小黑屋|手机版|站务邮箱|学逆向论坛 ( 粤ICP备2021023307号 )|网站地图

    GMT+8, 2024-11-24 04:13 , Processed in 0.172297 second(s), 44 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表