zoukankan      html  css  js  c++  java
  • Int 1的实现过程 (一)

      闲话少说,直奔主题,首先OD载入一个程序,然后执行一下单步(调试器会将TF置1)

      此时,CPU会在基于当前线程上下文的环境中,进入int 1的中断门,也就是KiTrap01

    kd> !idt -a
    
    Dumping IDT:
    
    00:	805431a0 nt!KiTrap00
    01:	8054331c nt!KiTrap01     // int 1会转到这个函数执行
    02:	Task Selector = 0x0058   // NMI  从这里可以看到NMI是通过任务门执行的
    03:	80543730 nt!KiTrap03
    04:	805438b0 nt!KiTrap04
    05:	80543a10 nt!KiTrap05
    06:	80543b84 nt!KiTrap06
    07:	805441fc nt!KiTrap07
    08:	Task Selector = 0x0050  // DF 因为发生DF时,寄存器可能已经出错了,所以需要任务门,加载新的环境
    09:	80544600 nt!KiTrap09
    

      然后我们看下windbg,首先在KiTrap01下断,其次通过OD的单步后,确实已经中断到windbg的KiTrap01处了,其环境也是被调试线程的环境

         看下TSS中ESP0的值

    kd> r tr
    tr=00000028
    kd> dg 28
                                      P Si Gr Pr Lo
    Sel    Base     Limit     Type    l ze an es ng Flags
    ---- -------- -------- ---------- - -- -- -- -- --------
    0028 80042000 000020ab TSS32 Busy 0 Nb By P  Nl 0000008b
    kd> dd 80042000
    80042000  0c458b24 b23b9de0 8b080010 758b0855  //b23b9de0就是ESP0的值 

            intel手册中说到,在转移到中断例程入口前,会先将SS  ESP  EFLAGS  CS  EIP  ErrorCode压入内核栈,所以我们看看ESP0中的值

    kd> dd esp
    b23b9dcc 00421480 0000001b 00000346 0012ffc0
    b23b9ddc 00000023                  //从这里可以得知   SS:23    ESP:12FFC0    EFLAGS:346    CS:1b    EIP:421480
    

        好了,可以进入正题了,先看下KiTrap01的执行过程

    nt!KiTrap01:
    8054331c 6a00            push    0                 // ErrorCode
    8054331e 66c74424020000  mov     word ptr [esp+2],0
    80543325 55              push    ebp
    80543326 53              push    ebx
    80543327 56              push    esi
    80543328 57              push    edi
    80543329 0fa0            push    fs
    8054332b bb30000000      mov     ebx,30h
    80543330 668ee3          mov     fs,bx
    80543333 648b1d00000000  mov     ebx,dword ptr fs:[0]
    8054333a 53              push    ebx                // ExceptionList
    8054333b 83ec04          sub     esp,4               // PreviousPreviousMode
    8054333e 50              push    eax
    8054333f 51              push    ecx
    80543340 52              push    edx
    80543341 1e              push    ds
    80543342 06              push    es
    80543343 0fa8            push    gs
    80543345 66b82300        mov     ax,23h
    80543349 83ec30          sub     esp,30h             // 到这里_KTRAP_FRAME已经填充一半了,还差30h
    8054334c 668ed8          mov     ds,ax
    8054334f 668ec0          mov     es,ax
    80543352 8bec            mov     ebp,esp
    80543354 f744247000000200 test    dword ptr [esp+70h],20000h  // 检测是否是虚拟8086模式
    8054335c 7596            jne     nt!V86_kit1_a (805432f4)      // 是虚拟8086模式的话,就发生跳转,这里我们应该继续执行
    8054335e fc              cld
    8054335f 8b5d60          mov     ebx,dword ptr [ebp+60h]      // 被压入栈的EBP寄存器的值,这里是12FFF0
    80543362 8b7d68          mov     edi,dword ptr [ebp+68h]      // 被压入栈中EIP寄存器的值,这里是421480
    80543365 89550c          mov     dword ptr [ebp+0Ch],edx    // KiFastSystemCall
    80543368 c74508000ddbba  mov     dword ptr [ebp+8],0BADB0D00h // DbgArgMark
    8054336f 895d00          mov     dword ptr [ebp],ebx      // DbgEbp
    80543372 897d04          mov     dword ptr [ebp+4],edi     // DbgEip

    /************************************************************************************************************************************** /*****                  执行完这几个栈操作后,我们看下栈中的值                                   *****
    /**************************************************************************************************************************************   kd> dd ebp  其实这里都是KTRAP_FTAME的值   b23b9d64 0012fff0  00421480 badb0d00 7c92e4f4   b23b9d74 7c930208 ffffffff ffffffff 0012fff0   b23b9d84 00000000 80543349 00000008 00000196   b23b9d94 00000000 00000023 00000023 7c92e4f4   b23b9da4 0012ffb0 00000000 00000146 ffffffff   b23b9db4 00000030 7c930208 ffffffff 7ffd8000   b23b9dc4 0012fff0 00000000 00421480 0000001b   b23b9dd4 00000346 0012ffc0 00000023 805470de 80543375 64f60550000000ff test byte ptr fs:[50h],0FFh    // 测试DebugActive 8054337d 0f85edfeffff jne nt!Dr_kit1_a (80543270) 80543383 64833d5400000000 cmp dword ptr fs:[54h],0 8054338b 7561 jne nt!KiTrap01+0xd2 (805433ee) 8054338d 8b4d68 mov ecx,dword ptr [ebp+68h] 80543390 81f920255480 cmp ecx,offset nt!KiFastCallEntry (80542520)   80543396 0f84c4feffff je nt!KiTrap00+0xc0 (80543260) // 测试是不是sysenter指令,如果是的话,不能步过 8054339c f7457000000200 test dword ptr [ebp+70h],20000h 805433a3 7524       jne    nt!KiTrap01+0xad (805433c9) // 检测虚拟8086模式 805433a5 66f7456c0100 test   word ptr [ebp+6Ch],1     805433ab 7408      je    nt!KiTrap01+0x99 (805433b5)   // 检测当前CPL,如果是R3的话,就不发生跳转 805433ad 66837d6c1b   cmp    word ptr [ebp+6Ch],1Bh 805433b2 7515       jne    nt!KiTrap01+0xad (805433c9)     // 如果是R3的话,CS应该是1B,如果不是的话,发生跳转 805433b4 fb         sti 805433b5 816570fffeffff and    dword ptr [ebp+70h],0FFFFFEFFh   //EFLAGS的TF位清零 805433bc 8b5d68 mov    ebx,dword ptr [ebp+68h]     // (ebx)-> faulting instruction 805433bf b804000080 mov   eax,80000004h         // TF异常的错误码 805433c4 e94efcffff jmp   nt!KiExceptionExit+0x16b (80543017)

     

    80543017 33c9            xor     ecx,ecx
    80543019 e81a000000      call    nt!CommonDispatchException (80543038)  // Never return
    

     接下来看看CommonDispatchException内部都做了些什么

    /**********************************************************************************************
    /*****          Set up exception record for raising exception            *****
    /**********************************************************************************************
    首先来看看EXCEPTION_RECORD
      kd> dt _exception_record
      nt!_EXCEPTION_RECORD
      +0x000 ExceptionCode : Int4B
      +0x004 ExceptionFlags : Uint4B
      +0x008 ExceptionRecord : Ptr32 _EXCEPTION_RECORD
      +0x00c ExceptionAddress : Ptr32 Void
      +0x010 NumberParameters : Uint4B
      +0x014 ExceptionInformation : [15] Uint4B
    
    
    nt!CommonDispatchException:
    80543038 83ec50          sub     esp,50h            // ExceptionRecordLength, allocate exception record
    8054303b 890424          mov     dword ptr [esp],eax     // set ExceptionCode           其实也就是上文的80000004h
    8054303e 33c0            xor     eax,eax
    80543040 89442404        mov     dword ptr [esp+4],eax    // set ExceptionFlags         这里为0
    80543044 89442408        mov     dword ptr [esp+8],eax    //  set associated ExceptionRecord 这里为0
    80543048 895c240c        mov     dword ptr [esp+0Ch],ebx  //  set ExceptionAddress       其实也就是上文的421480
    8054304c 894c2410        mov     dword ptr [esp+10h],ecx  //  set NumberParameters       这里为0
    80543050 83f900          cmp     ecx,0
    80543053 740c            je      nt!CommonDispatchException+0x29 (80543061)  
    
    //跳到了这里 set up arguments and call _KiDispatchException
    80543061 8bcc       mov ecx,esp               //  (ecx)->exception record
    80543063 f7457000000200 test dword ptr [ebp+70h],20000h
    8054306a 7407       je nt!CommonDispatchException+0x3b (80543073)  // 因为不是虚拟8086模式,所以会发生跳转
    
    //跳转到这里后,就该调用KiDispatchException了
    stdCall _KiDispatchException,<ecx, 0, ebp, eax, 1>      //  汇编中的原型
    KiDispatchException (                       //  API中的原型
    IN PEXCEPTION_RECORD ExceptionRecord,
    IN PKEXCEPTION_FRAME ExceptionFrame,
    IN PKTRAP_FRAME TrapFrame,
    IN KPROCESSOR_MODE PreviousMode,
    IN BOOLEAN FirstChance
    )
    
    80543073 8b456c      mov   eax,dword ptr [ebp+6Ch]   
    80543076 83e001      and   eax,1           //  通过CS段选择子,得到被调试程序的CPL, 通过与运算后,得到后面的PreviousMode
    80543079 6a01       push  1              //  1 - first chance TRUE
    8054307b 50        push  eax            //  eax - PreviousMode
    8054307c 55         push  ebp            //  TrapFrame
    8054307d 6a00        push  0             //   ExceptionFrame
    8054307f 51        push  ecx            //   ExceptionRecord
    80543080 e8e1c3fbff    call   nt!KiDispatchException (804ff466)
    

      

    这里再看看我们的KTRAP_FRAME的具体值,这些值能很详细的说明故障信息

    kd> dt _ktrap_frame b2bf3d64
    nt!_KTRAP_FRAME
       +0x000 DbgEbp           : 0x12fff0
       +0x004 DbgEip           : 0x421480
       +0x008 DbgArgMark       : 0xbadb0d00
       +0x00c DbgArgPointer    : 0x7c92e4f4
       +0x010 TempSegCs        : 0x7c930208
       +0x014 TempEsp          : 0xffffffff
       +0x018 Dr0              : 0xffffffff
       +0x01c Dr1              : 0x12fff0
       +0x020 Dr2              : 0
       +0x024 Dr3              : 0x80543349
       +0x028 Dr6              : 8
       +0x02c Dr7              : 0x196
       +0x030 SegGs            : 0
       +0x034 SegEs            : 0x23
       +0x038 SegDs            : 0x23
       +0x03c Edx              : 0x7c92e4f4
       +0x040 Ecx              : 0x12ffb0
       +0x044 Eax              : 0
       +0x048 PreviousPreviousMode : 0x146
       +0x04c ExceptionList    : 0xffffffff _EXCEPTION_REGISTRATION_RECORD
       +0x050 SegFs            : 0x30
       +0x054 Edi              : 0x7c930208
       +0x058 Esi              : 0xffffffff
       +0x05c Ebx              : 0x7ffd8000
       +0x060 Ebp              : 0x12fff0
       +0x064 ErrCode          : 0
       +0x068 Eip              : 0x421480
       +0x06c SegCs            : 0x1b
       +0x070 EFlags           : 0x246
       +0x074 HardwareEsp      : 0x12ffc0
       +0x078 HardwareSegSs    : 0x23
       +0x07c V86Es            : 0
       +0x080 V86Ds            : 0
       +0x084 V86Fs            : 0
       +0x088 V86Gs            : 0
    

      

      好了,先分析到这吧,明天分析KiDispatchException这个函数......困了!

                                                                  01:08:21

      

      

     
  • 相关阅读:
    Python如何利用Xpath进行解析
    Java的GUI如何能够切换界面
    Java的GUI设计小技巧
    Java的GUI设计中如何跨界面传值(static的用法)
    GUI的优化操作/添加背景图片等
    IDEA导入MySQL包
    Java的GUI设计
    IDEA如何把写好的java文件/项目打包成一个jar的文件
    clion中资源文件以及头文件的引用
    如何为python 2.7安装tensorflow?
  • 原文地址:https://www.cnblogs.com/testvt/p/5724394.html
Copyright © 2011-2022 走看看