• 用户APC的执行过程


    Windows内核分析索引目录:https://www.cnblogs.com/onetrainee/p/11675224.html

    用户APC的执行过程

    一、一个启发式问题

      有一个问题,线程什么时候检查自己的APC队列,答案前面已经介绍过,是执行KiServerExit函数时。

      KiServiceExit函数:这个函数是系统调用、异常或中断的必经之路。

      也就是说:当线程发现自己有APC要执行时,已经处于内核了,我们在系统调用那一节介绍过,从三环到零环,将数据保存在 _KTRAP_FRAME 结构体中。

      现在,我们发现有用户APC要执行,肯定要返回三环,肯定也需要借助 _KTRAP_FRAME 结构体。

      但是,_KTRAP_FRAME结构体保存着是原先的三环地址,返回绝对不可能返回到那里去,一定返回另外一个地方。

      可一个线程只有一个_KTRAP_FRAME,返回只能通过这个返回。

      因此,我们真正要做的:将原来的_KTRAP_FRAME结构体保存起来,之后建立一个新的,往里面写入返回时执行的ESP(栈地址)与EIP(代码地址),之后返回三环执行。

        执行完之后返回到零环,继续执行原来的任务。(如果搞懂这一点,那么用户APC的执行过程已经解决一大半了!)

    二、用户APC过程分析:

    由于分析量大,代码繁杂,直接整理成图标的形式展现出来,最后附带反汇编代码可以自己观看。

     三、反汇编代码

    1. KiserviceExit(ntkrnlpa.exe)代码分析

      1 :004667F0 _KiServiceExit2 proc near               ; CODE XREF: NtContinue(x,x)+3A↓j
      2 .text:004667F0                                         ; NtRaiseException(x,x,x)+3C↓j ...
      3 .text:004667F0
      4 .text:004667F0 arg_C           = dword ptr  10h
      5 .text:004667F0 arg_10          = dword ptr  14h
      6 .text:004667F0 arg_38          = dword ptr  3Ch
      7 .text:004667F0 arg_3C          = dword ptr  40h
      8 .text:004667F0 arg_40          = dword ptr  44h
      9 .text:004667F0 arg_44          = dword ptr  48h
     10 .text:004667F0 arg_48          = dword ptr  4Ch
     11 .text:004667F0 arg_60          = dword ptr  64h
     12 .text:004667F0 arg_64          = dword ptr  68h
     13 .text:004667F0 arg_68          = dword ptr  6Ch
     14 .text:004667F0 arg_6C          = dword ptr  70h
     15 .text:004667F0
     16 .text:004667F0                 cli
     17 .text:004667F1                 test    dword ptr [ebp+70h], 20000h
     18 .text:004667F8                 jnz     short loc_466800 ; 获取Kthread
     19 .text:004667FA                 test    byte ptr [ebp+6Ch], 1
     20 .text:004667FE                 jz      short loc_466834
     21 .text:00466800
     22 .text:00466800 loc_466800:                             ; CODE XREF: _KiServiceExit2+8↑j
     23 .text:00466800                                         ; _KiServiceExit2+41↓j
     24 .text:00466800                 mov     ebx, ds:0FFDFF124h ; 获取Kthread
     25 .text:00466806                 mov     byte ptr [ebx+2Eh], 0
     26 .text:0046680A                 cmp     byte ptr [ebx+4Ah], 0 ; 判断是否有用户APC请求
     27 .text:0046680E                 jz      short loc_466834 ; 如果有APC请求则不会跳转
     28 .text:00466810                 mov     ebx, ebp
     29 .text:00466812                 mov     ecx, 1          ; NewIrql
     30 .text:00466817                 call    ds:__imp_@KfRaiseIrql@4 ; KfRaiseIrql(x)
     31 .text:0046681D                 push    eax
     32 .text:0046681E                 sti
     33 .text:0046681F                 push    ebx
     34 .text:00466820                 push    0
     35 .text:00466822                 push    1               ; 这里处理用户层的APC函数
     36 .text:00466824                 call    _KiDeliverApc@12 ; 该函数实现对APC的处理
     37 .text:00466829                 pop     ecx             ; NewIrql
     38 .text:0046682A                 call    ds:__imp_@KfLowerIrql@4 ; KfLowerIrql(x)
     39 .text:00466830                 cli
     40 .text:00466831                 jmp     short loc_466800 ; 获取Kthread
     41 .text:00466831 ; ---------------------------------------------------------------------------
     42 .text:00466833                 db  90h
     43 .text:00466834 ; ---------------------------------------------------------------------------
     44 .text:00466834
     45 .text:00466834 loc_466834:                             ; CODE XREF: _KiServiceExit2+E↑j
     46 .text:00466834                                         ; _KiServiceExit2+1E↑j
     47 .text:00466834                 mov     edx, [esp+arg_48]
     48 .text:00466838                 mov     ebx, large fs:50h
     49 .text:0046683F                 mov     large fs:0, edx
     50 .text:00466846                 mov     ecx, [esp+arg_44]
     51 .text:0046684A                 mov     esi, large fs:124h
     52 .text:00466851                 mov     [esi+140h], cl
     53 .text:00466857                 test    ebx, 0FFh
     54 .text:0046685D                 jnz     short loc_4668B0
     55 .text:0046685F
     56 .text:0046685F loc_46685F:                             ; CODE XREF: _KiServiceExit2+D0↓j
     57 .text:0046685F                                         ; _KiServiceExit2+FB↓j
     58 .text:0046685F                 test    [esp+arg_6C], 20000h
     59 .text:00466867                 jnz     loc_466FD4
     60 .text:0046686D                 test    word ptr [esp+arg_68], 0FFF8h
     61 .text:00466874                 jz      short loc_4668F0
     62 .text:00466876                 mov     edx, [esp+arg_38]
     63 .text:0046687A                 mov     ecx, [esp+arg_3C]
     64 .text:0046687E                 mov     eax, [esp+arg_40]
     65 .text:00466882                 cmp     word ptr [ebp+6Ch], 8
     66 .text:00466887                 jz      short loc_466895
     67 .text:00466889                 lea     esp, [ebp+30h]
     68 .text:0046688C                 pop     gs
     69 .text:0046688E                 pop     es
     70 .text:0046688F                 pop     ds
     71 .text:00466890                 lea     esp, [ebp+50h]
     72 .text:00466893                 pop     fs
     73 .text:00466895
     74 .text:00466895 loc_466895:                             ; CODE XREF: _KiServiceExit2+97↑j
     75 .text:00466895                 lea     esp, [ebp+54h]
     76 .text:00466898                 pop     edi
     77 .text:00466899                 pop     esi
     78 .text:0046689A                 pop     ebx
     79 .text:0046689B                 pop     ebp
     80 .text:0046689C                 cmp     word ptr [esp-60h+arg_64], 80h
     81 .text:004668A3                 ja      loc_466FF0
     82 .text:004668A9                 add     esp, 4
     83 .text:004668AC                 iret
     84 .text:004668AC ; ---------------------------------------------------------------------------
     85 .text:004668AD                 db  8Dh
     86 .text:004668AE                 db  49h ; I
     87 .text:004668AF                 db    0
     88 .text:004668B0 ; ---------------------------------------------------------------------------
     89 .text:004668B0
     90 .text:004668B0 loc_4668B0:                             ; CODE XREF: _KiServiceExit2+6D↑j
     91 .text:004668B0                 test    dword ptr [ebp+70h], 20000h
     92 .text:004668B7                 jnz     short loc_4668C2
     93 .text:004668B9                 test    dword ptr [ebp+6Ch], 1
     94 .text:004668C0                 jz      short loc_46685F
     95 .text:004668C2
     96 .text:004668C2 loc_4668C2:                             ; CODE XREF: _KiServiceExit2+C7↑j
     97 .text:004668C2                 xor     ebx, ebx
     98 .text:004668C4                 mov     esi, [ebp+18h]
     99 .text:004668C7                 mov     edi, [ebp+1Ch]
    100 .text:004668CA                 mov     dr7, ebx
    101 .text:004668CD                 mov     dr0, esi
    102 .text:004668D0                 mov     ebx, [ebp+20h]
    103 .text:004668D3                 mov     dr1, edi
    104 .text:004668D6                 mov     dr2, ebx
    105 .text:004668D9                 mov     esi, [ebp+24h]
    106 .text:004668DC                 mov     edi, [ebp+28h]
    107 .text:004668DF                 mov     ebx, [ebp+2Ch]
    108 .text:004668E2                 mov     dr3, esi
    109 .text:004668E5                 mov     dr6, edi
    110 .text:004668E8                 mov     dr7, ebx
    111 .text:004668EB                 jmp     loc_46685F
    112 .text:004668F0 ; ---------------------------------------------------------------------------
    113 .text:004668F0
    114 .text:004668F0 loc_4668F0:                             ; CODE XREF: _KiServiceExit2+84↑j
    115 .text:004668F0                 mov     ebx, [esp+arg_C]
    116 .text:004668F4                 mov     [esp+arg_68], ebx
    117 .text:004668F8                 mov     ebx, [esp+arg_10]
    118 .text:004668FC                 sub     ebx, 0Ch
    119 .text:004668FF                 mov     [esp+arg_60], ebx
    120 .text:00466903                 mov     esi, [esp+arg_6C]
    121 .text:00466907                 mov     [ebx+8], esi
    122 .text:0046690A                 mov     esi, [esp+arg_68]
    123 .text:0046690E                 mov     [ebx+4], esi
    124 .text:00466911                 mov     esi, [esp+arg_64]
    125 .text:00466915                 mov     [ebx], esi
    126 .text:00466917                 mov     eax, [esp+arg_40]
    127 .text:0046691B                 mov     edx, [esp+arg_38]
    128 .text:0046691F                 mov     ecx, [esp+arg_3C]
    129 .text:00466923                 add     esp, 54h
    130 .text:00466926                 pop     edi
    131 .text:00466927                 pop     esi
    132 .text:00466928                 pop     ebx
    133 .text:00466929                 pop     ebp
    134 .text:0046692A                 mov     esp, [esp-64h+arg_60]
    135 .text:0046692D                 iret
    136 .text:0046692D _KiServiceExit2 endp ; sp-analysis failed

    2. KiDeliverApc(ntkrnlpa.exe)代码分析

      1 ; __stdcall KiDeliverApc(x, x, x)
      2 .text:00426A2E                 public _KiDeliverApc@12
      3 .text:00426A2E _KiDeliverApc@12 proc near              ; CODE XREF: KiSwapThread()+5F↓p
      4 .text:00426A2E                                         ; _KiSystemService+21B↓p ...
      5 .text:00426A2E
      6 .text:00426A2E LockHandle      = _KLOCK_QUEUE_HANDLE ptr -28h
      7 .text:00426A2E var_1C          = dword ptr -1Ch
      8 .text:00426A2E BugCheckParameter1= dword ptr -18h
      9 .text:00426A2E var_14          = dword ptr -14h
     10 .text:00426A2E var_10          = dword ptr -10h
     11 .text:00426A2E var_C           = dword ptr -0Ch
     12 .text:00426A2E var_8           = dword ptr -8
     13 .text:00426A2E var_4           = dword ptr -4
     14 .text:00426A2E arg_0           = byte ptr  8
     15 .text:00426A2E arg_4           = dword ptr  0Ch
     16 .text:00426A2E arg_8           = dword ptr  10h
     17 .text:00426A2E
     18 .text:00426A2E                 mov     edi, edi
     19 .text:00426A30                 push    ebp
     20 .text:00426A31                 mov     ebp, esp
     21 .text:00426A33                 sub     esp, 28h
     22 .text:00426A36                 mov     ecx, [ebp+arg_8]
     23 .text:00426A39                 test    ecx, ecx
     24 .text:00426A3B                 jz      short loc_426A54
     25 .text:00426A3D                 mov     edx, [ecx+68h]
     26 .text:00426A40                 mov     eax, offset _ExpInterlockedPopEntrySListResume@0 ; ExpInterlockedPopEntrySListResume()
     27 .text:00426A45                 cmp     edx, eax
     28 .text:00426A47                 jb      short loc_426A54
     29 .text:00426A49                 cmp     edx, offset _ExpInterlockedPopEntrySListEnd@0 ; ExpInterlockedPopEntrySListEnd()
     30 .text:00426A4F                 ja      short loc_426A54
     31 .text:00426A51                 mov     [ecx+68h], eax
     32 .text:00426A54
     33 .text:00426A54 loc_426A54:                             ; CODE XREF: KiDeliverApc(x,x,x)+D↑j
     34 .text:00426A54                                         ; KiDeliverApc(x,x,x)+19↑j ...
     35 .text:00426A54                 push    ebx
     36 .text:00426A55                 push    esi
     37 .text:00426A56                 push    edi
     38 .text:00426A57                 mov     eax, large fs:124h
     39 .text:00426A5D                 mov     esi, eax
     40 .text:00426A5F                 mov     eax, [esi+134h]
     41 .text:00426A65                 mov     [ebp+var_1C], eax
     42 .text:00426A68                 mov     eax, [esi+44h]
     43 .text:00426A6B                 mov     [esi+134h], ecx
     44 .text:00426A71                 lea     ecx, [esi+0E8h] ; SpinLock
     45 .text:00426A77                 lea     edx, [ebp+LockHandle] ; LockHandle
     46 .text:00426A7A                 mov     [ebp+BugCheckParameter1], eax
     47 .text:00426A7D                 call    ds:__imp_@KeAcquireInStackQueuedSpinLock@8 ; KeAcquireInStackQueuedSpinLock(x,x)
     48 .text:00426A83                 mov     byte ptr [esi+49h], 0
     49 .text:00426A87                 lea     ebx, [esi+34h]  ; 取内核APC列表(双向链表 第一个内核 第二个用户)
     50 .text:00426A8A                 jmp     loc_426B70      ; 判断第一个链表是否为空,如果内核与当前地址一样,说明没有内核APC函数。
     51 .text:00426A8F ; ---------------------------------------------------------------------------
     52 .text:00426A8F
     53 .text:00426A8F loc_426A8F:                             ; CODE XREF: KiDeliverApc(x,x,x)+144↓j
     54 .text:00426A8F                 mov     eax, [ebx]
     55 .text:00426A91                 lea     edi, [eax-0Ch]
     56 .text:00426A94                 mov     ecx, [edi+14h]
     57 .text:00426A97                 mov     [ebp+var_14], ecx
     58 .text:00426A9A                 mov     ecx, [edi+1Ch]
     59 .text:00426A9D                 test    ecx, ecx
     60 .text:00426A9F                 mov     [ebp+var_4], ecx
     61 .text:00426AA2                 mov     edx, [edi+20h]
     62 .text:00426AA5                 mov     [ebp+var_10], edx
     63 .text:00426AA8                 mov     edx, [edi+24h]
     64 .text:00426AAB                 mov     [ebp+var_C], edx
     65 .text:00426AAE                 mov     edx, [edi+28h]
     66 .text:00426AB1                 mov     [ebp+var_8], edx
     67 .text:00426AB4                 jnz     short loc_426AF2
     68 .text:00426AB6                 mov     ecx, [eax]
     69 .text:00426AB8                 mov     eax, [eax+4]
     70 .text:00426ABB                 mov     [eax], ecx
     71 .text:00426ABD                 mov     [ecx+4], eax
     72 .text:00426AC0                 lea     ecx, [ebp+LockHandle] ; LockHandle
     73 .text:00426AC3                 mov     byte ptr [edi+2Eh], 0
     74 .text:00426AC7                 call    ds:__imp_@KeReleaseInStackQueuedSpinLock@4 ; KeReleaseInStackQueuedSpinLock(x)
     75 .text:00426ACD                 lea     eax, [ebp+var_8]
     76 .text:00426AD0                 push    eax
     77 .text:00426AD1                 lea     eax, [ebp+var_C]
     78 .text:00426AD4                 push    eax
     79 .text:00426AD5                 lea     eax, [ebp+var_10]
     80 .text:00426AD8                 push    eax
     81 .text:00426AD9                 lea     eax, [ebp+var_4]
     82 .text:00426ADC                 push    eax
     83 .text:00426ADD                 push    edi
     84 .text:00426ADE                 call    [ebp+var_14]
     85 .text:00426AE1                 lea     edx, [ebp+LockHandle] ; LockHandle
     86 .text:00426AE4                 lea     ecx, [esi+0E8h] ; SpinLock
     87 .text:00426AEA                 call    ds:__imp_@KeAcquireInStackQueuedSpinLock@8 ; KeAcquireInStackQueuedSpinLock(x,x)
     88 .text:00426AF0                 jmp     short loc_426B70 ; 判断第一个链表是否为空,如果内核与当前地址一样,说明没有内核APC函数。
     89 .text:00426AF2 ; ---------------------------------------------------------------------------
     90 .text:00426AF2
     91 .text:00426AF2 loc_426AF2:                             ; CODE XREF: KiDeliverApc(x,x,x)+86↑j
     92 .text:00426AF2                 cmp     byte ptr [esi+48h], 0
     93 .text:00426AF6                 jnz     loc_426C05
     94 .text:00426AFC                 cmp     dword ptr [esi+0D4h], 0
     95 .text:00426B03                 jnz     loc_426C05
     96 .text:00426B09                 mov     ecx, [eax]
     97 .text:00426B0B                 mov     eax, [eax+4]
     98 .text:00426B0E                 mov     [eax], ecx
     99 .text:00426B10                 mov     [ecx+4], eax
    100 .text:00426B13                 lea     ecx, [ebp+LockHandle] ; LockHandle
    101 .text:00426B16                 mov     byte ptr [edi+2Eh], 0
    102 .text:00426B1A                 call    ds:__imp_@KeReleaseInStackQueuedSpinLock@4 ; KeReleaseInStackQueuedSpinLock(x)
    103 .text:00426B20                 lea     eax, [ebp+var_8]
    104 .text:00426B23                 push    eax
    105 .text:00426B24                 lea     eax, [ebp+var_C]
    106 .text:00426B27                 push    eax
    107 .text:00426B28                 lea     eax, [ebp+var_10]
    108 .text:00426B2B                 push    eax
    109 .text:00426B2C                 lea     eax, [ebp+var_4]
    110 .text:00426B2F                 push    eax
    111 .text:00426B30                 push    edi
    112 .text:00426B31                 call    [ebp+var_14]
    113 .text:00426B34                 cmp     [ebp+var_4], 0
    114 .text:00426B38                 jz      short loc_426B5D
    115 .text:00426B3A                 xor     cl, cl          ; NewIrql
    116 .text:00426B3C                 mov     byte ptr [esi+48h], 1
    117 .text:00426B40                 call    ds:__imp_@KfLowerIrql@4 ; KfLowerIrql(x)
    118 .text:00426B46                 push    [ebp+var_8]
    119 .text:00426B49                 push    [ebp+var_C]
    120 .text:00426B4C                 push    [ebp+var_10]
    121 .text:00426B4F                 call    [ebp+var_4]
    122 .text:00426B52                 mov     cl, 1           ; NewIrql
    123 .text:00426B54                 call    ds:__imp_@KfRaiseIrql@4 ; KfRaiseIrql(x)
    124 .text:00426B5A                 mov     [ebp+LockHandle.OldIrql], al
    125 .text:00426B5D
    126 .text:00426B5D loc_426B5D:                             ; CODE XREF: KiDeliverApc(x,x,x)+10A↑j
    127 .text:00426B5D                 lea     edx, [ebp+LockHandle] ; LockHandle
    128 .text:00426B60                 lea     ecx, [esi+0E8h] ; SpinLock
    129 .text:00426B66                 call    ds:__imp_@KeAcquireInStackQueuedSpinLock@8 ; KeAcquireInStackQueuedSpinLock(x,x)
    130 .text:00426B6C                 mov     byte ptr [esi+48h], 0
    131 .text:00426B70
    132 .text:00426B70 loc_426B70:                             ; CODE XREF: KiDeliverApc(x,x,x)+5C↑j
    133 .text:00426B70                                         ; KiDeliverApc(x,x,x)+C2↑j
    134 .text:00426B70                 cmp     [ebx], ebx      ; 判断第一个链表是否为空,如果内核与当前地址一样,说明没有内核APC函数。
    135 .text:00426B72                 jnz     loc_426A8F      ; 如果有内核APC,则跳转去执行内核APC,否则继续执行处理用户APC。
    136 .text:00426B78                 lea     ecx, [esi+3Ch]  ; 取第二个双向链表,第二个APC队列。
    137 .text:00426B7B                 mov     eax, [ecx]      ; 判断当前队列是否为空
    138 .text:00426B7D                 cmp     eax, ecx
    139 .text:00426B7F                 jz      loc_426C05      ; 如果不为空,则说明存在用户APC,则跳转去处理.
    140 .text:00426B85                 cmp     [ebp+arg_0], 1  ; 判断参数是0还是1,如果为1的时候才处理用户APC
    141 .text:00426B89                 jnz     short loc_426C05 ; 如果是用户APC,则去跳转执行。
    142 .text:00426B8B                 cmp     byte ptr [esi+4Ah], 0
    143 .text:00426B8F                 jz      short loc_426C05
    144 .text:00426B91                 mov     byte ptr [esi+4Ah], 0
    145 .text:00426B95                 lea     edi, [eax-0Ch]  ; 获取_KAPC的首地址,因为链表在偏移+0ch处
    146 .text:00426B98                 mov     ecx, [edi+_KAPC.NormalRoutine]
    147 .text:00426B9B                 mov     ebx, [edi+_KAPC.KernelRoutine]
    148 .text:00426B9E                 mov     [ebp+var_4], ecx
    149 .text:00426BA1                 mov     ecx, [edi+_KAPC.NormalContext]
    150 .text:00426BA4                 mov     [ebp+var_10], ecx
    151 .text:00426BA7                 mov     ecx, [edi+24h]
    152 .text:00426BAA                 mov     [ebp+var_C], ecx
    153 .text:00426BAD                 mov     ecx, [edi+28h]
    154 .text:00426BB0                 mov     [ebp+var_8], ecx
    155 .text:00426BB3                 mov     ecx, [eax]      ; 链表操作 将当前APC从用户队列中拆除,因为变量已经存储在局部变量中,方便存储。
    156 .text:00426BB5                 mov     eax, [eax+4]
    157 .text:00426BB8                 mov     [eax], ecx
    158 .text:00426BBA                 mov     [ecx+4], eax
    159 .text:00426BBD                 lea     ecx, [ebp+LockHandle] ; LockHandle
    160 .text:00426BC0                 mov     byte ptr [edi+2Eh], 0
    161 .text:00426BC4                 call    ds:__imp_@KeReleaseInStackQueuedSpinLock@4 ; KeReleaseInStackQueuedSpinLock(x)
    162 .text:00426BCA                 lea     eax, [ebp+var_8]
    163 .text:00426BCD                 push    eax
    164 .text:00426BCE                 lea     eax, [ebp+var_C]
    165 .text:00426BD1                 push    eax
    166 .text:00426BD2                 lea     eax, [ebp+var_10]
    167 .text:00426BD5                 push    eax
    168 .text:00426BD6                 lea     eax, [ebp+var_4]
    169 .text:00426BD9                 push    eax
    170 .text:00426BDA                 push    edi
    171 .text:00426BDB                 call    ebx             ; 调用_KAPC.KernelRoutine 释放APC函数
    172 .text:00426BDD                 cmp     [ebp+var_4], 0
    173 .text:00426BE1                 jnz     short loc_426BEC
    174 .text:00426BE3                 push    1
    175 .text:00426BE5                 call    _KeTestAlertThread@4 ; KeTestAlertThread(x)
    176 .text:00426BEA                 jmp     short loc_426C0E
    177 .text:00426BEC ; ---------------------------------------------------------------------------
    178 .text:00426BEC
    179 .text:00426BEC loc_426BEC:                             ; CODE XREF: KiDeliverApc(x,x,x)+1B3↑j
    180 .text:00426BEC                 push    [ebp+var_8]
    181 .text:00426BEF                 push    [ebp+var_C]
    182 .text:00426BF2                 push    [ebp+var_10]
    183 .text:00426BF5                 push    [ebp+var_4]
    184 .text:00426BF8                 push    [ebp+arg_8]
    185 .text:00426BFB                 push    [ebp+arg_4]
    186 .text:00426BFE                 call    _KiInitializeUserApc@24 ; 用户APC中调用APC用来初始化用户APC执行的环境
    187 .text:00426C03                 jmp     short loc_426C0E
    188 .text:00426C05 ; ---------------------------------------------------------------------------
    189 .text:00426C05
    190 .text:00426C05 loc_426C05:                             ; CODE XREF: KiDeliverApc(x,x,x)+C8↑j
    191 .text:00426C05                                         ; KiDeliverApc(x,x,x)+D5↑j ...
    192 .text:00426C05                 lea     ecx, [ebp+LockHandle] ; LockHandle
    193 .text:00426C08                 call    ds:__imp_@KeReleaseInStackQueuedSpinLock@4 ; KeReleaseInStackQueuedSpinLock(x)
    194 .text:00426C0E
    195 .text:00426C0E loc_426C0E:                             ; CODE XREF: KiDeliverApc(x,x,x)+1BC↑j
    196 .text:00426C0E                                         ; KiDeliverApc(x,x,x)+1D5↑j
    197 .text:00426C0E                 mov     ecx, [ebp+BugCheckParameter1]
    198 .text:00426C11                 cmp     [esi+44h], ecx
    199 .text:00426C14                 jz      short loc_426C30
    200 .text:00426C16                 mov     eax, large fs:994h
    201 .text:00426C1C                 push    eax             ; BugCheckParameter4
    202 .text:00426C1D                 movzx   eax, byte ptr [esi+165h]
    203 .text:00426C24                 push    eax             ; BugCheckParameter3
    204 .text:00426C25                 push    dword ptr [esi+44h] ; BugCheckParameter2
    205 .text:00426C28                 push    ecx             ; BugCheckParameter1
    206 .text:00426C29                 push    5               ; BugCheckCode
    207 .text:00426C2B                 call    _KeBugCheckEx@20 ; KeBugCheckEx(x,x,x,x,x)
    208 .text:00426C30 ; ---------------------------------------------------------------------------
    209 .text:00426C30
    210 .text:00426C30 loc_426C30:                             ; CODE XREF: KiDeliverApc(x,x,x)+1E6↑j
    211 .text:00426C30                 mov     eax, [ebp+var_1C]
    212 .text:00426C33                 pop     edi
    213 .text:00426C34                 mov     [esi+134h], eax
    214 .text:00426C3A                 pop     esi
    215 .text:00426C3B                 pop     ebx
    216 .text:00426C3C                 leave
    217 .text:00426C3D                 retn    0Ch
    218 .text:00426C3D _KiDeliverApc@12 endp

    3. KiDeliverApc(ntkrnlpa.exe)代码分析

      1 :0042A9FE ; =============== S U B R O U T I N E =======================================
      2 .text:0042A9FE
      3 .text:0042A9FE ; Attributes: bp-based frame
      4 .text:0042A9FE
      5 .text:0042A9FE ; __stdcall KiInitializeUserApc(x, x, x, x, x, x)
      6 .text:0042A9FE _KiInitializeUserApc@24 proc near       ; CODE XREF: KiDeliverApc(x,x,x)+1D0↑p
      7 .text:0042A9FE
      8 .text:0042A9FE var_34C         = dword ptr -34Ch
      9 .text:0042A9FE var_340         = dword ptr -340h
     10 .text:0042A9FE var_2FC         = dword ptr -2FCh
     11 .text:0042A9FE var_2F8         = dword ptr -2F8h
     12 .text:0042A9FE var_2F4         = dword ptr -2F4h
     13 .text:0042A9FE BugCheckParameter3= dword ptr -2F0h
     14 .text:0042A9FE var_2EC         = dword ptr -2ECh
     15 .text:0042A9FE var_2E8         = dword ptr -2E8h
     16 .text:0042A9FE var_228         = dword ptr -228h
     17 .text:0042A9FE var_224         = dword ptr -224h
     18 .text:0042A9FE var_1C          = dword ptr -1Ch
     19 .text:0042A9FE ms_exc          = CPPEH_RECORD ptr -18h
     20 .text:0042A9FE arg_0           = dword ptr  8
     21 .text:0042A9FE arg_4           = dword ptr  0Ch
     22 .text:0042A9FE arg_8           = dword ptr  10h
     23 .text:0042A9FE arg_C           = dword ptr  14h
     24 .text:0042A9FE arg_10          = dword ptr  18h
     25 .text:0042A9FE arg_14          = dword ptr  1Ch
     26 .text:0042A9FE
     27 .text:0042A9FE ; __unwind { // __SEH_prolog
     28 .text:0042A9FE                 push    33Ch
     29 .text:0042AA03                 push    offset stru_4020B0
     30 .text:0042AA08                 call    __SEH_prolog
     31 .text:0042AA0D                 mov     eax, ___security_cookie
     32 .text:0042AA12                 mov     [ebp+var_1C], eax
     33 .text:0042AA15                 mov     eax, [ebp+_KAPC.Thread]
     34 .text:0042AA18                 mov     [ebp+var_2F4], eax
     35 .text:0042AA1E                 mov     ebx, [ebp+arg_4]
     36 .text:0042AA21                 mov     [ebp+BugCheckParameter3], ebx
     37 .text:0042AA27                 test    byte ptr [ebx+72h], 2
     38 .text:0042AA2B                 jnz     loc_42AB7B
     39 .text:0042AA31                 mov     [ebp+var_2E8], 10017h
     40 .text:0042AA3B                 lea     ecx, [ebp+var_2E8]
     41 .text:0042AA41                 push    ecx             ; context对象的首地址
     42 .text:0042AA42                 push    eax
     43 .text:0042AA43                 push    ebx             ; trap_frame的地址
     44 .text:0042AA44                 call    _KeContextFromKframes@12 ; 因为要返回3环去处理,_TRAP_FRAME保存的EIP与ESP显然需要修改,因此这里就需要来进行备份处理。
     45 .text:0042AA49 ;   __try { // __except at loc_42AB4E
     46 .text:0042AA49                 and     [ebp+ms_exc.registration.TryLevel], 0
     47 .text:0042AA4D                 mov     eax, 2DCh       ; 一个CONTEXT 和 另外四个值的大小
     48 .text:0042AA52                 mov     [ebp+var_2F8], eax
     49 .text:0042AA58                 mov     esi, [ebp+var_224] ; ebp指向context堆栈 context -2e8
     50 .text:0042AA5E                 and     esi, 0FFFFFFFCh ; 1100 四字节对齐
     51 .text:0042AA61                 sub     esi, eax        ; z在0环直接修改三环的堆栈,将用户三环堆栈减少为0x2DC字节
     52 .text:0042AA63                 mov     [ebp+var_2EC], esi
     53 .text:0042AA69                 push    4               ; Alignment
     54 .text:0042AA6B                 push    eax             ; Length
     55 .text:0042AA6C                 push    esi             ; Address
     56 .text:0042AA6D                 call    _ProbeForWrite@12 ; 修改新增部分的内存属性
     57 .text:0042AA72                 lea     edi, [esi+10h]  ; 先让过前面4个成员
     58 .text:0042AA75                 mov     ecx, 0B3h       ; 0B3*4 + 10 = 2DC
     59 .text:0042AA7A                 lea     esi, [ebp+var_2E8]
     60 .text:0042AA80                 rep movsd               ; 复制context到用户栈
     61 .text:0042AA82                 mov     dword ptr [ebx+6Ch], 1Bh
     62 .text:0042AA89                 push    23h
     63 .text:0042AA8B                 pop     eax
     64 .text:0042AA8C                 mov     [ebx+78h], eax
     65 .text:0042AA8F                 mov     [ebx+38h], eax
     66 .text:0042AA92                 mov     [ebx+34h], eax
     67 .text:0042AA95                 mov     dword ptr [ebx+50h], 3Bh
     68 .text:0042AA9C                 and     dword ptr [ebx+30h], 0
     69 .text:0042AAA0                 mov     ecx, [ebp+var_228]
     70 .text:0042AAA6                 test    ecx, 20000h
     71 .text:0042AAAC                 jz      short loc_42AAC6
     72 .text:0042AAAE                 cmp     byte ptr _KeI386VdmIoplAllowed, 0
     73 .text:0042AAB5                 jz      short loc_42AAC6
     74 .text:0042AAB7                 mov     eax, _KeI386EFlagsAndMaskV86
     75 .text:0042AABC                 and     eax, ecx
     76 .text:0042AABE                 or      eax, _KeI386EFlagsOrMaskV86
     77 .text:0042AAC4                 jmp     short loc_42AAD4
     78 .text:0042AAC6 ; ---------------------------------------------------------------------------
     79 .text:0042AAC6
     80 .text:0042AAC6 loc_42AAC6:                             ; CODE XREF: KiInitializeUserApc(x,x,x,x,x,x)+AE↑j
     81 .text:0042AAC6                                         ; KiInitializeUserApc(x,x,x,x,x,x)+B7↑j
     82 .text:0042AAC6                 and     ecx, 3E0DD7h
     83 .text:0042AACC                 or      ecx, 200h
     84 .text:0042AAD2                 mov     eax, ecx
     85 .text:0042AAD4
     86 .text:0042AAD4 loc_42AAD4:                             ; CODE XREF: KiInitializeUserApc(x,x,x,x,x,x)+C6↑j
     87 .text:0042AAD4                 mov     [ebx+KTRAP_FRAME.EFlags], eax
     88 .text:0042AAD7                 mov     eax, large fs:292 ; 直接来进行修改fs寄存器
     89 .text:0042AADD                 mov     [ebp+var_2FC], eax
     90 .text:0042AAE3                 cmp     byte ptr [eax+KTRAP_FRAME.SegGs], 0
     91 .text:0042AAE7                 jz      short loc_42AAED
     92 .text:0042AAE9                 or      byte ptr [ebx+71h], 30h
     93 .text:0042AAED
     94 .text:0042AAED loc_42AAED:                             ; CODE XREF: KiInitializeUserApc(x,x,x,x,x,x)+E9↑j
     95 .text:0042AAED                 mov     eax, [ebp+var_2EC]
     96 .text:0042AAF3                 mov     [ebx+KTRAP_FRAME.HardwareEsp], eax
     97 .text:0042AAF6                 mov     ecx, _KeUserApcDispatcher
     98 .text:0042AAFC                 mov     [ebx+KTRAP_FRAME._Eip], ecx ; 将eip改为_KeUserApcDispatcher这个函数,这意味着跑回来,就执行这个函数。
     99 .text:0042AAFF                 and     [ebx+KTRAP_FRAME.ErrCode], 0
    100 .text:0042AB03                 mov     ecx, [ebp+arg_8]
    101 .text:0042AB06                 mov     [eax], ecx
    102 .text:0042AB08                 push    4
    103 .text:0042AB0A                 pop     ecx
    104 .text:0042AB0B                 add     eax, ecx
    105 .text:0042AB0D                 mov     [ebp+var_2EC], eax
    106 .text:0042AB13                 mov     edx, [ebp+arg_C]
    107 .text:0042AB16                 mov     [eax], edx
    108 .text:0042AB18                 add     eax, ecx
    109 .text:0042AB1A                 mov     [ebp+var_2EC], eax
    110 .text:0042AB20                 mov     edx, [ebp+arg_10]
    111 .text:0042AB23                 mov     [eax], edx
    112 .text:0042AB25                 add     eax, ecx
    113 .text:0042AB27                 mov     [ebp+var_2EC], eax
    114 .text:0042AB2D                 mov     edx, [ebp+arg_14]
    115 .text:0042AB30                 mov     [eax], edx
    116 .text:0042AB32                 add     eax, ecx
    117 .text:0042AB34                 mov     [ebp+var_2EC], eax
    118 .text:0042AB3A                 jmp     short loc_42AB77
    119 .text:0042AB3C ; ---------------------------------------------------------------------------
    120 .text:0042AB3C
    121 .text:0042AB3C loc_42AB3C:                             ; DATA XREF: .text:stru_4020B0↑o
    122 .text:0042AB3C ;   __except filter // owned by 42AA49
    123 .text:0042AB3C                 mov     eax, [ebp+ms_exc.exc_ptr]
    124 .text:0042AB3F                 push    dword ptr [eax]
    125 .text:0042AB41                 lea     eax, [ebp+var_34C]
    126 .text:0042AB47                 push    eax
    127 .text:0042AB48                 call    _KiCopyInformation@8 ; KiCopyInformation(x,x)
    128 .text:0042AB4D                 retn
    129 .text:0042AB4E ; ---------------------------------------------------------------------------
    130 .text:0042AB4E
    131 .text:0042AB4E loc_42AB4E:                             ; DATA XREF: .text:stru_4020B0↑o
    132 .text:0042AB4E ;   __except(loc_42AB3C) // owned by 42AA49
    133 .text:0042AB4E                 mov     esp, [ebp+ms_exc.old_esp]
    134 .text:0042AB51                 mov     eax, [ebp+BugCheckParameter3]
    135 .text:0042AB57                 mov     ecx, [eax+68h]
    136 .text:0042AB5A                 mov     [ebp+var_340], ecx
    137 .text:0042AB60                 push    1               ; char
    138 .text:0042AB62                 push    1               ; int
    139 .text:0042AB64                 push    eax             ; BugCheckParameter3
    140 .text:0042AB65                 push    [ebp+var_2F4]   ; int
    141 .text:0042AB6B                 lea     eax, [ebp+var_34C]
    142 .text:0042AB71                 push    eax             ; int
    143 .text:0042AB72                 call    _KiDispatchException@20 ; KiDispatchException(x,x,x,x,x)
    144 .text:0042AB72 ;   } // starts at 42AA49
    145 .text:0042AB77
    146 .text:0042AB77 loc_42AB77:                             ; CODE XREF: KiInitializeUserApc(x,x,x,x,x,x)+13C↑j
    147 .text:0042AB77                 or      [ebp+ms_exc.registration.TryLevel], 0FFFFFFFFh
    148 .text:0042AB7B
    149 .text:0042AB7B loc_42AB7B:                             ; CODE XREF: KiInitializeUserApc(x,x,x,x,x,x)+2D↑j
    150 .text:0042AB7B                 mov     ecx, [ebp+var_1C]
    151 .text:0042AB7E                 call    @xHalReferenceHandler@4 ; xHalReferenceHandler(x)
    152 .text:0042AB83                 call    __SEH_epilog
    153 .text:0042AB88                 retn    18h
    154 .text:0042AB88 ; } // starts at 42A9FE
    155 .text:0042AB88 _KiInitializeUserApc@24 endp

    4. KiUserApcDispatcher(ntdll.dll)分析

     1 ; __stdcall KiUserApcDispatcher(x, x, x, x, x)
     2 public _KiUserApcDispatcher@20
     3 _KiUserApcDispatcher@20 proc near
     4 arg_C= byte ptr  10h
     5 lea     edi, [esp+arg_C]
     6 pop     eax
     7 call    eax             ; NormalRoutine 执行用户APC的总入口
     8 push    1
     9 push    edi
    10 call    _ZwContinue@8   ; 返回到用户内核
    11 nop
    12 _KiUserApcDispatcher@20 endp ; sp-analysis failed
  • 相关阅读:
    mysql5.7 ERROR 1045 (28000): Access denied for user解决方法
    C++ json解决方案
    Gitblit无法查看单个文件解决方案
    git 拉取指定的远程分支(三种方式)
    全栈12
    git commit之后,想撤销commit
    video
    iframe
    git恢复之前版本的两种方法reset、revert
    Eclipse
  • 原文地址:https://www.cnblogs.com/onetrainee/p/11788097.html
Copyright © 2020-2023  润新知