APC(四)

KiDeliverApc 内核APC

从KiFastEntry进入内核
然后进入KiDeliverApc函数分发APC

.text:0043E262 loc_43E262:                             ; CODE XREF: _KiServiceExit+18↑j
.text:0043E262                 mov     byte ptr [ebx+3Ah], 0
.text:0043E266                 cmp     byte ptr [ebx+56h], 0
.text:0043E26A                 jz      short loc_43E2B4
.text:0043E26C                 mov     ebx, ebp        ; KTARP_TFRAME
.text:0043E26E                 mov     [ebx+44h], eax  ; 之前调用函数的返回值
.text:0043E271                 mov     dword ptr [ebx+50h], 3Bh ; ';'
.text:0043E278                 mov     dword ptr [ebx+38h], 23h ; '#'
.text:0043E27F                 mov     dword ptr [ebx+34h], 23h ; '#'
.text:0043E286                 mov     dword ptr [ebx+30h], 0
.text:0043E28D                 mov     ecx, 1          ; NewIrql
.text:0043E292                 call    ds:__imp_@KfRaiseIrql@4 ; IRQL提升为APC等级
.text:0043E298                 push    eax
.text:0043E299                 sti
.text:0043E29A                 push    ebx             ; TRAP_FRAME
.text:0043E29B                 push    0
.text:0043E29D                 push    1               ; mode
.text:0043E29F                 call    _KiDeliverApc@12 ; 派发APC
.text:0043E2A4                 pop     ecx             ; NewIrql
.text:0043E2A5                 call    ds:__imp_@KfLowerIrql@4 ; KfLowerIrql(x)
.text:0043E2AB                 mov     eax, [ebx+44h]
.text:0043E2AE                 cli
.text:0043E2AF                 jmp     short loc_43E24D

KTRAP_FRAME 保存R3的寄存器的值的结构

typedef struct _KTRAP_FRAME
{
     ULONG DbgEbp;
     ULONG DbgEip;
     ULONG DbgArgMark;
     ULONG DbgArgPointer;
     WORD TempSegCs;
     UCHAR Logging;
     UCHAR Reserved;
     ULONG TempEsp;
     ULONG Dr0;
     ULONG Dr1;
     ULONG Dr2;
     ULONG Dr3;
     ULONG Dr6;
     ULONG Dr7;
     ULONG SegGs;
     ULONG SegEs;
     ULONG SegDs;
     ULONG Edx;
     ULONG Ecx;
     ULONG Eax;
     ULONG PreviousPreviousMode;
     PEXCEPTION_REGISTRATION_RECORD ExceptionList;
     ULONG SegFs;
     ULONG Edi;
     ULONG Esi;
     ULONG Ebx;
     ULONG Ebp;
     ULONG ErrCode;
     ULONG Eip;
     ULONG SegCs;
     ULONG EFlags;
     ULONG HardwareEsp;
     ULONG HardwareSegSs;
     ULONG V86Es;
     ULONG V86Ds;
     ULONG V86Fs;
     ULONG V86Gs;
} KTRAP_FRAME, *PKTRAP_FRAME;

进入KiDeliverApc
首先保存环境 然后

.text:004B164F loc_4B164F:                             ; CODE XREF: KiDeliverApc(x,x,x)+13↑j
.text:004B164F                 mov     edi, large fs:124h ; CurrentThread 拿到线程
.text:004B1656                 cmp     word ptr [edi+86h], 0 ; 检测内核APC是否被关闭了
.text:004B165E                 mov     eax, [edi+128h] ; Kthread.TrapFrame
.text:004B1664                 mov     [esp+30h+var_4], eax ; 保存以前的
.text:004B1668                 mov     eax, [edi+50h]
.text:004B166B                 mov     [edi+128h], ecx ; 把新的保存到线程
.text:004B1671                 mov     [esp+30h+var_C], eax ; 保存进程
.text:004B1675                 mov     byte ptr [edi+55h], 0 ; ApcState.KernelApcPeading 置为0
.text:004B1679                 jnz     loc_4B18EB      ; 如果没关闭就返回
.text:004B167F                 xchg    eax, [esp+30h+var_8]
.text:004B1683                 mov     ebx, ds:__imp_@KfLowerIrql@4 ; 降级的函数
.text:004B1689                 jmp     loc_4B17C0
.text:004B17C0 loc_4B17C0:                             ; CODE XREF: KiDeliverApc(x,x,x)+54↑j
.text:004B17C0                                         ; KiDeliverApc(x,x,x)+111↑j
.text:004B17C0                 lea     eax, [edi+40h]  ; Thread.ApcState 拿到链表
.text:004B17C3                 cmp     [eax], eax      ; 判断内核APC队列是否有值
.text:004B17C5                 jnz     loc_4B168E
.text:004B168E loc_4B168E:                             ; CODE XREF: KiDeliverApc(x,x,x)+190↓j
.text:004B168E                 call    ds:__imp__KeRaiseIrqlToDpcLevel@0 ; 提升至DPC等级
.text:004B1694
.text:004B1694 ; public: static void __cdecl SMKM_STORE<struct SM_TRAITS>::SmStReadThread(void *)
.text:004B1694 ?SmStReadThread@?$SMKM_STORE@USM_TRAITS@@@@SAXPEAX@Z:
.text:004B1694                 and     [esp+30h+var_10], 0
.text:004B1699                 mov     [esp+30h+NewIrql], al
.text:004B169D                 lea     esi, [edi+60h]
.text:004B16A0                 jmp     short loc_4B16CB
.text:004B16CB loc_4B16CB:                             ; CODE XREF: KiDeliverApc(x,x,x)+6B↑j
.text:004B16CB                 xor     eax, eax
.text:004B16CD                 mov     ecx, esi
.text:004B16CF                 inc     eax
.text:004B16D0                 xchg    eax, [ecx]      ; 加锁
.text:004B16D2                 test    eax, eax
.text:004B16D4                 jnz     short loc_4B16A2
.text:004B16D6                 lea     ecx, [edi+40h]  ; APCSTATE
.text:004B16D9                 mov     eax, [ecx]
.text:004B16DB                 cmp     eax, ecx        ; 判断内核队列是否为空
.text:004B16DD                 jz      loc_4B17FE
.text:004B16E3                 mov     byte ptr [edi+55h], 0
.text:004B16E7                 lea     esi, [eax-0Ch]  ; 获取APC对象
.text:004B16EA                 mov     ecx, [esi+14h]
.text:004B16ED                 mov     [esp+30h+var_10], ecx
.text:004B16F1                 mov     ecx, [esi+1Ch]
.text:004B16F4                 mov     [esp+30h+var_20], ecx
.text:004B16F8                 mov     edx, [esi+20h]
.text:004B16FB                 mov     [esp+30h+var_14], edx
.text:004B16FF                 mov     edx, [esi+24h]
.text:004B1702                 mov     [esp+30h+var_18], edx
.text:004B1706                 mov     edx, [esi+28h]
.text:004B1709                 mov     [esp+30h+var_1C], edx ; 全拿出来
.text:004B170D                 test    ecx, ecx        ; NormalRoutine 为空就是特殊APC
.text:004B170F                 jnz     short loc_4B1748 ; 如果不是特殊
.text:004B1711                 mov     ecx, [eax]      ; 头部摘掉APC
.text:004B1713                 mov     eax, [eax+4]
.text:004B1716                 mov     [eax], ecx
.text:004B1718                 mov     [ecx+4], eax
.text:004B171B                 mov     byte ptr [esi+2Eh], 0
.text:004B171F                 xor     ecx, ecx        ; 释放队列锁
.text:004B1721                 lea     eax, [edi+60h]
.text:004B1724                 lock and [eax], ecx
.text:004B1727                 mov     cl, [esp+30h+NewIrql] ; NewIrql
.text:004B172B                 call    ebx ; KfLowerIrql(x) ; 等级又降下去了
.text:004B172D                 lea     eax, [esp+30h+var_1C]
.text:004B1731                 push    eax
.text:004B1732                 lea     eax, [esp+34h+var_18]
.text:004B1736                 push    eax
.text:004B1737                 lea     eax, [esp+38h+var_14]
.text:004B173B                 push    eax
.text:004B173C                 lea     eax, [esp+3Ch+var_20]
.text:004B1740                 push    eax
.text:004B1741                 push    esi ;放入
.text:004B1742                 call    [esp+44h+var_10] ; call kernelroutine
.text:004B1746                 jmp     short loc_4B17C0

如果不是特殊APC

.text:004B1748 loc_4B1748:                             ; CODE XREF: KiDeliverApc(x,x,x)+DA↑j
.text:004B1748                 cmp     byte ptr [edi+54h], 0 ; 判断kernelAPC在不在执行中
.text:004B174C                 jnz     loc_4B180B
.text:004B1752                 cmp     word ptr [edi+84h], 0 ; APC有没有关闭
.text:004B175A                 jnz     loc_4B180B
.text:004B1760                 mov     ecx, [eax]
.text:004B1762                 mov     eax, [eax+4]
.text:004B1765                 mov     [eax], ecx
.text:004B1767                 mov     [ecx+4], eax    ; 移除APC节点
.text:004B176A                 mov     byte ptr [esi+2Eh], 0
.text:004B176E                 xor     ecx, ecx
.text:004B1770                 lea     eax, [edi+60h]  ; Kthread.ApcQueueLock  解除锁
.text:004B1773                 lock and [eax], ecx
.text:004B1776                 mov     cl, [esp+30h+NewIrql] ; NewIrql
.text:004B177A                 call    ebx ; KfLowerIrql(x) ; KfLowerIrql(x)
.text:004B177C                 lea     eax, [esp+30h+var_1C]
.text:004B1780                 push    eax
.text:004B1781                 lea     eax, [esp+34h+var_18]
.text:004B1785                 push    eax
.text:004B1786                 lea     eax, [esp+38h+var_14]
.text:004B178A                 push    eax
.text:004B178B                 lea     eax, [esp+3Ch+var_20]
.text:004B178F                 push    eax
.text:004B1790                 push    esi
.text:004B1791                 call    [esp+44h+var_10]
.text:004B1795                 cmp     [esp+30h+var_20], 0
.text:004B179A                 jz      short loc_4B17BC
.text:004B179C                 xor     cl, cl          ; NewIrql
.text:004B179E                 mov     byte ptr [edi+54h], 1
.text:004B17A2                 call    ebx ; KfLowerIrql(x) ; KfLowerIrql(x)
.text:004B17A4                 push    [esp+30h+var_1C]
.text:004B17A8                 push    [esp+34h+var_18]
.text:004B17AC                 push    [esp+38h+var_14]
.text:004B17B0                 call    [esp+3Ch+var_20]
.text:004B17B4                 mov     cl, 1           ; NewIrql
.text:004B17B6                 call    ds:__imp_@KfRaiseIrql@4 ; KfRaiseIrql(x)

继续拿链表判断下一个还有没有值

.text:004B17C0 loc_4B17C0:                             ; CODE XREF: KiDeliverApc(x,x,x)+54↑j
.text:004B17C0                                         ; KiDeliverApc(x,x,x)+111↑j
.text:004B17C0                 lea     eax, [edi+40h]  ; Thread.ApcState n拿到链表
.text:004B17C3                 cmp     [eax], eax      ; 判断内核APC队列是否有值
.text:004B17C5                 jnz     loc_4B168E

然后执行用户APC

.text:004B17CB loc_4B17CB:                             ; CODE XREF: KiDeliverApc(x,x,x)+1D4↓j
.text:004B17CB                 cmp     [ebp+arg_0], 1  ; 如果是用户模式就执行用户APC
.text:004B17CF                 jnz     loc_4B18EB
.text:004B17D5                 lea     eax, [edi+48h]
.text:004B17D8                 cmp     [eax], eax
.text:004B17DA                 jz      loc_4B18EB ; 没有就退出
.text:004B17E0                 cmp     byte ptr [edi+56h], 0
.text:004B17E4                 jz      loc_4B18EB
.text:004B17EA                 call    ds:__imp__KeRaiseIrqlToDpcLevel@0 ; KeRaiseIrqlToDpcLevel()
.text:004B17F0                 and     [esp+30h+var_10], 0
.text:004B17F5                 mov     [esp+30h+NewIrql], al
.text:004B17F9                 lea     esi, [edi+60h]
.text:004B17FC                 jmp     short loc_4B1847
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值