CPU异常分析(以trap00为例)
Windows内核分析索引目录:https://www.cnblogs.com/onetrainee/p/11675224.html
CPU异常的记录(trap00为例)
一、CPU检测到除零异常的执行流程
二、Trap00 函数的分析
当发生除零异常时,查IDT表会查到Trap00函数,该函数的目的是构建_KTRAP_FRAME结构,查错误码,之后调用 commonDispatchExcption进行封装。
我们可能很奇怪,明明CPU检测到的错误,本身就在内核,还会有 _KTRAP_FRAME结构。
很简单,用户也会走这个函数,我们在反汇编代码分析时,发现其还有一条路线是处理用户层的,如果是用户层直接进来,当然要进行线程上下文切换。
三、CommonDispatchException函数
该函数就是完成封装 _EXCEPTION_RECORD结构体,之后调用 _KiDispatchException来开始真正的派发函数。
四、反汇编代码:
1. Trap00函数反汇编代码
1 .text:00436650 _KiTrap00 proc near ; DATA XREF: INIT:_IDT↓o 2 .text:00436650 3 .text:00436650 var_2 = word ptr -2 4 .text:00436650 arg_4 = dword ptr 8 5 .text:00436650 6 .text:00436650 ; FUNCTION CHUNK AT .text:004363FB SIZE 00000013 BYTES 7 .text:00436650 8 .text:00436650 push 0 9 .text:00436652 mov [esp+4+var_2], 0 10 .text:00436659 push ebp 11 .text:0043665A push ebx 12 .text:0043665B push esi 13 .text:0043665C push edi 14 .text:0043665D push fs 15 .text:0043665F mov ebx, 30h ; 30这个值作为段选择子 16 .text:00436664 mov fs, bx 17 .text:00436667 assume fs:nothing 18 .text:00436667 mov ebx, large fs:0 19 .text:0043666E push ebx 20 .text:0043666F sub esp, 4 21 .text:00436672 push eax 22 .text:00436673 push ecx 23 .text:00436674 push edx 24 .text:00436675 push ds 25 .text:00436676 push es 26 .text:00436677 push gs 27 .text:00436679 mov ax, 23h 28 .text:0043667D sub esp, 30h 29 .text:00436680 mov ds, ax 30 .text:00436683 assume ds:nothing 31 .text:00436683 mov es, ax 32 .text:00436686 assume es:nothing 33 .text:00436686 mov ebp, esp ; 从这里开始 ,EBP已经等于 Trap_Frame 结构,比如ebp+30为SegGs 34 .text:00436688 test [esp+_KTRAP_FRAME.EFlags], 20000h ; 判断 eflag 标准,是否是虚拟8086模式,如果是跳转下面函数 35 .text:00436690 jnz short V86_kit0_a ; 如果是虚拟8086,则继续填充_KTRAP_FRAME 结构 36 .text:00436692 37 .text:00436692 loc_436692: ; CODE XREF: V86_kit0_a+25↑j 38 .text:00436692 mov ecx, large fs:124h 39 .text:00436699 cld 40 .text:0043669A and [ebp+_KTRAP_FRAME.Dr7], 0 41 .text:0043669E test byte ptr [ecx+3], 0DFh 42 .text:004366A2 jnz Dr_kit0_a 43 .text:004366A8 44 .text:004366A8 loc_4366A8: ; CODE XREF: Dr_kit0_a+D↑j 45 .text:004366A8 ; Dr_kit0_a+79↑j 46 .text:004366A8 mov ebx, [ebp+_TRAP_FRAME.Ebp] ; ebp 47 .text:004366AB mov edi, [ebp+_KTRAP_FRAME._Eip] ; eip 48 .text:004366AE mov [ebp+_KTRAP_FRAME.DbgArgPointer], edx 49 .text:004366B1 mov [ebp+_KTRAP_FRAME.DbgArgMark], 0BADB0D00h 50 .text:004366B8 mov [ebp+_KTRAP_FRAME.DbgEbp], ebx ; 保存堆栈 51 .text:004366BB mov [ebp+_KTRAP_FRAME.DbgEip], edi ; 保存异常的EIP 52 .text:004366BE test byte ptr [ebp+(_KTRAP_FRAME.EFlags+2)], 2 53 .text:004366C2 jnz short loc_436712 54 .text:004366C4 test byte ptr [ebp+_KTRAP_FRAME.SegCs], 1 55 .text:004366C8 jnz short loc_4366DB 56 .text:004366CA sti 57 .text:004366CB push ebp 58 .text:004366CC push 0 59 .text:004366CE push 0 60 .text:004366D0 push 0 61 .text:004366D2 push 0 62 .text:004366D4 push 7Fh 63 .text:004366D6 call _KeBugCheck2@24 ; KeBugCheck2(x,x,x,x,x,x) 64 .text:004366DB ; --------------------------------------------------------------------------- 65 .text:004366DB 66 .text:004366DB loc_4366DB: ; CODE XREF: _KiTrap00+78↑j 67 .text:004366DB cmp word ptr [ebp+_KTRAP_FRAME.SegCs], 1Bh 68 .text:004366E0 jnz short loc_4366FF 69 .text:004366E2 sti 70 .text:004366E3 push ebp ; 将trap_frame压进去 71 .text:004366E4 call _Ki386CheckDivideByZeroTrap@4 ; 拿到除零异常的错误码 72 .text:004366E9 mov ebx, [ebp+_KTRAP_FRAME._Eip] 73 .text:004366EC jmp loc_4363FB 74 .text:004366F1 ; --------------------------------------------------------------------------- 75 .text:004366F1 76 .text:004366F1 loc_4366F1: ; CODE XREF: _KiTrap00+C0↓j 77 .text:004366F1 ; _KiTrap00+CB↓j 78 .text:004366F1 sti 79 .text:004366F2 mov ebx, [ebp+_KTRAP_FRAME._Eip] 80 .text:004366F5 mov eax, 0C0000094h 81 .text:004366FA jmp loc_4363FB 82 .text:004366FF ; --------------------------------------------------------------------------- 83 .text:004366FF 84 .text:004366FF loc_4366FF: ; CODE XREF: _KiTrap00+90↑j 85 .text:004366FF mov ebx, large fs:124h 86 .text:00436706 mov ebx, [ebx+50h] 87 .text:00436709 cmp dword ptr [ebx+148h], 0 88 .text:00436710 jz short loc_4366F1 89 .text:00436712 90 .text:00436712 loc_436712: ; CODE XREF: _KiTrap00+72↑j 91 .text:00436712 push 0 92 .text:00436714 call _Ki386VdmReflectException_A@4 ; Ki386VdmReflectException_A(x) 93 .text:00436719 or al, al 94 .text:0043671B jz short loc_4366F1 95 .text:0043671D jmp Kei386EoiHelper@0 ; Kei386EoiHelper() 96 .text:0043671D _KiTrap00 endp
2.CommonDispatchException反汇编代码
1 .text:0043641C CommonDispatchException proc near ; CODE XREF: sub_43653F-142↑p 2 .text:0043641C ; sub_43653F-136↑p ... 3 .text:0043641C 4 .text:0043641C var_50 = dword ptr -50h 5 .text:0043641C var_4C = dword ptr -4Ch 6 .text:0043641C var_48 = dword ptr -48h 7 .text:0043641C var_44 = dword ptr -44h 8 .text:0043641C var_40 = dword ptr -40h 9 .text:0043641C var_3C = byte ptr -3Ch 10 .text:0043641C 11 .text:0043641C sub esp, 50h 12 .text:0043641F mov [esp+_EXCEPTION_RECORD32.ExceptionCode], eax 13 .text:00436422 xor eax, eax 14 .text:00436424 mov [esp+_EXCEPTION_RECORD32.ExceptionFlags], eax 15 .text:00436428 mov [esp+_EXCEPTION_RECORD32.ExceptionRecord], eax 16 .text:0043642C mov [esp+_EXCEPTION_RECORD32.ExceptionAddress], ebx 17 .text:00436430 mov [esp+_EXCEPTION_RECORD32.NumberParameters], ecx 18 .text:00436434 cmp ecx, 0 ; 判断是否存在参数 19 .text:00436437 jz short loc_436445 ; 如果存在参数,则进行赋值,否则直接跳过。 20 .text:00436439 lea ebx, [esp+_EXCEPTION_RECORD32.ExceptionInformation] 21 .text:0043643D mov [ebx], edx 22 .text:0043643F mov [ebx+4], esi 23 .text:00436442 mov [ebx+8], edi 24 .text:00436445 25 .text:00436445 loc_436445: ; CODE XREF: CommonDispatchException+1B↑j 26 .text:00436445 mov ecx, esp ; 将 _EXCEPTION_RECORD 首地址放到 ecx 中 27 .text:00436447 test byte ptr [ebp+72h], 2 28 .text:0043644B jz short loc_436454 29 .text:0043644D mov eax, 0FFFFh 30 .text:00436452 jmp short loc_436457 31 .text:00436454 ; --------------------------------------------------------------------------- 32 .text:00436454 33 .text:00436454 loc_436454: ; CODE XREF: CommonDispatchException+2F↑j 34 .text:00436454 mov eax, [ebp+6Ch] 35 .text:00436457 36 .text:00436457 loc_436457: ; CODE XREF: CommonDispatchException+36↑j 37 .text:00436457 and eax, 1 38 .text:0043645A push 1 ; char 39 .text:0043645C push eax ; int 40 .text:0043645D push ebp ; BugCheckParameter3 41 .text:0043645E push 0 ; int 42 .text:00436460 push ecx ; int 43 .text:00436461 call _KiDispatchException@20 ; KiDispatchException(x,x,x,x,x) 44 .text:00436466 mov esp, ebp 45 .text:00436468 jmp Kei386EoiHelper@0 ; Kei386EoiHelper() 46 .text:00436468 CommonDispatchException endp