简单分析int3与int0

前言

int3和int 0的流程如果只是简单分析其实相当类似,唯一的差别就是int 3的dec操作差点给我整蒙了,所以我们先分析int 3

再次之前先来了解一个结构体

_EXCEPTION_RECORD

kd> dt _EXCEPTION_RECORD
ntdll!_EXCEPTION_RECORD
   +0x000 ExceptionCode    : Int4B    //异常码
   +0x004 ExceptionFlags   : Uint4B
   +0x008 ExceptionRecord  : Ptr32 _EXCEPTION_RECORD
   +0x00c ExceptionAddress : Ptr32 Void    //异常函数
   +0x010 NumberParameters : Uint4B
   +0x014 ExceptionInformation : [15] Uint4B

源码分析

int 3源码

.text:00407AA1 _KiTrap03       proc near               ; DATA XREF: INIT:005ED114↓o
.text:00407AA1
.text:00407AA1 var_2           = word ptr -2
.text:00407AA1 arg_4           = dword ptr  8
.text:00407AA1
.text:00407AA1                 push    0
.text:00407AA3                 mov     [esp+4+var_2], 0
.text:00407AAA                 push    ebp
.text:00407AAB                 push    ebx
.text:00407AAC                 push    esi
.text:00407AAD                 push    edi
.text:00407AAE                 push    fs
.text:00407AB0                 mov     ebx, 30h ; '0'
.text:00407AB5                 mov     fs, ebx
.text:00407AB7                 mov     ebx, large fs:0
.text:00407ABE                 push    ebx
.text:00407ABF                 sub     esp, 4
.text:00407AC2                 push    eax
.text:00407AC3                 push    ecx
.text:00407AC4                 push    edx
.text:00407AC5                 push    ds
.text:00407AC6                 push    es
.text:00407AC7                 push    gs
.text:00407AC9                 mov     ax, 23h ; '#'
.text:00407ACD                 sub     esp, 30h
.text:00407AD0                 mov     ds, eax
.text:00407AD2                 mov     es, eax
.text:00407AD4                 mov     ebp, esp
.text:00407AD6                 test    [esp+_KTRAP_FRAME.EFlags], 20000h
.text:00407ADE                 jnz     short V86_kit3_a
.text:00407AE0
.text:00407AE0 loc_407AE0:                             ; CODE XREF: V86_kit3_a+25↑j
.text:00407AE0                 cld
.text:00407AE1                 mov     ebx, [ebp+_KTRAP_FRAME._Ebp]
.text:00407AE4                 mov     edi, [ebp+_KTRAP_FRAME._Eip]
.text:00407AE7                 mov     [ebp+_KTRAP_FRAME.DbgArgPointer], edx
.text:00407AEA                 mov     [ebp+_KTRAP_FRAME.DbgArgMark], 0BADB0D00h
.text:00407AF1                 mov     [ebp+_KTRAP_FRAME.DbgEbp], ebx
.text:00407AF4                 mov     [ebp+_KTRAP_FRAME.DbgEip], edi
.text:00407AF7                 test    large byte ptr fs:50h, 0FFh
.text:00407AFF                 jnz     Dr_kit3_a
.text:00407B05
.text:00407B05 loc_407B05:                             ; CODE XREF: Dr_kit3_a+10↑j
.text:00407B05                                         ; Dr_kit3_a+7C↑j
.text:00407B05                 cmp     ds:_PoHiberInProgress, 0
.text:00407B0C                 jnz     short loc_407B15
.text:00407B0E                 lock inc ds:_KiHardwareTrigger
.text:00407B15
.text:00407B15 loc_407B15:                             ; CODE XREF: _KiTrap03+6B↑j
.text:00407B15                 mov     eax, 0
.text:00407B1A
.text:00407B1A loc_407B1A:                             ; CODE XREF: _KiDebugService+70↑j
.text:00407B1A                 test    [ebp+_KTRAP_FRAME.EFlags], 20000h ; 判断虚拟8086
.text:00407B21                 jnz     short loc_407B4C
.text:00407B23                 test    word ptr [ebp+_KTRAP_FRAME.SegCs], 1 ; 判断是否从3环来
.text:00407B29                 jz      short loc_407B33
.text:00407B2B                 cmp     word ptr [ebp+_KTRAP_FRAME.SegCs], 1Bh
.text:00407B30                 jnz     short loc_407B4C
.text:00407B32
.text:00407B32 loc_407B32:                             ; CODE XREF: _KiTrap03+BC↓j
.text:00407B32                 sti
.text:00407B33
.text:00407B33 loc_407B33:                             ; CODE XREF: _KiTrap03+88↑j
.text:00407B33                                         ; _KiTrap03+CF↓j
.text:00407B33                 mov     esi, ecx
.text:00407B35                 mov     edi, edx
.text:00407B37                 mov     edx, eax
.text:00407B39                 mov     ebx, [ebp+_KTRAP_FRAME._Eip]
.text:00407B3C                 dec     ebx
.text:00407B3D                 mov     ecx, 3
.text:00407B42                 mov     eax, 80000003h
.text:00407B47                 call    CommonDispatchException
.text:00407B4C
.text:00407B4C loc_407B4C:                             ; CODE XREF: _KiTrap03+80↑j
.text:00407B4C                                         ; _KiTrap03+8F↑j
.text:00407B4C                 mov     ebx, large fs:_KPCR.PrcbData.CurrentThread
.text:00407B53                 mov     ebx, [ebx+_KTHREAD.ApcState.Process]
.text:00407B56                 cmp     dword ptr [ebx+158h], 0
.text:00407B5D                 jz      short loc_407B32
.text:00407B5F                 push    3
.text:00407B61                 call    _Ki386VdmReflectException_A@4 ; Ki386VdmReflectException_A(x)
.text:00407B66                 test    ax, 0FFFFh
.text:00407B6A                 jnz     Kei386EoiHelper@0 ; Kei386EoiHelper()
.text:00407B70                 jmp     short loc_407B33
.text:00407B70 _KiTrap03       endp

我们发现函数在上述的一顿操作后,这里有个小细节需要说,我们发现ebx在获得了3环的eip后,并且进行了dec减一,原因就是需要找到出中断的(这是陷阱异常的特性),就会对CommonDispatchException进行调用

CommonDispatchException

.text:004073A6 CommonDispatchException proc near       ; CODE XREF: _KiTrap00-187↑p
.text:004073A6                                         ; _KiTrap00-17B↑p ...
.text:004073A6
.text:004073A6 var_50          = dword ptr -50h
.text:004073A6 var_4C          = dword ptr -4Ch
.text:004073A6 var_48          = dword ptr -48h
.text:004073A6 var_44          = dword ptr -44h
.text:004073A6 var_40          = dword ptr -40h
.text:004073A6 var_3C          = byte ptr -3Ch
.text:004073A6
.text:004073A6                 sub     esp, 50h
.text:004073A9                 mov     [esp+_EXCEPTION_RECORD.ExceptionCode], eax
.text:004073AC                 xor     eax, eax
.text:004073AE                 mov     [esp+_EXCEPTION_RECORD.ExceptionFlags], eax
.text:004073B2                 mov     [esp+_EXCEPTION_RECORD.ExceptionRecord], eax
.text:004073B6                 mov     [esp+_EXCEPTION_RECORD.ExceptionAddress], ebx ; EIP
.text:004073BA                 mov     [esp+_EXCEPTION_RECORD.NumberParameters], ecx
.text:004073BE                 cmp     ecx, 0
.text:004073C1                 jz      short loc_4073CF
.text:004073C3                 lea     ebx, [esp+_EXCEPTION_RECORD.ExceptionInformation]
.text:004073C7                 mov     [ebx], edx
.text:004073C9                 mov     [ebx+4], esi
.text:004073CC                 mov     [ebx+8], edi
.text:004073CF
.text:004073CF loc_4073CF:                             ; CODE XREF: CommonDispatchException+1B↑j
.text:004073CF                 mov     ecx, esp
.text:004073D1                 test    [ebp+_KTRAP_FRAME.EFlags], 20000h ; 判断是否为虚拟8086模式
.text:004073D8                 jz      short loc_4073E1
.text:004073DA                 mov     eax, 0FFFFh
.text:004073DF                 jmp     short loc_4073E4
.text:004073E1 ; ---------------------------------------------------------------------------
.text:004073E1
.text:004073E1 loc_4073E1:                             ; CODE XREF: CommonDispatchException+32↑j
.text:004073E1                 mov     eax, [ebp+_KTRAP_FRAME.SegCs]
.text:004073E4
.text:004073E4 loc_4073E4:                             ; CODE XREF: CommonDispatchException+39↑j
.text:004073E4                 and     eax, 1
.text:004073E7                 push    1               ; char
.text:004073E9                 push    eax             ; int
.text:004073EA                 push    ebp             ; BugCheckParameter3
.text:004073EB                 push    0               ; int
.text:004073ED                 push    ecx             ; ExceptionRecord
.text:004073EE                 call    _KiDispatchException@20 ; KiDispatchException(x,x,x,x,x)
.text:004073F3                 mov     esp, ebp
.text:004073F5                 jmp     Kei386EoiHelper@0 ; Kei386EoiHelper()
.text:004073F5 CommonDispatchException endp

在进入该函数后,我们可以发先其最终又调用了_KiDispatchException(异常分发函数,这个要到后面几篇回有介绍的)

我们在来看看int 0的差别在哪

int 0

.text:0040750E                 push    0
.text:00407510                 mov     [esp+4+var_2], 0 ; 填充TrapFrame
.text:00407517                 push    ebp
.text:00407518                 push    ebx
.text:00407519                 push    esi
.text:0040751A                 push    edi
.text:0040751B                 push    fs
.text:0040751D                 mov     ebx, 30h ; '0'
.text:00407522                 mov     fs, ebx
.text:00407524                 assume fs:nothing
.text:00407524                 mov     ebx, large fs:0
.text:0040752B                 push    ebx
.text:0040752C                 sub     esp, 4
.text:0040752F                 push    eax
.text:00407530                 push    ecx
.text:00407531                 push    edx
.text:00407532                 push    ds
.text:00407533                 push    es
.text:00407534                 push    gs
.text:00407536                 mov     ax, 23h ; '#'
.text:0040753A                 sub     esp, 30h
.text:0040753D                 mov     ds, eax         ; ds=0x23
.text:0040753F                 assume ds:nothing
.text:0040753F                 mov     es, eax         ; es=0x23
.text:00407541                 assume es:nothing
.text:00407541                 mov     ebp, esp        ; 提升堆栈到_Trap_Frame的0x00偏移处(DbgEbp)
.text:00407543                 test    [esp+_KTRAP_FRAME.EFlags], 20000h ; 判断是否为虚拟8086模式
.text:0040754B                 jnz     short V86_kit0_a
.text:0040754D
.text:0040754D loc_40754D:                             ; CODE XREF: V86_kit0_a+25↑j
.text:0040754D                 cld
.text:0040754E                 mov     ebx, [ebp+_KTRAP_FRAME._Ebp]
.text:00407551                 mov     edi, [ebp+_KTRAP_FRAME._Eip]
.text:00407554                 mov     [ebp+_KTRAP_FRAME.DbgArgPointer], edx
.text:00407557                 mov     [ebp+_KTRAP_FRAME.DbgArgMark], 0BADB0D00h
.text:0040755E                 mov     [ebp+_KTRAP_FRAME.DbgEbp], ebx
.text:00407561                 mov     [ebp+_KTRAP_FRAME.DbgEip], edi
.text:00407564                 test    large byte ptr fs:50h, 0FFh ; 判断内核调试器是否存在,存在则跳转
.text:0040756C                 jnz     Dr_kit0_a
.text:00407572
.text:00407572 loc_407572:                             ; CODE XREF: Dr_kit0_a+10↑j
.text:00407572                                         ; Dr_kit0_a+7C↑j
.text:00407572                 test    [ebp+_KTRAP_FRAME.EFlags], 20000h ; 判断是否为虚拟8086模式
.text:00407579                 jnz     short loc_4075B8 ; 是则跳转
.text:0040757B                 test    byte ptr [ebp+_KTRAP_FRAME.SegCs], 1 ; 是从3环来的还是0环来的
.text:0040757F                 jz      short loc_407588 ; 是0环则跳转
.text:00407581                 cmp     word ptr [ebp+_KTRAP_FRAME.SegCs], 1Bh
.text:00407586                 jnz     short loc_4075A5
.text:00407588
.text:00407588 loc_407588:                             ; CODE XREF: _KiTrap00+71↑j
.text:00407588                 sti
.text:00407589                 push    ebp
.text:0040758A                 call    _Ki386CheckDivideByZeroTrap@4 ; Ki386CheckDivideByZeroTrap(x)
.text:0040758F                 mov     ebx, [ebp+68h]
.text:00407592                 jmp     loc_407385
.text:00407597 ; ---------------------------------------------------------------------------
.text:00407597
.text:00407597 loc_407597:                             ; CODE XREF: _KiTrap00+A8↓j
.text:00407597                                         ; _KiTrap00+B9↓j
.text:00407597                 sti
.text:00407598                 mov     ebx, [ebp+_KTRAP_FRAME._Eip]
.text:0040759B                 mov     eax, 0C0000094h ; 异常码
.text:004075A0                 jmp     loc_407385
.text:004075A5 ; ---------------------------------------------------------------------------
.text:004075A5
.text:004075A5 loc_4075A5:                             ; CODE XREF: _KiTrap00+78↑j
.text:004075A5                 mov     ebx, large fs:_KPCR.PrcbData.CurrentThread
.text:004075AC                 mov     ebx, [ebx+_KTHREAD.ApcState.Process]
.text:004075AF                 cmp     [ebx+_EPROCESS.VdmObjects], 0
.text:004075B6                 jz      short loc_407597
.text:004075B8
.text:004075B8 loc_4075B8:                             ; CODE XREF: _KiTrap00+6B↑j
.text:004075B8                 push    0
.text:004075BA                 call    _Ki386VdmReflectException_A@4 ; Ki386VdmReflectException_A(x)
.text:004075BF                 or      al, al
.text:004075C1                 jnz     Kei386EoiHelper@0 ; Kei386EoiHelper()
.text:004075C7                 jmp     short loc_407597
.text:004075C7 _KiTrap00       endp

我们很容易发现int 0和int 3就是少了哪个dec 指令,其余的流程跟int 3几乎一模一样

posted @ 2021-02-01 15:32  PYozo_free  阅读(412)  评论(0编辑  收藏  举报