-
-
[原创]Windows内核学习笔记之异常(上)
-
发表于: 2021-12-30 12:14 26477
-
中断通常是由CPU外部的输入输出设备(硬件)所触发的,供外部设备通知CPU”有事情要处理“,因此又称为中断请求。中断请求的目的是希望CPU暂时停止执行当前执行的程序,转去执行中断请求所对应的中断处理例程。
与中断不同,异常通常是CPU在执行指令时,即当CPU在执行程序指令时遇到操作数有错误或检测到指令规范中定义的非法情况。前者的一个典型例子是执行除法指令时遇到除数为0,后者的典型例子包括在用户模式下执行特权指令等。第二种来源是某些特殊指令,这些指令的预期行为就是产生相应的异常,比如INT 3指令的目的就是产生一个断点异常,让CPU中断进调试器。换句话说,这个异常是”故意“产生的,是预料内的。这样的指令还有INTO,INT O和BOUND。第三种来源是奔腾CPU引入的机器检查异常,即当CPU执行指令期间检测到CPU内部或外部的硬件错误。
中断与异常的根本差异是:异常来自于CPU本身,是CPU主动产生的;而中断则是来源于外部设备,是中断源发起的,CPU是被动的。
根据CPU报告异常的方式和导致异常的指令是否可以安全地重新执行,IA-32 CPU把异常分为3类:错误(fault),陷阱(trap)和中止(abort)。
导致错误类异常地情况通常可以被纠正,而且一旦纠正以后,程序可以无损失地恢复执行,此类异常最常见地一个例子就是缺页异常。
当CPU报告错误类异常时,CPU将其恢复成导致该异常的指令被执行之前的状态。而且在CPU转去执行异常处理程序前,在栈钟保存的CS和EIP指针是指向导致异常的这条指令(而不是下一条指令)。因此,当异常处理程序返回继续执行时,CPU接下来执行的第一条指令依然是刚才导致异常的那条指令。所以,如果导致异常的情况没有被消除,那么,CPU将会再次产生异常。
与错误类异常不同,当CPU报告陷阱类异常时,导致该异常的指令已经执行完毕,压入栈钟的CS和EIP值(即异常处理程序的返回地址)是导致该异常的指令执行后紧接着要执行的下一条指令。值得说明的是,下一条指令并不一定是与导致异常的指令相邻的下一条。如果导致异常的指令是跳转指令或函数调用指令,那么下一条指令可能是内存地址不相邻的另一条指令。
导致陷阱类异常的情况通常也是可以无损失地恢复执行的。比如INT 3指令导致的断点异常就属于陷阱类异常,该异常会使CPU中断到调试器,从调试器返回后,被调试器程序可以继续执行。
中止类异常主要是用来报告严重的错误,比如硬件错误和系统表中包含非法值或不一致的状态等。这类异常不允许恢复继续执行。原因有二:首先,当这类异常发生时,CPU并不总能保证报告的导致异常的指令地址是精确的。其次,出于安全性考虑,这类异常可能是由于导致该异常的程序执行非法操作导致的,因此就应该强迫其中止退出。
下表是这三类异常的关键特征:
在保护模式下,当有中断或异常发生时,CPU是通过中断描述符表(IDT)来寻找处理函数的。因此,可以说IDT是CPU(硬件)与操作系统(软件)交接的中断和异常的关口。操作系统在启动早期的一个重要任务就是设置IDT,准备好处理异常和中断的各个函数。每个中断或异常都被赋予了一个整数ID,称为向量号。系统根据向量号从IDT表中查找相应的中断或异常的处理例程。IA-32架构规定0~31号向量供CPU设计者使用,32~255号向量(224个)供操作系统和计算机系统生产厂商或其他软硬件开发商使用。下表归纳了PC系统中常见向量号对应的中断和异常:
CPU在同一时间只能执行一个程序,如果多个中断请求或异常情况同时发生,CPU就会按照优先级高低次序依次处理,先处理优先级最高的。下表是IA-32架构定义的10个中断/异常优先级别:
在操作系统层次有两类异常:
CPU异常(硬件异常):由CPU产生的
软件异常:通过软件方式模拟出的异常,比如调用RaiseException API而产生的异常和使用编程语言的throw关键字抛出的异常
无论是哪类异常,Windows操作系统都用EXCEPTION_RECORD结构来描述它,该结构的定义如下:
对于ExceptionFlags标志位,目前已定义的标志位如下:
EH_NONCONTINUABLE(1):该异常不可恢复继续执行
EH_UNWINDING(2):当因为执行栈展开而调用异常处理函数时,会设置此标志
EH_EXIT_UNWIND(4):也是用于栈展开,较少使用
EH_STACK_INVALID(8):当检测到栈错误时,设置此标志
EH_ENSTED_CALL(0x10):用于表示内嵌的异常
下图则是ExceptionCode对应的用于异常的状态码:
对于产生的CPU异常,处理器会根据IDT表查询到需要执行的函数,如下所示是部分产生了CPU异常以后会执行的处理例程:
以除0异常调用的KiTrap0为例,函数会首先对陷阱帧进行填充,然后对cs寄存器进行判断
接着对进程的成员进行判断,最终都会跳到loc_5074AB执行
loc_4075AB处的代码会对ebx和eax分别赋值为Eip和异常状态码,然后跳转到loc_407399
而loc_407399的代码仅仅是清空ecx,此时的ecx保存的其实是参数的个数,由于除0异常无需传参,所以ecx为0,而将其他信息作为附带参数(最多3个)的时候,会分别将参数放入EDX(参数一), ESI(参数二), EDI(参数三), 接着调用CommonDispatchException函数
CommonDispatchException会在栈上开辟空间,在根据传递的参数来为开辟的结构体EXCEPTION_RECORD赋值,随后调用KiDispatchException函数来完成异常的分发
软件异常的实现是需要取决于编译器的,对于vs2017来说,可以使用throw关键字来产生软件异常,该关键字是通过调用_CxxThrowException函数来实现的
而_CxxThrowException函数则会调用kernel32.dll中的RaiseException,此时的传入的第一个参数在RaiseException中会赋给ExceptionCode,此时是0xE06D7363,该值取决于编译器,每次调用的时候都是这个数值
在RaiseException函数中会开辟栈空间用来保存EXCEPTION_RECORD结构,异常发生的地址ExceptionAddress则固定为_RaiseException,而不是异常发生地址。随后调用ntdll.dll中的RtlRaiseException,该函数会将执行上下文(通用寄存器等)放入CONTEXT结构,然后通过系统服务调用机制调用内核函数KiRaiseException
NtRaiseException函数会继续调用KiRaiseException
KiRaiseException会将CONTEXT保存到TrapFrame中,调用KiDispatchException来实现异常的分发
综上所述,无论是CPU异常还是软件异常,尽管产生的原因不同,但最终都会调用内核中的KiDispatchException来分发异常,也就是说,Windows系统是使用统一的方法来分发CPU异常和软件异常
Windows内核中的KiDispatchException函数是分发各种Windows异常的枢纽。其函数原型如下:
下图为KiDispatchException函数的执行流程,该函数首先调用KeContextFromKframes函数来将参数TrapFrame中的内容保存到CONTEXT中,以供向调试器和异常处理器函数报告异常时使用,接下来根据先前模式来选择操作流程
根据IDA反汇编的结果可以看到KiDispatchException首先对局部变量进行赋值,然后再根据先前模式以及是否存在调试器来修改CONTEXT结构中的ContextFlags
将TrapFrame中的数据保存到Context中,判断是否为断点异常,如果是断点异常,将EIP减掉1
如果不是断点异常就会根据异常代码选择是否为KI_EXCEPTION_ACCESS_VIOLATION来选择是否要将异常代码改成EXCEPTION_ACCESS_VIOLATION
根据先前模式来选择执行流程
对于内核异常,首先会判断是否是第一次执行,如果是第一次执行就会继续判断是否存在内核调试器,如果存在内核调试器此时的KiDebugRoutine就会保存内核调试引擎的KdpTrap。如果该函数调用成功,返回值就会为1,否则会0
无论是不存在内核调试器还是KdpTrap函数执行失败,都会跳转到loc_4335A6处执行,此时会调用RtlDispatchException函数来处理异常,如果函数执行成功就会返回1,否则返回0
判断返回值是否为1,也就是是否成功处理了异常
如果为1,接下来就会将保存再CONTEXT结构中的数据复制到TrapFrame中,退出函数
如果为0,继续判断是否有内核调试器,如果有就继续调用KiDebugRoutine中保存的函数来处理异常
如果此时不存在内核调试器或者KiDebugRoutine中的函数没有处理掉异常,接下来就会产生蓝屏
如果处理掉了,就会跳转到上面的loc_424AC8来恢复陷阱帧,退出函数。退出函数以后,接下来就会返回到CommonDispatchException执行,该函数会通过iretd返回用户层。
对于用户异常,同样会首先判断是否是第一次执行,是的话继续判断是否存在内核调试器,如果存在内核调试器且调试端口为0,则会调用KdpTrap函数,如果返回值为1,即成功处理了异常,就会跳转到loc_424AC8退出函数
如果不存在内核调试器,或内核调试函数并没有成功处理异常,接下来就会通过调用函数DbgForwardException来将异常发给调试子系统处理,如果成功处理则返回1
如果没有处理成功,就会将陷阱帧中的EIP修改为_KiUserExceptionDispatcher,随后退出函数。这样,当程序返回到用户层的时候,就会执行函数_KiUserExceptionDispacher,该函数是在ntdll.dll中
在KiUserExceptionDispatcher中会通过调用RltDispatchException来处理异常,如果处理成功,返回值为1,接下来就会调用ZwContinue来修正陷阱帧中的EIP恢复执行
否则就会调用ZwRaiseException
ZwRaiseException就会再次进入内核层调用NtRaiseException
此时运行到KiDispatchException先前模式为用户模式清空下,判断是否为第一次运行的时候会跳转到loc_44B196运行,因为此时不是第一次运行
在loc_440F9E中,函数会两次调用DbgkForwardException来处理异常,如果处理成功,则返回值为1,然后正常退出函数,如果处理失败,接下来就会结束进程,出现蓝屏
无论是用户层还是内核层都会通过调用RtlDispatcherException来完成异常处理,只不过前者在ntdll.dll中,后者在内核中,两个函数功能和执行逻辑是基本一致的,不过由于“服务”对象不同,它们分别存在于两个模块中
从Windows XP系统开始,Windows支持通过以下两种异常处理机制来处理异常。
SEH:结构化异常处理机制
VEH:向量化异常处理机制
其中SEH既可以在用户模式下和内核模式下都可以使用,而VEH只能在用户模式下使用。在ntdll.dll中和内核中的异常处理函数RtlDispatchException最大的区别也就是ntdll.dll的异常处理函数是处理用户模式下的异常,此时会先调用函数RtlCallVectoredExceptionHandler函数通过VEH来处理异常,如果返回值非0,则处理完成,否则会继续通过SEH处理异常。
VEH的基本思想是通过注册以下原型的回调函数来接收和处理异常。
参数ExceptionInfo是指向EXCEPTION_POINTERS结构的指针,该结构包含了指向CONTEXT结构和异常记录结构的指针,定义如下:
通过AddVectoredExceptionHandler可以注册回调函数,如下是函数定义:
如果注册成功,返回值指向的是系统为该异常处理器分配的结构(VEH_REGISTERATION)指针,应用程序应该保存这个指针,以便销毁向量化异常处理器时使用;如果注册失败,返回值就为0。
在AddVectoredExceptionHandler内部,会为每个向量化异常处理器分配一个类型如下结构的长度(长为12字节)。
当有多个向量化异常处理器时,这些向量化异常处理器的VEH_REGISTRATION结构组成一个环状链表。ntdll.dll中的全局变量RtlpCalloutEntryList指向该链表的头。
RemoveVectoredExceptionHandler函数用来注销向量化异常处理器,也就是将一个向量化异常处理器从RtlpCalloutEntryList所指向的链表中移除,该函数定义如下:
其中的参数就是通过AddVectorExceptionHandler注册异常处理器成功时的返回值。
前面说过,和内核的异常处理函数相比,ntdll.dll中的异常处理函数会首先通过调用函数RtlCallVectoredExceptionHandler来给向量化异常处理器优先的处理机会。
RtlCallVectoredExceptionHandler会直接判断全局链表RtlpCalloutEntryList中是否有向量化异常处理器,如果没有则将al清空作为返回值,也就是返回FALSE
如果有的话,会对局部变量赋值,调用RtlEnterCriticalSection函数防止其他线程访问链表
接下来会遍历链表,通过RtlDecodePointer函数来=获得向量化异常处理器的回调函数,然后调用这个回调函数,此时压入会将pExceptRec的地址压入栈中,而紧邻该变量的地址保存的就是参数pContext,所以此时传入的其实是EXCEPTION_POINTERS结构体参数
如果成功处理异常,此时的返回值为-1,就会将局部变量赋值为1,跳转到loc_7C962647处执行代码
如果遍历完链表依然没有成功,就会将局部遍历赋值为0
赋值完以后执行的代码和成功处理异常以后执行的代码是一样的,此时将局部变量保存的结果赋给al作为返回值
最后退出函数
此时如果任何一个向量化异常处理器处理掉异常,那么返回值都会为1。如果都没处理,返回值为0,接下来就要通过结构化异常来处理异常。
为了让系统和应用程序代码都可以简单方便地支持异常处理,Windows系统定义了一套标准的机制来规范异常处理代码的设计(对程序员)和编译(对编译器),这套机制称为结构化异常处理。
从系统(广义)的角度看,SEH是Windows操作系统中的异常分发和处理机制的总称,其实现遍布在Windows系统的很多模块和数据结构中。
从编程(狭义)的角度看,SEH是一套规范,利用这套规范,程序员可以编写处理代码来复用系统的异常处理设施。可以将其理解为是操作系统的异常机制的对外接口,也就是如何在Windows程序中使用Windows系统的异常处理机制。
在用户模式下,fs:[0]寄存器指向的是线程环境块(TEB),TEB的起始处有一个称为线程信息块的结构(TIB)。而在内核模式下,fs:[0]指向的则是KPCR结构的开始处,其第一个成员也是线程信息块结构(TIB)。TIB结构包含了异常,线程栈等信息,该结构定义如下:
TIB起始处保存的是ExceptionList字段,所以fs:[0]的内容就是ExceptionList字段的内容,该字段是_EXCEPTION_REGISTRATION_RECORD结构体,定义如下:
根据定义可以知道,所有异常处理函数通过_EXCEPTION_REGISTRATION_RECORD结构保存在栈中。通过Next字段可以找到其下一个异常处理函数,当Next为0xFFFFFFFF(-1)的时候,代表没有下一个异常处理函数,Handler则指向了异常处理函数,指向的函数原型如下:
可以得出结论,系统可以通过fs:[0]这种便捷方式引用ExceptionList字段,获得一个链表的头指针,这个链表的每个节点是一个_EXCEPTION_REGISTRATION_RECORD结构,描述了一个结构化的异常处理器(handler),该链表通过成员Next连接起来。当有异常发生时,系统就可以通过Next成员,依次调用这个链表上的处理器来分发异常。
可以把结构化依次处理看作操作系统于用户代码协同处理软硬件依次的一种模型,而fs:[0]链条便是这二者的接口。当有异常需要处理时,操作系统通过fs:[0]链条来寻找异常处理器,给用户代码处理异常清空的机会
由上内容可知道,结构化异常处理器是要保存在栈上的。因此,可以用以下代码来登记一个结构化异常处理器:
其中第一行是将一个具有SEH标准的函数原型的处理函数地址,第二行将fs:[0],也就是字段ExceptionList的当前值入栈,栈上就建立了一个EXCEPTION_REGISTRATION_RECORD结构,栈顶地址便是这个结构的地址,因此,第3行把esp寄存器的内容赋给fs:[0],实质上就是把刚刚注册的异常处理器的地址赋给ExceptionList。当CPU继续指向这段代码的下面代码时候,如果有异常发生,那么系统在遍历fs:[0]链条时便会首先找到这个异常处理器,给其处理器机会。因此,以上代码片段一旦插入,那么它之后的代码便进入了它所安装的异常处理器的“保护”范围。
可以使用如下代码来注销前面登记的异常处理器:
此时esp指向的是刚注册的结构化异常处理器的EXCEPTION_REGISTRATION_RECORD结构体的地址,其第一个成员Next指向的是前一个异常登记结构的地址,将其赋给fs:[0],也就是赋给ExceptionList,这样,fs:[0]的内容就恢复到了安装这个结构化异常处理器前的状态。
对于ntdll.dll中的RtlDispatcherException,如果VEH没有成功处理异常,接着就会通过SEH来处理异常。
通过调用RtlpGetStackLimits来获取栈基址和栈界限
RtlpGetStackLimits函数实现如下(根据Tib结构可以知道,fs:[0x8]为栈边界,fs:[0x4]为栈基址):
调用RtlpGetRegistrationHead来获取ExceptionList字段
根据其函数实现可以知道,是将ExceptionList赋给eax
判断获取的ExceptionList的Next成员是否为-1
如果为-1,就会退出函数,此时局部变量var_res为0,将其赋给eax,就是指定返回值为0
判断ExceptionList是否在栈空间内以及其最低两位是否为1
如果任何一个条件不满足,接下来就会为ExceptionFlags赋值以后退出函数
如果都满足条件,接下来就会判断异常处理函数地址是否不在栈内,如果在栈内就会跳转到上面的loc_7C94A316退出函数,该机制就是为了支持DEP功能的
如果不在栈中,通过RtlIsValidHandler来判断异常处理函数是否合法,不合法的话依然会跳转到上面的loc_7C94A316退出函数,该机制是为了支持SAFESEH
通过验证以后就会通过RtlpExecuteHandlerForException来处理异常,并将返回值赋给edi
该函数返回值会是一个枚举类型EXCEPTION_DISPOSITION的常量,含义如下:
接下来就是根据返回值进行操作,首先判断是否为0,且ExceptionFlags是否满足条件,如果满足条件就会将局部变量var_res赋值为1,接下来就会继续执行上面的loc_4C994AA21的代码,将var_res的值赋给eax作为局部变量返回,代表处理成功,然后退出函数
如果ExceptionFlags不满足条件,会调用RtlRaiseException分发异常
如果返回值为1,且ExceptionFlags符合条件,就会跳转到上面的loc_7C94AA21处退出函数
否则就取出下一异常处理器,判断Next是否为-1,不为-1就会跳转到loc_7C94A994继续上面操作,为-1则退出函数
如果返回值不为0, 1, 2就会调用RtlRaiseException来分发异常
如果为2,对pNestedRegistration继续判断,如果地址小于pExecptRec,来决定是否要为pExecptRec赋值,随后跳转到上面的loc_7C94A306来取下一个异常处理器后继续执行上述循环过程
下图是对上述过程的展现:
对于异常处理函数RtlpExecuteHanlderForException,首先将函数地址SehHandler赋给edx,随后跳转到ExecuteHandler
而ExecuteHandler则是通过ExecuteHandler2实现的
ExecuteHandler2则是会将SehHandler函数登记到SEH异常链条中,随后在调用传入的函数,此时的edx在前面被赋值为SehHandler函数地址
异常处理的一个特征就是线程相关性。也就是说,异常的分发和处理是在线程范围内进行的,异常处理器的注册也是相对线程而言
从应用范围来:SEH既可以在用户态(应用程序)代码中,也可也在内核态(比如驱动程序)代码中,但VEH只能在用户态代码中。另外,VEH只有在XP或更高版本的Windows系统中才能使用。
从优先级的角度:对于同时注册了VEH和SEH的代码所触发的异常,VEH比SEH先得到处理权
从注册方式角度看:SEH的注册信息是以固定的结构存储在线程栈中,不同层次的各个SEH的注册信息依次被压入栈中,分布栈的不同位置,依靠结构内的指针和联系,因为人们经常将一个函数所对应的区域称为栈帧,所以结构化异常处理器又经常称为基于帧的异常处理器;VEH的注册信息是存储在进程的内存堆中
从作用域看:VEH处理器相对于整个进程都有效,具有全局性;结构化异常处理器是动态建立在所在函数的栈帧上,会随着函数的返回而注销,因此SEH只对当前函数所这个函数所调用的子函数有效
从编译角度看:SEH的注册和销毁都依靠编译器编译时所生成的数据结构与代码的,VEH的注册和销毁都是通过系统的API显示完成的,不需要编译器特殊处理
分类 | 报告时间 | 保存的CS和EIP指针 | 可恢复性 |
---|---|---|---|
错误 | 开始执行导致异常的指令时 | 导致异常的那条指令 | 可以恢复执行 |
陷阱 | 执行完导致异常的指令时 | 导致异常的那他指令的下一条指令 | 可以恢复执行 |
中止 | 不确定 | 不确定 | 不可以 |
向量号 | 助记符 | 门类型/类型 | 处理例程/TSS选择子 | 中断/异常 | 来源 |
---|---|---|---|---|---|
00 | #DE | 中断 | nt!KiTrap00 | 除0错误 | DIV和IDIV指令 |
01 | #DB | 中断 | nt!KiTrap01 | 调试异常,用于软件调试 | 任何代码或数据的引用 |
02 | 任务 | 0x0058 | NMI中断 | 不可屏蔽的外部中断 | |
03 | #BP | 中断 | nt!KiTrap03 | 断点 | INT 3指令 |
04 | #OF | 中断 | nt!KiTrap04 | 溢出 | INTO指令 |
05 | #BR | 中断 | nt!KiTrap05 | 数组越界 | BOUND指令 |
06 | #UD | 中断 | nt!KiTrap06 | 无效指令 | UD2指令或任何保留的指令 |
07 | #NM | 中断 | nt!KiTrap07 | 数学协处理器不存在或不可用 | 浮点或WAIT/FWAIT指令 |
08 | #DF | 任务 | 0x0050 | 双重错误 | 任何可能产生异常的指令,不可屏蔽中断或可屏蔽中断 |
09 | #MF | 中断 | nt!KiTrap09 | 协处理器段溢出 | 浮点指令 |
0A | #TS | 中断 | nt!KiTrap0A | 无效TSS | 任务切换或访问TSS |
0B | #NP | 错误 | nt!KiTrap0B | 段不存在 | 加载段寄存器或访问系统段 |
0C | #SS | 错误 | nt!KiTrap0C | 栈段错误 | 栈操作或加载SS寄存器 |
0D | #GP | 错误 | nt!KiTrap0D | 一般性保护 | 任何内存引用和保护性检查 |
0E | #PF | 错误 | nt!KiTrap0E | 页错误 | 任何内存引用 |
0F | 保留 | nt!KiTrap0F | |||
10 | #MF | 错误 | nt!KiTrap10 | 浮点错误 | 浮点或WAIT/FWAIT指令 |
11 | #AC | 错误 | nt!KiTrap11 | 内存对齐检查 | 对内存中数据的引用 |
12 | #MC | 中止 | nt!KiTrap12 | 机器检查 | 错误代码和来源于型号有关 |
13 | #XF | 错误 | nt!KiTrap13 | SIMD浮点错误 | SIMD浮点指令 |
14~1F | 保留 | nt!KiTrap0F | |||
20~28 | 保留 | NULL | 未使用 | ||
29 | nt!KiRaiseSecurityCheckFailure | 异常 | 用于支持Windows8引入的FailFast机制 | ||
2A | nt!KiGetTickCount | ||||
2B | nt!KiCallbackReturn | 从逆向调用返回 | |||
2C | nt!KiRaiseAssertion | 断言 | |||
2D | nt!KiDebugService | 调试服务 | |||
2E | nt!KiSystemService | 系统服务 | |||
2F | nt!KiTrap0F | ||||
30 | hal!Halp8254ClockInterrupt | IRQ0 | 时钟中断 | ||
31~3F | 驱动程序通过KINTERRUPT结构注册的处理例程 | IRQ1~IRQ15 | 其他硬件设备的中断 | ||
40~FD | nt!KiUnexpectedInterruptX | N/A | 没有使用 |
优先级 | 描述 |
---|---|
1(最高) | 硬件重启动和机器检查异常 |
2 | 任务切换陷阱 |
3 | 外部硬件(例如芯片组)通过CPU引脚发给CPU的特别干预 |
4 | 上一条指令导致的陷阱:执行INT3导致的断电;调试陷阱,包括单步执行异常(EFLAGS[TF]=1)和利用调试寄存器设置的数据或输入输出断点 |
5 | 不可屏蔽(外部硬件)中断(NMI) |
6 | 可屏蔽(外部硬件)中断 |
7 | 代码断点错误异常,即从内存取指令时检测到于调试寄存器中的断点地址相匹配,也就是利用调试寄存器设置的代码断点 |
8 | 取下一条指令时检测到的错误:违法代码段长度限制;代码内存页错误(即代码属性的内存页导致的错误) |
9 | 解码下一指令时检测到的错误:指令长度大于15字节(包括前缀);非法操作码;协处理器不可用 |
10(最低) | 指令指令时检测到的错误:溢出,当EFLAGS[OF]=1时执行INTO指令;执行BOUND指令时检测到边界错误;无效TSS;段不存在;栈异常;一般保护异常;数据页错误;对齐检查异常;x87 FPU异常;SIMD浮点异常 |
#define EXCEPTION_MAXIMUM_PARAMETERS 15 // maximum number of exception parameters
typedef struct _EXCEPTION_RECORD {
DWORD ExceptionCode;
DWORD ExceptionFlags;
struct _EXCEPTION_RECORD
*
ExceptionRecord;
PVOID ExceptionAddress;
DWORD NumberParameters;
ULONG_PTR ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS];
} EXCEPTION_RECORD;
#define EXCEPTION_MAXIMUM_PARAMETERS 15 // maximum number of exception parameters
typedef struct _EXCEPTION_RECORD {
DWORD ExceptionCode;
DWORD ExceptionFlags;
struct _EXCEPTION_RECORD
*
ExceptionRecord;
PVOID ExceptionAddress;
DWORD NumberParameters;
ULONG_PTR ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS];
} EXCEPTION_RECORD;
名称 | 作用 |
---|---|
ExceptionCode | 异常代码:一个32位的整数,其格式是Windows系统的状态代码格式 |
ExceptionFlags | 异常标志:它的每一位代表一种标志 |
ExceptionRecord | 相关的另一个异常:EXCEPTION_RECORD指针,指向与该异常相关的另一个异常记录,如果没有相关的异常,那么这个指针就会为空 |
ExceptionAddress | 异常发生地址:记录异常地址,对于硬件异常,它的值因为异常类型不同而可能是导致异常的那条指令的地址,或者是导致异常指令的下一条地址 |
NumberParameters | 参数数组中元素个数:ExceptionInformation数组中包含的有效参数个数,该结构允许存储15个附加参数 |
ExceptionInformation | 参数数组 |
.text:
00407522
_KiTrap00 proc near ; DATA XREF: INIT:_IDT↓o
.text:
00407522
.text:
00407522
var_2
=
word ptr
-
2
.text:
00407522
arg_4
=
dword ptr
8
.text:
00407522
.text:
00407522
; FUNCTION CHUNK AT .text:
00407399
SIZE
00000021
BYTES
.text:
00407522
.text:
00407522
push
0
; 填充ErrorCode
.text:
00407524
mov [esp
+
4
+
var_2],
0
.text:
0040752B
push ebp ; 填充Ebp
.text:
0040752C
push ebx ; 填充Ebx
.text:
0040752D
push esi ; 填充Esi
.text:
0040752E
push edi ; 填充Edi
.text:
0040752F
push fs ; 填充fs
.text:
00407531
mov ebx,
30h
.text:
00407536
mov fs, ebx ; 将fs指向KPCR
.text:
00407538
assume fs:nothing
.text:
00407538
mov ebx, large fs:
0
.text:
0040753F
push ebx ; 填充ExceptionList
.text:
00407540
sub esp,
4
; esp指向Eax
.text:
00407543
push eax ; 填充Eax
.text:
00407544
push ecx ; 填充Ecx
.text:
00407545
push edx ; 填充Edx
.text:
00407546
push ds ; 填充ds
.text:
00407547
push es ; 填充es
.text:
00407548
push gs ; 填充gs
.text:
0040754A
mov ax,
23h
.text:
0040754E
sub esp,
30h
; 将esp指向陷阱帧头部,也就是DbgEbp
.text:
00407551
mov ds, eax
.text:
00407553
assume ds:nothing
.text:
00407553
mov es, eax ; 将ds, es赋值为
0x23
.text:
00407555
assume es:nothing
.text:
00407555
mov ebp, esp ; 将ebp指向陷阱帧头部
.text:
00407557
test [esp
+
68h
+
arg_4],
20000h
; 判断是否为虚拟
8086
模式
.text:
0040755F
jnz short V86_kit0_a
.text:
00407561
.text:
00407561
loc_407561: ; CODE XREF: V86_kit0_a
+
25
↑j
.text:
00407561
cld
.text:
00407562
mov ebx, [ebp
+
60h
] ; 将ebp赋给ebx
.text:
00407565
mov edi, [ebp
+
68h
] ; 将Eip赋给edi
.text:
00407568
mov [ebp
+
0Ch
], edx ; 将edx赋给DbgArgPointer
.text:
0040756B
mov dword ptr [ebp
+
8
],
0BADB0D00h
; 为DbgArgMark赋值
.text:
00407572
mov [ebp
+
0
], ebx ; 填充DbgEbp
.text:
00407575
mov [ebp
+
4
], edi ; 填充DbgEip
.text:
00407578
test large byte ptr fs:
50h
,
0FFh
; 判断是否处于调试模式
.text:
00407580
jnz Dr_kit0_a
.text:
00407586
.text:
00407586
loc_407586: ; CODE XREF: Dr_kit0_a
+
10
↑j
.text:
00407586
; Dr_kit0_a
+
7C
↑j
.text:
00407586
test dword ptr [ebp
+
70h
],
20000h
; 判断是否处于虚拟
8086
模式
.text:
0040758D
jnz short loc_4075CC
.text:
0040758F
test byte ptr [ebp
+
6Ch
],
1
; 判断cs寄存器第
0
位是否有
1
.text:
00407593
jz short loc_40759C
.text:
00407595
cmp
word ptr [ebp
+
6Ch
],
1Bh
; 判断cs寄存器是否等于
0x1B
.text:
0040759A
jnz short loc_4075B9
.text:
00407522
_KiTrap00 proc near ; DATA XREF: INIT:_IDT↓o
.text:
00407522
.text:
00407522
var_2
=
word ptr
-
2
.text:
00407522
arg_4
=
dword ptr
8
.text:
00407522
.text:
00407522
; FUNCTION CHUNK AT .text:
00407399
SIZE
00000021
BYTES
.text:
00407522
.text:
00407522
push
0
; 填充ErrorCode
.text:
00407524
mov [esp
+
4
+
var_2],
0
.text:
0040752B
push ebp ; 填充Ebp
.text:
0040752C
push ebx ; 填充Ebx
.text:
0040752D
push esi ; 填充Esi
.text:
0040752E
push edi ; 填充Edi
.text:
0040752F
push fs ; 填充fs
.text:
00407531
mov ebx,
30h
.text:
00407536
mov fs, ebx ; 将fs指向KPCR
.text:
00407538
assume fs:nothing
.text:
00407538
mov ebx, large fs:
0
.text:
0040753F
push ebx ; 填充ExceptionList
.text:
00407540
sub esp,
4
; esp指向Eax
.text:
00407543
push eax ; 填充Eax
.text:
00407544
push ecx ; 填充Ecx
.text:
00407545
push edx ; 填充Edx
.text:
00407546
push ds ; 填充ds
.text:
00407547
push es ; 填充es
.text:
00407548
push gs ; 填充gs
.text:
0040754A
mov ax,
23h
.text:
0040754E
sub esp,
30h
; 将esp指向陷阱帧头部,也就是DbgEbp
.text:
00407551
mov ds, eax
.text:
00407553
assume ds:nothing
.text:
00407553
mov es, eax ; 将ds, es赋值为
0x23
.text:
00407555
assume es:nothing
.text:
00407555
mov ebp, esp ; 将ebp指向陷阱帧头部
.text:
00407557
test [esp
+
68h
+
arg_4],
20000h
; 判断是否为虚拟
8086
模式
.text:
0040755F
jnz short V86_kit0_a
.text:
00407561
.text:
00407561
loc_407561: ; CODE XREF: V86_kit0_a
+
25
↑j
.text:
00407561
cld
.text:
00407562
mov ebx, [ebp
+
60h
] ; 将ebp赋给ebx
.text:
00407565
mov edi, [ebp
+
68h
] ; 将Eip赋给edi
.text:
00407568
mov [ebp
+
0Ch
], edx ; 将edx赋给DbgArgPointer
.text:
0040756B
mov dword ptr [ebp
+
8
],
0BADB0D00h
; 为DbgArgMark赋值
.text:
00407572
mov [ebp
+
0
], ebx ; 填充DbgEbp
.text:
00407575
mov [ebp
+
4
], edi ; 填充DbgEip
.text:
00407578
test large byte ptr fs:
50h
,
0FFh
; 判断是否处于调试模式
.text:
00407580
jnz Dr_kit0_a
.text:
00407586
.text:
00407586
loc_407586: ; CODE XREF: Dr_kit0_a
+
10
↑j
.text:
00407586
; Dr_kit0_a
+
7C
↑j
.text:
00407586
test dword ptr [ebp
+
70h
],
20000h
; 判断是否处于虚拟
8086
模式
.text:
0040758D
jnz short loc_4075CC
.text:
0040758F
test byte ptr [ebp
+
6Ch
],
1
; 判断cs寄存器第
0
位是否有
1
.text:
00407593
jz short loc_40759C
.text:
00407595
cmp
word ptr [ebp
+
6Ch
],
1Bh
; 判断cs寄存器是否等于
0x1B
.text:
0040759A
jnz short loc_4075B9
.text:
004075B9
loc_4075B9: ; CODE XREF: _KiTrap00
+
78
↑j
.text:
004075B9
mov ebx, large fs:
124h
.text:
004075C0
mov ebx, [ebx
+
_KTHREAD.ApcState.Process]
.text:
004075C3
cmp
[ebx
+
_EPROCESS.VdmObjects],
0
.text:
004075CA
jz short loc_4075AB
.text:
004075CC
.text:
004075CC
loc_4075CC: ; CODE XREF: _KiTrap00
+
6B
↑j
.text:
004075CC
push
0
.text:
004075CE
call _Ki386VdmReflectException_A@
4
; Ki386VdmReflectException_A(x)
.text:
004075D3
or
al, al
.text:
004075D5
jnz Kei386EoiHelper@
0
; Kei386EoiHelper()
.text:
004075DB
jmp short loc_4075AB
.text:
004075DB
_KiTrap00 endp
.text:
004075B9
loc_4075B9: ; CODE XREF: _KiTrap00
+
78
↑j
.text:
004075B9
mov ebx, large fs:
124h
.text:
004075C0
mov ebx, [ebx
+
_KTHREAD.ApcState.Process]
.text:
004075C3
cmp
[ebx
+
_EPROCESS.VdmObjects],
0
.text:
004075CA
jz short loc_4075AB
.text:
004075CC
.text:
004075CC
loc_4075CC: ; CODE XREF: _KiTrap00
+
6B
↑j
.text:
004075CC
push
0
.text:
004075CE
call _Ki386VdmReflectException_A@
4
; Ki386VdmReflectException_A(x)
.text:
004075D3
or
al, al
.text:
004075D5
jnz Kei386EoiHelper@
0
; Kei386EoiHelper()
.text:
004075DB
jmp short loc_4075AB
.text:
004075DB
_KiTrap00 endp
.text:
004075AB
loc_4075AB: ; CODE XREF: _KiTrap00
+
A8↓j
.text:
004075AB
; _KiTrap00
+
B9↓j
.text:
004075AB
sti
.text:
004075AC
mov ebx, [ebp
+
68h
] ; 将陷阱帧中的Eip赋值给ebx
.text:
004075AF
mov eax, STATUS_INTEGER_DIVIDE_BY_ZERO
.text:
004075B4
jmp loc_407399
.text:
004075AB
loc_4075AB: ; CODE XREF: _KiTrap00
+
A8↓j
.text:
004075AB
; _KiTrap00
+
B9↓j
.text:
004075AB
sti
.text:
004075AC
mov ebx, [ebp
+
68h
] ; 将陷阱帧中的Eip赋值给ebx
.text:
004075AF
mov eax, STATUS_INTEGER_DIVIDE_BY_ZERO
.text:
004075B4
jmp loc_407399
.text:
00407399
loc_407399: ; CODE XREF: _KiTrap00
+
84
↓j
.text:
00407399
; _KiTrap00
+
92
↓j ...
.text:
00407399
xor ecx, ecx
.text:
0040739B
call CommonDispatchException
.text:
00407399
loc_407399: ; CODE XREF: _KiTrap00
+
84
↓j
.text:
00407399
; _KiTrap00
+
92
↓j ...
.text:
00407399
xor ecx, ecx
.text:
0040739B
call CommonDispatchException
.text:
004073BA
CommonDispatchException proc near ; CODE XREF: _KiTrap00
-
187
↑p
.text:
004073BA
; _KiTrap00
-
17B
↑p ...
.text:
004073BA
.text:
004073BA
var_50
=
_EXCEPTION_RECORD ptr
-
50h
.text:
004073BA
.text:
004073BA
sub esp,
50h
.text:
004073BD
mov [esp
+
50h
+
var_50.ExceptionCode], eax
.text:
004073C0
xor eax, eax
.text:
004073C2
mov [esp
+
50h
+
var_50.ExceptionFlags], eax
.text:
004073C6
mov [esp
+
50h
+
var_50.ExceptionRecord], eax
.text:
004073CA
mov [esp
+
50h
+
var_50.ExceptionAddress], ebx
.text:
004073CE
mov [esp
+
50h
+
var_50.NumberParameters], ecx
.text:
004073D2
cmp
ecx,
0
; 判断是否有参数
.text:
004073D5
jz short loc_4073E3 ; 将ExceptionRecord地址赋给ecx
.text:
004073D7
lea ebx, [esp
+
50h
+
var_50.ExceptionInformation]
.text:
004073DB
mov [ebx], edx
.text:
004073DD
mov [ebx
+
4
], esi
.text:
004073E0
mov [ebx
+
8
], edi
.text:
004073E3
.text:
004073E3
loc_4073E3: ; CODE XREF: CommonDispatchException
+
1B
↑j
.text:
004073E3
mov ecx, esp ; 将ExceptionRecord地址赋给ecx
.text:
004073E5
test dword ptr [ebp
+
70h
],
20000h
.text:
004073EC
jz short loc_4073F5
.text:
004073EE
mov eax,
0FFFFh
.text:
004073F3
jmp short loc_4073F8
.text:
004073F5
;
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
.text:
004073F5
.text:
004073F5
loc_4073F5: ; CODE XREF: CommonDispatchException
+
32
↑j
.text:
004073F5
mov eax, [ebp
+
6Ch
]
.text:
004073F8
.text:
004073F8
loc_4073F8: ; CODE XREF: CommonDispatchException
+
39
↑j
.text:
004073F8
and
eax,
1
.text:
004073FB
push
1
; FirstChance
.text:
004073FD
push eax ; PreviousMode
.text:
004073FE
push ebp ; TrapFrame
.text:
004073FF
push
0
; ExceptionFrame
.text:
00407401
push ecx ; ExceptionRecord
.text:
00407402
call _KiDispatchException@
20
; KiDispatchException(x,x,x,x,x)
.text:
00407407
mov esp, ebp
.text:
00407409
jmp Kei386EoiHelper@
0
; Kei386EoiHelper()
.text:
00407409
CommonDispatchException endp
.text:
004073BA
CommonDispatchException proc near ; CODE XREF: _KiTrap00
-
187
↑p
.text:
004073BA
; _KiTrap00
-
17B
↑p ...
.text:
004073BA
.text:
004073BA
var_50
=
_EXCEPTION_RECORD ptr
-
50h
.text:
004073BA
.text:
004073BA
sub esp,
50h
.text:
004073BD
mov [esp
+
50h
+
var_50.ExceptionCode], eax
.text:
004073C0
xor eax, eax
.text:
004073C2
mov [esp
+
50h
+
var_50.ExceptionFlags], eax
.text:
004073C6
mov [esp
+
50h
+
var_50.ExceptionRecord], eax
.text:
004073CA
mov [esp
+
50h
+
var_50.ExceptionAddress], ebx
.text:
004073CE
mov [esp
+
50h
+
var_50.NumberParameters], ecx
.text:
004073D2
cmp
ecx,
0
; 判断是否有参数
.text:
004073D5
jz short loc_4073E3 ; 将ExceptionRecord地址赋给ecx
.text:
004073D7
lea ebx, [esp
+
50h
+
var_50.ExceptionInformation]
.text:
004073DB
mov [ebx], edx
.text:
004073DD
mov [ebx
+
4
], esi
.text:
004073E0
mov [ebx
+
8
], edi
.text:
004073E3
.text:
004073E3
loc_4073E3: ; CODE XREF: CommonDispatchException
+
1B
↑j
.text:
004073E3
mov ecx, esp ; 将ExceptionRecord地址赋给ecx
.text:
004073E5
test dword ptr [ebp
+
70h
],
20000h
.text:
004073EC
jz short loc_4073F5
.text:
004073EE
mov eax,
0FFFFh
.text:
004073F3
jmp short loc_4073F8
.text:
004073F5
;
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
.text:
004073F5
.text:
004073F5
loc_4073F5: ; CODE XREF: CommonDispatchException
+
32
↑j
.text:
004073F5
mov eax, [ebp
+
6Ch
]
.text:
004073F8
.text:
004073F8
loc_4073F8: ; CODE XREF: CommonDispatchException
+
39
↑j
.text:
004073F8
and
eax,
1
.text:
004073FB
push
1
; FirstChance
.text:
004073FD
push eax ; PreviousMode
.text:
004073FE
push ebp ; TrapFrame
.text:
004073FF
push
0
; ExceptionFrame
.text:
00407401
push ecx ; ExceptionRecord
.text:
00407402
call _KiDispatchException@
20
; KiDispatchException(x,x,x,x,x)
.text:
00407407
mov esp, ebp
.text:
00407409
jmp Kei386EoiHelper@
0
; Kei386EoiHelper()
.text:
00407409
CommonDispatchException endp
.text:
7C812AA9
; void __stdcall RaiseException(DWORD dwExceptionCode, DWORD dwExceptionFlags, DWORD nNumberOfArguments, const ULONG_PTR
*
lpArguments)
.text:
7C812AA9
public _RaiseException@
16
.text:
7C812AA9
_RaiseException@
16
proc near ; CODE XREF: OutputDebugStringA(x)
+
4F
↓p
.text:
7C812AA9
; DATA XREF: .text:off_7C802654↑o ...
.text:
7C812AA9
.text:
7C812AA9
ExceptionRecord
=
EXCEPTION_RECORD ptr
-
50h
.text:
7C812AA9
dwExceptionCode
=
dword ptr
8
.text:
7C812AA9
dwExceptionFlags
=
dword ptr
0Ch
.text:
7C812AA9
nNumberOfArguments
=
dword ptr
10h
.text:
7C812AA9
lpArguments
=
dword ptr
14h
.text:
7C812AA9
arg_14
=
word ptr
1Ch
.text:
7C812AA9
arg_18
=
dword ptr
20h
.text:
7C812AA9
.text:
7C812AA9
; FUNCTION CHUNK AT .text:
7C844950
SIZE
00000008
BYTES
.text:
7C812AA9
; FUNCTION CHUNK AT .text:
7C84B737
SIZE
00000037
BYTES
.text:
7C812AA9
.text:
7C812AA9
mov edi, edi
.text:
7C812AAB
push ebp
.text:
7C812AAC
mov ebp, esp
.text:
7C812AAE
sub esp,
50h
; 开辟栈空间
.text:
7C812AB1
mov eax, [ebp
+
dwExceptionCode] ; 将第一个参数赋给eax
.text:
7C812AB4
and
[ebp
+
ExceptionRecord.ExceptionRecord],
0
.text:
7C812AB8
mov [ebp
+
ExceptionRecord.ExceptionCode], eax ; 为ExceptionCode赋值
.text:
7C812ABB
mov eax, [ebp
+
dwExceptionFlags]
.text:
7C812ABE
push esi
.text:
7C812ABF
mov esi, [ebp
+
lpArguments]
.text:
7C812AC2
and
eax,
1
.text:
7C812AC5
test esi, esi
.text:
7C812AC7
mov [ebp
+
ExceptionRecord.ExceptionFlags], eax
.text:
7C812ACA
mov [ebp
+
ExceptionRecord.ExceptionAddress], offset _RaiseException@
16
; RaiseException(x,x,x,x)
.text:
7C812AD1
jz loc_7C812B70
.text:
7C812AD7
mov ecx, [ebp
+
nNumberOfArguments]
.text:
7C812ADA
cmp
ecx,
0Fh
.text:
7C812ADD
ja loc_7C844950
.text:
7C812AE3
.text:
7C812AE3
loc_7C812AE3: ; CODE XREF: RaiseException(x,x,x,x)
+
31EAA
↓j
.text:
7C812AE3
test ecx, ecx ; 参数个数是否为
0
.text:
7C812AE5
mov [ebp
+
ExceptionRecord.NumberParameters], ecx
.text:
7C812AE8
jz short loc_7C812AF1
.text:
7C812AEA
push edi
.text:
7C812AEB
lea edi, [ebp
+
ExceptionRecord.ExceptionInformation]
.text:
7C812AEE
rep movsd
.text:
7C812AF0
pop edi
.text:
7C812AF1
.text:
7C812AF1
loc_7C812AF1: ; CODE XREF: RaiseException(x,x,x,x)
+
3F
↑j
.text:
7C812AF1
; RaiseException(x,x,x,x)
+
CB↓j
.text:
7C812AF1
lea eax, [ebp
+
ExceptionRecord]
.text:
7C812AF4
push eax ; ExceptionRecord
.text:
7C812AF5
call ds:__imp__RtlRaiseException@
4
; RtlRaiseException(x)
.text:
7C812AFB
pop esi
.text:
7C812AFC
leave
.text:
7C812AFD
retn
10h
.text:
7C812AA9
; void __stdcall RaiseException(DWORD dwExceptionCode, DWORD dwExceptionFlags, DWORD nNumberOfArguments, const ULONG_PTR
*
lpArguments)
.text:
7C812AA9
public _RaiseException@
16
.text:
7C812AA9
_RaiseException@
16
proc near ; CODE XREF: OutputDebugStringA(x)
+
4F
↓p
.text:
7C812AA9
; DATA XREF: .text:off_7C802654↑o ...
.text:
7C812AA9
.text:
7C812AA9
ExceptionRecord
=
EXCEPTION_RECORD ptr
-
50h
.text:
7C812AA9
dwExceptionCode
=
dword ptr
8
.text:
7C812AA9
dwExceptionFlags
=
dword ptr
0Ch
.text:
7C812AA9
nNumberOfArguments
=
dword ptr
10h
.text:
7C812AA9
lpArguments
=
dword ptr
14h
.text:
7C812AA9
arg_14
=
word ptr
1Ch
.text:
7C812AA9
arg_18
=
dword ptr
20h
.text:
7C812AA9
.text:
7C812AA9
; FUNCTION CHUNK AT .text:
7C844950
SIZE
00000008
BYTES
.text:
7C812AA9
; FUNCTION CHUNK AT .text:
7C84B737
SIZE
00000037
BYTES
.text:
7C812AA9
.text:
7C812AA9
mov edi, edi
.text:
7C812AAB
push ebp
.text:
7C812AAC
mov ebp, esp
.text:
7C812AAE
sub esp,
50h
; 开辟栈空间
.text:
7C812AB1
mov eax, [ebp
+
dwExceptionCode] ; 将第一个参数赋给eax
.text:
7C812AB4
and
[ebp
+
ExceptionRecord.ExceptionRecord],
0
.text:
7C812AB8
mov [ebp
+
ExceptionRecord.ExceptionCode], eax ; 为ExceptionCode赋值
.text:
7C812ABB
mov eax, [ebp
+
dwExceptionFlags]
.text:
7C812ABE
push esi
.text:
7C812ABF
mov esi, [ebp
+
lpArguments]
.text:
7C812AC2
and
eax,
1
.text:
7C812AC5
test esi, esi
.text:
7C812AC7
mov [ebp
+
ExceptionRecord.ExceptionFlags], eax
.text:
7C812ACA
mov [ebp
+
ExceptionRecord.ExceptionAddress], offset _RaiseException@
16
; RaiseException(x,x,x,x)
.text:
7C812AD1
jz loc_7C812B70
.text:
7C812AD7
mov ecx, [ebp
+
nNumberOfArguments]
.text:
7C812ADA
cmp
ecx,
0Fh
.text:
7C812ADD
ja loc_7C844950
.text:
7C812AE3
.text:
7C812AE3
loc_7C812AE3: ; CODE XREF: RaiseException(x,x,x,x)
+
31EAA
↓j
.text:
7C812AE3
test ecx, ecx ; 参数个数是否为
0
.text:
7C812AE5
mov [ebp
+
ExceptionRecord.NumberParameters], ecx
.text:
7C812AE8
jz short loc_7C812AF1
.text:
7C812AEA
push edi
.text:
7C812AEB
lea edi, [ebp
+
ExceptionRecord.ExceptionInformation]
.text:
7C812AEE
rep movsd
.text:
7C812AF0
pop edi
.text:
7C812AF1
.text:
7C812AF1
loc_7C812AF1: ; CODE XREF: RaiseException(x,x,x,x)
+
3F
↑j
.text:
7C812AF1
; RaiseException(x,x,x,x)
+
CB↓j
.text:
7C812AF1
lea eax, [ebp
+
ExceptionRecord]
.text:
7C812AF4
push eax ; ExceptionRecord
.text:
7C812AF5
call ds:__imp__RtlRaiseException@
4
; RtlRaiseException(x)
.text:
7C812AFB
pop esi
.text:
7C812AFC
leave
.text:
7C812AFD
retn
10h
.text:
0040A1DF
; NTSTATUS __stdcall NtRaiseException(PEXCEPTION_RECORD ExceptionRecord, PCONTEXT ContextRecord, BOOLEAN FirstChance)
.text:
0040A1DF
_NtRaiseException@
12
proc near ; DATA XREF: .text:
0040DAF4
↓o
.text:
0040A1DF
.text:
0040A1DF
TraFrame
=
dword ptr
0
.text:
0040A1DF
ExceptionRecord
=
dword ptr
8
.text:
0040A1DF
ContextRecord
=
dword ptr
0Ch
.text:
0040A1DF
FirstChance
=
byte ptr
10h
.text:
0040A1DF
TrapFrame
=
dword ptr
3Ch
.text:
0040A1DF
.text:
0040A1DF
push ebp
.text:
0040A1E0
mov ebx, large fs:
124h
.text:
0040A1E7
mov edx, [ebp
+
TrapFrame]
.text:
0040A1EA
mov [ebx
+
_KTHREAD.TrapFrame], edx
.text:
0040A1F0
mov ebp, esp
.text:
0040A1F2
mov ebx, [ebp
+
TraFrame]
.text:
0040A1F5
mov edx, dword ptr [ebp
+
FirstChance]
.text:
0040A1F8
mov eax, [ebx
+
_ETHREAD.Tcb.ContextSwitches]
.text:
0040A1FB
mov ecx, [ebp
+
ContextRecord]
.text:
0040A1FE
mov large fs:
0
, eax
.text:
0040A204
mov eax, [ebp
+
ExceptionRecord]
.text:
0040A207
push edx ; FirstChance
.text:
0040A208
push ebx ; TrapFrame
.text:
0040A209
push
0
; ExceptionFrame
.text:
0040A20B
push ecx ; ContextRecord
.text:
0040A20C
push eax ; ExceptionRecord
.text:
0040A20D
call _KiRaiseException@
20
; KiRaiseException(x,x,x,x,x)
.text:
0040A212
pop ebp
.text:
0040A213
mov esp, ebp
.text:
0040A215
or
eax, eax
.text:
0040A217
jz _KiServiceExit2
.text:
0040A21D
jmp _KiServiceExit
.text:
0040A21D
_NtRaiseException@
12
endp
.text:
0040A1DF
; NTSTATUS __stdcall NtRaiseException(PEXCEPTION_RECORD ExceptionRecord, PCONTEXT ContextRecord, BOOLEAN FirstChance)
.text:
0040A1DF
_NtRaiseException@
12
proc near ; DATA XREF: .text:
0040DAF4
↓o
.text:
0040A1DF
.text:
0040A1DF
TraFrame
=
dword ptr
0
.text:
0040A1DF
ExceptionRecord
=
dword ptr
8
.text:
0040A1DF
ContextRecord
=
dword ptr
0Ch
.text:
0040A1DF
FirstChance
=
byte ptr
10h
.text:
0040A1DF
TrapFrame
=
dword ptr
3Ch
.text:
0040A1DF
.text:
0040A1DF
push ebp
.text:
0040A1E0
mov ebx, large fs:
124h
.text:
0040A1E7
mov edx, [ebp
+
TrapFrame]
.text:
0040A1EA
mov [ebx
+
_KTHREAD.TrapFrame], edx
.text:
0040A1F0
mov ebp, esp
.text:
0040A1F2
mov ebx, [ebp
+
TraFrame]
.text:
0040A1F5
mov edx, dword ptr [ebp
+
FirstChance]
.text:
0040A1F8
mov eax, [ebx
+
_ETHREAD.Tcb.ContextSwitches]
.text:
0040A1FB
mov ecx, [ebp
+
ContextRecord]
.text:
0040A1FE
mov large fs:
0
, eax
.text:
0040A204
mov eax, [ebp
+
ExceptionRecord]
.text:
0040A207
push edx ; FirstChance
.text:
0040A208
push ebx ; TrapFrame
.text:
0040A209
push
0
; ExceptionFrame
.text:
0040A20B
push ecx ; ContextRecord
.text:
0040A20C
push eax ; ExceptionRecord
.text:
0040A20D
call _KiRaiseException@
20
; KiRaiseException(x,x,x,x,x)
.text:
0040A212
pop ebp
.text:
0040A213
mov esp, ebp
.text:
0040A215
or
eax, eax
.text:
0040A217
jz _KiServiceExit2
.text:
0040A21D
jmp _KiServiceExit
.text:
0040A21D
_NtRaiseException@
12
endp
.text:
004413DD
push dword ptr [ebp
+
PreviousMode]
.text:
004413E3
mov eax, [ebp
+
var_ContextRecord]
.text:
004413E9
push [eax
+
_CONTEXT.ContextFlags]
.text:
004413EB
push eax
.text:
004413EC
push [ebp
+
var_ExceptionFrame]
.text:
004413F2
push [ebp
+
var_TrapFrame]
.text:
004413F8
call _KeContextToKframes@
20
; KeContextToKframes(x,x,x,x,x)
.text:
004413FD
and
byte ptr [ebx
+
3
],
0EFh
; 清空第
4
位
.text:
00441401
push dword ptr [ebp
+
FirstChance] ; FirstChance
.text:
00441404
push dword ptr [ebp
+
PreviousMode] ; PreviousMode
.text:
0044140A
push [ebp
+
var_TrapFrame] ; TrapFrame
.text:
00441410
push [ebp
+
var_ExceptionFrame] ; ExceptionFrame
.text:
00441416
push ebx ; ExceptionRecord
.text:
00441417
call _KiDispatchException@
20
.text:
004413DD
push dword ptr [ebp
+
PreviousMode]
.text:
004413E3
mov eax, [ebp
+
var_ContextRecord]
.text:
004413E9
push [eax
+
_CONTEXT.ContextFlags]
.text:
004413EB
push eax
.text:
004413EC
push [ebp
+
var_ExceptionFrame]
.text:
004413F2
push [ebp
+
var_TrapFrame]
.text:
004413F8
call _KeContextToKframes@
20
; KeContextToKframes(x,x,x,x,x)
.text:
004413FD
and
byte ptr [ebx
+
3
],
0EFh
; 清空第
4
位
.text:
00441401
push dword ptr [ebp
+
FirstChance] ; FirstChance
.text:
00441404
push dword ptr [ebp
+
PreviousMode] ; PreviousMode
.text:
0044140A
push [ebp
+
var_TrapFrame] ; TrapFrame
.text:
00441410
push [ebp
+
var_ExceptionFrame] ; ExceptionFrame
.text:
00441416
push ebx ; ExceptionRecord
.text:
00441417
call _KiDispatchException@
20
VOID KiDispatchException(IN PEXCEPTION_RECORD ExceptionRecord,
IN PKEXCEPTION_FRAME ExceptionFrame,
IN PKTRAP_FRAME TrapFrame,
IN KPROCESSOR_MODE PreviousMode,
IN BOOLEAN FirstChance);
VOID KiDispatchException(IN PEXCEPTION_RECORD ExceptionRecord,
IN PKEXCEPTION_FRAME ExceptionFrame,
IN PKTRAP_FRAME TrapFrame,
IN KPROCESSOR_MODE PreviousMode,
IN BOOLEAN FirstChance);
参数 | 含义 |
---|---|
ExceptionRecord | 指向EXCEPTION_RECORD结构,用来描述要分发的异常 |
ExceptionFrame | 对于x86系统,该参数总是为NULL |
TrapFrame | 指向KTRAP_FRAME结构体,用来描述异常发生时的处理器状态 |
PreviousMode | 指定先前模式,为0则先前模式为内核模式,为1则先前模式为用户模式 |
FirstChance | 表示是否是第一轮分发这个异常。对于一个异常,Windows系统最多分发两轮 |
.text:
004249F5
;
int
__stdcall KiDispatchException(PEXCEPTION_RECORD ExceptionRecord,
int
ExceptionFrame, ULONG_PTR TrapFrame, KPROCESSOR_MODE PreviousMode, BOOLEAN FirstChance)
.text:
004249F5
_KiDispatchException@
20
proc near ; CODE XREF: CommonDispatchException
+
48
↑p
.text:
004249F5
; KiRaiseException(x,x,x,x,x)
+
158
↓p ...
.text:
004249F5
.text:
004249F5
var_3A0
=
dword ptr
-
3A0h
.text:
004249F5
var_394
=
dword ptr
-
394h
.text:
004249F5
var_350
=
EXCEPTION_RECORD ptr
-
350h
.text:
004249F5
var_300
=
dword ptr
-
300h
.text:
004249F5
var_2FC
=
dword ptr
-
2FCh
.text:
004249F5
var_TrapFrame
=
dword ptr
-
2F8h
.text:
004249F5
var_2F4
=
dword ptr
-
2F4h
.text:
004249F5
var_ExceptionFrame
=
dword ptr
-
2F0h
.text:
004249F5
var_ExceptionRecord
=
dword ptr
-
2ECh
.text:
004249F5
Context
=
CONTEXT ptr
-
2E8h
.text:
004249F5
var_Cookie
=
dword ptr
-
1Ch
.text:
004249F5
ms_exc
=
CPPEH_RECORD ptr
-
18h
.text:
004249F5
ExceptionRecord
=
dword ptr
8
.text:
004249F5
ExceptionFrame
=
dword ptr
0Ch
.text:
004249F5
TrapFrame
=
dword ptr
10h
.text:
004249F5
PreviousMode
=
byte ptr
14h
.text:
004249F5
FirstChance
=
byte ptr
18h
.text:
004249F5
push
390h
.text:
004249FA
push offset stru_424AF8
.text:
004249FF
call __SEH_prolog
.text:
00424A04
mov eax, ds:___security_cookie
.text:
00424A09
mov [ebp
+
var_Cookie], eax
.text:
00424A0C
mov esi, [ebp
+
ExceptionRecord]
.text:
00424A0F
mov [ebp
+
var_ExceptionRecord], esi
.text:
00424A15
mov ecx, [ebp
+
ExceptionFrame]
.text:
00424A18
mov [ebp
+
var_ExceptionFrame], ecx
.text:
00424A1E
mov ebx, [ebp
+
TrapFrame]
.text:
00424A21
mov [ebp
+
var_TrapFrame], ebx
.text:
00424A27
mov eax, large fs:
20h
.text:
00424A2D
inc [eax
+
_KPRCB.KeExceptionDispatchCount]
.text:
00424A33
mov [ebp
+
Context.ContextFlags],
10017h
.text:
00424A3D
cmp
[ebp
+
PreviousMode],
1
; 先前模式是否为用户模式
.text:
00424A41
jz short loc_424A4C
.text:
00424A43
cmp
ds:_KdDebuggerEnabled,
0
; 是否存在内核调试器
.text:
00424A4A
jz short loc_424A69
.text:
00424A4C
.text:
00424A4C
loc_424A4C: ; CODE XREF: KiDispatchException(x,x,x,x,x)
+
4C
↑j
.text:
00424A4C
mov [ebp
+
Context.ContextFlags],
1001Fh
.text:
00424A56
cmp
ds:_KeI386XMMIPresent,
0
.text:
00424A5D
jz short loc_424A69
.text:
00424A5F
mov [ebp
+
Context.ContextFlags],
1003Fh
.text:
004249F5
;
int
__stdcall KiDispatchException(PEXCEPTION_RECORD ExceptionRecord,
int
ExceptionFrame, ULONG_PTR TrapFrame, KPROCESSOR_MODE PreviousMode, BOOLEAN FirstChance)
.text:
004249F5
_KiDispatchException@
20
proc near ; CODE XREF: CommonDispatchException
+
48
↑p
.text:
004249F5
; KiRaiseException(x,x,x,x,x)
+
158
↓p ...
.text:
004249F5
.text:
004249F5
var_3A0
=
dword ptr
-
3A0h
.text:
004249F5
var_394
=
dword ptr
-
394h
.text:
004249F5
var_350
=
EXCEPTION_RECORD ptr
-
350h
.text:
004249F5
var_300
=
dword ptr
-
300h
.text:
004249F5
var_2FC
=
dword ptr
-
2FCh
.text:
004249F5
var_TrapFrame
=
dword ptr
-
2F8h
.text:
004249F5
var_2F4
=
dword ptr
-
2F4h
.text:
004249F5
var_ExceptionFrame
=
dword ptr
-
2F0h
.text:
004249F5
var_ExceptionRecord
=
dword ptr
-
2ECh
.text:
004249F5
Context
=
CONTEXT ptr
-
2E8h
.text:
004249F5
var_Cookie
=
dword ptr
-
1Ch
.text:
004249F5
ms_exc
=
CPPEH_RECORD ptr
-
18h
.text:
004249F5
ExceptionRecord
=
dword ptr
8
.text:
004249F5
ExceptionFrame
=
dword ptr
0Ch
.text:
004249F5
TrapFrame
=
dword ptr
10h
.text:
004249F5
PreviousMode
=
byte ptr
14h
.text:
004249F5
FirstChance
=
byte ptr
18h
.text:
004249F5
push
390h
.text:
004249FA
push offset stru_424AF8
.text:
004249FF
call __SEH_prolog
.text:
00424A04
mov eax, ds:___security_cookie
.text:
00424A09
mov [ebp
+
var_Cookie], eax
.text:
00424A0C
mov esi, [ebp
+
ExceptionRecord]
.text:
00424A0F
mov [ebp
+
var_ExceptionRecord], esi
.text:
00424A15
mov ecx, [ebp
+
ExceptionFrame]
.text:
00424A18
mov [ebp
+
var_ExceptionFrame], ecx
.text:
00424A1E
mov ebx, [ebp
+
TrapFrame]
.text:
00424A21
mov [ebp
+
var_TrapFrame], ebx
.text:
00424A27
mov eax, large fs:
20h
.text:
00424A2D
inc [eax
+
_KPRCB.KeExceptionDispatchCount]
.text:
00424A33
mov [ebp
+
Context.ContextFlags],
10017h
.text:
00424A3D
cmp
[ebp
+
PreviousMode],
1
; 先前模式是否为用户模式
.text:
00424A41
jz short loc_424A4C
.text:
00424A43
cmp
ds:_KdDebuggerEnabled,
0
; 是否存在内核调试器
.text:
00424A4A
jz short loc_424A69
.text:
00424A4C
.text:
00424A4C
loc_424A4C: ; CODE XREF: KiDispatchException(x,x,x,x,x)
+
4C
↑j
.text:
00424A4C
mov [ebp
+
Context.ContextFlags],
1001Fh
.text:
00424A56
cmp
ds:_KeI386XMMIPresent,
0
.text:
00424A5D
jz short loc_424A69
.text:
00424A5F
mov [ebp
+
Context.ContextFlags],
1003Fh
.text:
00424A69
loc_424A69: ; CODE XREF: KiDispatchException(x,x,x,x,x)
+
55
↑j
.text:
00424A69
; KiDispatchException(x,x,x,x,x)
+
68
↑j
.text:
00424A69
lea eax, [ebp
+
Context]
.text:
00424A6F
push eax
.text:
00424A70
push ecx
.text:
00424A71
push ebx
.text:
00424A72
call _KeContextFromKframes@
12
; KeContextFromKframes(x,x,x)
.text:
00424A77
mov eax, [esi
+
_EXCEPTION_RECORD.ExceptionCode]
.text:
00424A79
cmp
eax, EXCEPTION_BREAKPOINT ; 判断是否为断点异常
.text:
00424A7E
jnz loc_44110E
.text:
00424A84
dec [ebp
+
Context._Eip]
.text:
00424A69
loc_424A69: ; CODE XREF: KiDispatchException(x,x,x,x,x)
+
55
↑j
.text:
00424A69
; KiDispatchException(x,x,x,x,x)
+
68
↑j
.text:
00424A69
lea eax, [ebp
+
Context]
.text:
00424A6F
push eax
.text:
00424A70
push ecx
.text:
00424A71
push ebx
.text:
00424A72
call _KeContextFromKframes@
12
; KeContextFromKframes(x,x,x)
.text:
00424A77
mov eax, [esi
+
_EXCEPTION_RECORD.ExceptionCode]
.text:
00424A79
cmp
eax, EXCEPTION_BREAKPOINT ; 判断是否为断点异常
.text:
00424A7E
jnz loc_44110E
.text:
00424A84
dec [ebp
+
Context._Eip]
.text:
0044110E
loc_44110E: ; CODE XREF: KiDispatchException(x,x,x,x,x)
+
89
↑j
.text:
0044110E
cmp
eax, KI_EXCEPTION_ACCESS_VIOLATION
.text:
00441113
jnz loc_424A8A ; 清空edi
.text:
00441119
mov [esi
+
_EXCEPTION_RECORD.ExceptionCode], EXCEPTION_ACCESS_VIOLATION
.text:
0044111F
cmp
[ebp
+
PreviousMode],
1
.text:
00441123
jnz loc_424A8A
.text:
0044110E
loc_44110E: ; CODE XREF: KiDispatchException(x,x,x,x,x)
+
89
↑j
.text:
0044110E
cmp
eax, KI_EXCEPTION_ACCESS_VIOLATION
.text:
00441113
jnz loc_424A8A ; 清空edi
.text:
00441119
mov [esi
+
_EXCEPTION_RECORD.ExceptionCode], EXCEPTION_ACCESS_VIOLATION
.text:
0044111F
cmp
[ebp
+
PreviousMode],
1
.text:
00441123
jnz loc_424A8A
.text:
00424A8A
loc_424A8A: ; CODE XREF: KiDispatchException(x,x,x,x,x)
+
1C71E
↓j
.text:
00424A8A
; KiDispatchException(x,x,x,x,x)
+
1C72E
↓j ...
.text:
00424A8A
xor edi, edi ; 清空edi
.text:
00424A8C
.text:
00424A8C
loc_424A8C: ; CODE XREF: KiDispatchException(x,x,x,x,x)
+
266BE
↓j
.text:
00424A8C
cmp
[ebp
+
PreviousMode],
0
; 判断先前模式是否是内核模式
.text:
00424A90
jnz loc_440F9E
.text:
00424A8A
loc_424A8A: ; CODE XREF: KiDispatchException(x,x,x,x,x)
+
1C71E
↓j
.text:
00424A8A
; KiDispatchException(x,x,x,x,x)
+
1C72E
↓j ...
.text:
00424A8A
xor edi, edi ; 清空edi
.text:
00424A8C
.text:
00424A8C
loc_424A8C: ; CODE XREF: KiDispatchException(x,x,x,x,x)
+
266BE
↓j
.text:
00424A8C
cmp
[ebp
+
PreviousMode],
0
; 判断先前模式是否是内核模式
.text:
00424A90
jnz loc_440F9E
.text:
00424A96
cmp
[ebp
+
FirstChance],
1
; 判断是否为第一次执行
.text:
00424A9A
jnz loc_44B0C0
.text:
00424AA0
mov eax, ds:_KiDebugRoutine
.text:
00424AA5
cmp
eax, edi ; 判断是否存在内核调试器
.text:
00424AA7
jz loc_4335A6
.text:
00424AAD
push edi
.text:
00424AAE
push edi
.text:
00424AAF
lea ecx, [ebp
+
Context]
.text:
00424AB5
push ecx
.text:
00424AB6
push esi
.text:
00424AB7
push [ebp
+
var_ExceptionFrame]
.text:
00424ABD
push ebx
.text:
00424ABE
call eax ; _KiDebugRoutine
.text:
00424AC0
test al, al ; 判断返回值是否为
0
.text:
00424AC2
jz loc_4335A6
.text:
00424A96
cmp
[ebp
+
FirstChance],
1
; 判断是否为第一次执行
.text:
00424A9A
jnz loc_44B0C0
.text:
00424AA0
mov eax, ds:_KiDebugRoutine
.text:
00424AA5
cmp
eax, edi ; 判断是否存在内核调试器
.text:
00424AA7
jz loc_4335A6
.text:
00424AAD
push edi
.text:
00424AAE
push edi
.text:
00424AAF
lea ecx, [ebp
+
Context]
.text:
00424AB5
push ecx
.text:
00424AB6
push esi
.text:
00424AB7
push [ebp
+
var_ExceptionFrame]
.text:
00424ABD
push ebx
.text:
00424ABE
call eax ; _KiDebugRoutine
.text:
00424AC0
test al, al ; 判断返回值是否为
0
.text:
00424AC2
jz loc_4335A6
.text:
004335A6
loc_4335A6: ; CODE XREF: KiDispatchException(x,x,x,x,x)
+
B2↑j
.text:
004335A6
; KiDispatchException(x,x,x,x,x)
+
CD↑j
.text:
004335A6
lea eax, [ebp
+
Context]
.text:
004335AC
push eax ; Context
.text:
004335AD
push esi ; ExceptionRecord
.text:
004335AE
call _RtlDispatchException@
8
; RtlDispatchException(x,x)
.text:
004335B3
jmp loc_44B0B8
.text:
004335A6
loc_4335A6: ; CODE XREF: KiDispatchException(x,x,x,x,x)
+
B2↑j
.text:
004335A6
; KiDispatchException(x,x,x,x,x)
+
CD↑j
.text:
004335A6
lea eax, [ebp
+
Context]
.text:
004335AC
push eax ; Context
.text:
004335AD
push esi ; ExceptionRecord
.text:
004335AE
call _RtlDispatchException@
8
; RtlDispatchException(x,x)
.text:
004335B3
jmp loc_44B0B8
.text:
0044B0B8
loc_44B0B8: ; CODE XREF: KiDispatchException(x,x,x,x,x)
+
EBBE↑j
.text:
0044B0B8
cmp
al,
1
.text:
0044B0BA
jz loc_424AC8
.text:
0044B0B8
loc_44B0B8: ; CODE XREF: KiDispatchException(x,x,x,x,x)
+
EBBE↑j
.text:
0044B0B8
cmp
al,
1
.text:
0044B0BA
jz loc_424AC8
.text:
00424AC8
loc_424AC8: ; CODE XREF: KiDispatchException(x,x,x,x,x)
+
1C5EB
↓j
.text:
00424AC8
; KiDispatchException(x,x,x,x,x)
+
1C743
↓j ...
.text:
00424AC8
push dword ptr [ebp
+
PreviousMode]
.text:
00424ACB
push [ebp
+
Context.ContextFlags]
.text:
00424AD1
lea eax, [ebp
+
Context]
.text:
00424AD7
push eax
.text:
00424AD8
push [ebp
+
var_ExceptionFrame]
.text:
00424ADE
push ebx
.text:
00424ADF
call _KeContextToKframes@
20
; KeContextToKframes(x,x,x,x,x)
.text:
00424AE4
.text:
00424AE4
loc_424AE4: ; CODE XREF: KiDispatchException(x,x,x,x,x)
+
1C5FC
↓j
.text:
00424AE4
; KiDispatchException(x,x,x,x,x)
+
1C701
↓j ...
.text:
00424AE4
mov ecx, [ebp
+
var_Cookie]
.text:
00424AE7
call sub_403063
.text:
00424AEC
call __SEH_epilog
.text:
00424AF1
retn
14h
.text:
00424AF1
_KiDispatchException@
20
endp
.text:
00424AC8
loc_424AC8: ; CODE XREF: KiDispatchException(x,x,x,x,x)
+
1C5EB
↓j
.text:
00424AC8
; KiDispatchException(x,x,x,x,x)
+
1C743
↓j ...
.text:
00424AC8
push dword ptr [ebp
+
PreviousMode]
.text:
00424ACB
push [ebp
+
Context.ContextFlags]
.text:
00424AD1
lea eax, [ebp
+
Context]
.text:
00424AD7
push eax
.text:
00424AD8
push [ebp
+
var_ExceptionFrame]
.text:
00424ADE
push ebx
.text:
00424ADF
call _KeContextToKframes@
20
; KeContextToKframes(x,x,x,x,x)
.text:
00424AE4
.text:
00424AE4
loc_424AE4: ; CODE XREF: KiDispatchException(x,x,x,x,x)
+
1C5FC
↓j
.text:
00424AE4
; KiDispatchException(x,x,x,x,x)
+
1C701
↓j ...
.text:
00424AE4
mov ecx, [ebp
+
var_Cookie]
.text:
00424AE7
call sub_403063
.text:
00424AEC
call __SEH_epilog
.text:
00424AF1
retn
14h
.text:
00424AF1
_KiDispatchException@
20
endp
.text:
0044B0C0
loc_44B0C0: ; CODE XREF: KiDispatchException(x,x,x,x,x)
+
A5↑j
.text:
0044B0C0
mov eax, ds:_KiDebugRoutine
.text:
0044B0C5
cmp
eax, edi ; 是否存在内核调试器
.text:
0044B0C7
jz loc_44B1C2
.text:
0044B0CD
push
1
.text:
0044B0CF
push edi
.text:
0044B0D0
lea ecx, [ebp
+
Context]
.text:
0044B0D6
push ecx
.text:
0044B0D7
push esi
.text:
0044B0D8
push [ebp
+
var_ExceptionFrame]
.text:
0044B0DE
push ebx
.text:
0044B0DF
call eax ; _KiDebugRoutine
.text:
0044B0E1
test al, al ; 判断返回值是否为
0
.text:
0044B0E3
jz loc_44B1C2
.text:
0044B0E9
jmp loc_424AC8
.text:
0044B0C0
loc_44B0C0: ; CODE XREF: KiDispatchException(x,x,x,x,x)
+
A5↑j
.text:
0044B0C0
mov eax, ds:_KiDebugRoutine
.text:
0044B0C5
cmp
eax, edi ; 是否存在内核调试器
.text:
0044B0C7
jz loc_44B1C2
.text:
0044B0CD
push
1
.text:
0044B0CF
push edi
.text:
0044B0D0
lea ecx, [ebp
+
Context]
.text:
0044B0D6
push ecx
.text:
0044B0D7
push esi
.text:
0044B0D8
push [ebp
+
var_ExceptionFrame]
.text:
0044B0DE
push ebx
.text:
0044B0DF
call eax ; _KiDebugRoutine
.text:
0044B0E1
test al, al ; 判断返回值是否为
0
.text:
0044B0E3
jz loc_44B1C2
.text:
0044B0E9
jmp loc_424AC8
.text:
0044B1C2
loc_44B1C2: ; CODE XREF: KiDispatchException(x,x,x,x,x)
+
266D2
↑j
.text:
0044B1C2
; KiDispatchException(x,x,x,x,x)
+
266EE
↑j ...
.text:
0044B1C2
push edi ; BugCheckParameter4
.text:
0044B1C3
push ebx ; BugCheckParameter3
.text:
0044B1C4
push dword ptr [esi
+
0Ch
] ; BugCheckParameter2
.text:
0044B1C7
push dword ptr [esi] ; BugCheckParameter1
.text:
0044B1C9
push
8Eh
; BugCheckCode
.text:
0044B1CE
call _KeBugCheckEx@
20
.text:
0044B1C2
loc_44B1C2: ; CODE XREF: KiDispatchException(x,x,x,x,x)
+
266D2
↑j
.text:
0044B1C2
; KiDispatchException(x,x,x,x,x)
+
266EE
↑j ...
.text:
0044B1C2
push edi ; BugCheckParameter4
.text:
0044B1C3
push ebx ; BugCheckParameter3
.text:
0044B1C4
push dword ptr [esi
+
0Ch
] ; BugCheckParameter2
.text:
0044B1C7
push dword ptr [esi] ; BugCheckParameter1
.text:
0044B1C9
push
8Eh
; BugCheckCode
.text:
0044B1CE
call _KeBugCheckEx@
20
.text:
00407370
loc_407370: ; CODE XREF: Kei386EoiHelper()
+
14F
↓j
.text:
00407370
; Kei386EoiHelper()
+
156
↓j
.text:
00407370
add esp,
4
.text:
00407373
iret
.text:
00407370
loc_407370: ; CODE XREF: Kei386EoiHelper()
+
14F
↓j
.text:
00407370
; Kei386EoiHelper()
+
156
↓j
.text:
00407370
add esp,
4
.text:
00407373
iret
.text:
00440F9E
loc_440F9E: ; CODE XREF: KiDispatchException(x,x,x,x,x)
+
9B
↑j
.text:
00440F9E
cmp
[ebp
+
FirstChance],
1
; 是否是第一次执行
.text:
00440FA2
jnz loc_44B196
.text:
00440FA8
cmp
ds:_KiDebugRoutine, edi ; 判断是否存在内核调试器
.text:
00440FAE
jz short loc_440FE6
.text:
00440FB0
mov eax, large fs:
124h
.text:
00440FB6
mov eax, [eax
+
_KTHREAD.ApcState.Process]
.text:
00440FB9
cmp
[eax
+
_EPROCESS.DebugPort], edi ; 调试端口是否为
0
.text:
00440FBF
jnz loc_44B0F3
.text:
00440FC5
.text:
00440FC5
loc_440FC5: ; CODE XREF: KiDispatchException(x,x,x,x,x)
+
EBC5↑j
.text:
00440FC5
push edi
.text:
00440FC6
push dword ptr [ebp
+
PreviousMode]
.text:
00440FC9
lea eax, [ebp
+
Context]
.text:
00440FCF
push eax
.text:
00440FD0
push esi
.text:
00440FD1
push [ebp
+
var_ExceptionFrame]
.text:
00440FD7
push ebx
.text:
00440FD8
call ds:_KiDebugRoutine
.text:
00440FDE
test al, al ; 是否处理了异常
.text:
00440FE0
jnz loc_424AC8
.text:
00440F9E
loc_440F9E: ; CODE XREF: KiDispatchException(x,x,x,x,x)
+
9B
↑j
.text:
00440F9E
cmp
[ebp
+
FirstChance],
1
; 是否是第一次执行
.text:
00440FA2
jnz loc_44B196
.text:
00440FA8
cmp
ds:_KiDebugRoutine, edi ; 判断是否存在内核调试器
.text:
00440FAE
jz short loc_440FE6
.text:
00440FB0
mov eax, large fs:
124h
.text:
00440FB6
mov eax, [eax
+
_KTHREAD.ApcState.Process]
.text:
00440FB9
cmp
[eax
+
_EPROCESS.DebugPort], edi ; 调试端口是否为
0
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)
赞赏
- [原创]CVE-2022-21882提权漏洞学习笔记 16383
- [原创]CVE-2021-1732提权漏洞学习笔记 19489
- [原创]CVE-2014-1767提权漏洞学习笔记 15192
- [原创]CVE-2018-8453提权漏洞学习笔记 18526
- [原创]CVE-2020-1054提权漏洞学习笔记 13542