ExpTimerApcRoutine函数分析之作用是ActiveTimerListHead里面移除定时器_etimer

devtools/2025/4/1 0:19:03/


第一部分:
VOID
ExpTimerApcRoutine (
    IN PKAPC Apc,
    IN PKNORMAL_ROUTINE *NormalRoutine,
    IN PVOID *NormalContext,
    IN PVOID *SystemArgument1,
    IN PVOID *SystemArgument2
    )

/*++

Routine Description:

    This function is the special APC routine that is called to remove
    a timer from the current thread's active timer list.

Arguments:

    Apc - Supplies a pointer to the APC object used to invoke this routine.

    NormalRoutine - Supplies a pointer to a pointer to the normal routine
        function that was specified when the APC was initialized.

    NormalContext - Supplies a pointer to a pointer to an arbitrary data
        structure that was specified when the APC was initialized.

    SystemArgument1, SystemArgument2 - Supplies a set of two pointers to
        two arguments that contain untyped data.

Return Value:

    None.

--*/

{

    PETHREAD ExThread;
    PETIMER ExTimer;
    KIRQL OldIrql1;
    ULONG DerefCount;

    UNREFERENCED_PARAMETER (NormalContext);
    UNREFERENCED_PARAMETER (SystemArgument1);
    UNREFERENCED_PARAMETER (SystemArgument2);

    //
    // Get address of executive timer object and the current thread object.
    //

    ExThread = PsGetCurrentThread();
    ExTimer = CONTAINING_RECORD(Apc, ETIMER, TimerApc);

    //
    // If the timer is still in the current thread's active timer list, then
    // remove it if it is not a periodic timer and set APC associated FALSE.
    // It is possible for the timer not to be in the current thread's active
    // timer list since the APC could have been delivered, and then another
    // thread could have set the timer again with another APC. This would
    // have caused the timer to be removed from the current thread's active
    // timer list.
    //
    // N. B. The spin locks for the timer and the active timer list must be
    //  acquired in the order: 1) timer lock, 2) thread list lock.
    //

    DerefCount = 1;
    ExAcquireSpinLock(&ExTimer->Lock, &OldIrql1);
    ExAcquireSpinLockAtDpcLevel(&ExThread->ActiveTimerListLock);
    if ((ExTimer->ApcAssociated) && (&ExThread->Tcb == ExTimer->TimerApc.Thread)) {
        if (ExTimer->Period == 0) {
            RemoveEntryList(&ExTimer->ActiveTimerListEntry);
            ExTimer->ApcAssociated = FALSE;
            DerefCount++;
        }

    } else {
        *NormalRoutine = (PKNORMAL_ROUTINE)NULL;
    }

    ExReleaseSpinLockFromDpcLevel(&ExThread->ActiveTimerListLock);
    ExReleaseSpinLock(&ExTimer->Lock, OldIrql1);

    ObDereferenceObjectEx(ExTimer, DerefCount);

    return;
}


1: kd> dv
            Apc = 0x893b13b0
  NormalRoutine = 0xba30ed48
  NormalContext = 0xba30ed3c
SystemArgument1 = 0xba30ed40
SystemArgument2 = 0xba30ed44
       OldIrql1 = 0x89 ''
     DerefCount = 0x3d


1: kd> dt kapc 893b13b0
CSRSRV!KAPC
   +0x000 Type             : 0n18
   +0x002 Size             : 0n48
   +0x004 Spare0           : 0x220
   +0x008 Thread           : 0x896d9da0 _KTHREAD
   +0x00c ApcListEntry     : _LIST_ENTRY [ 0x896d9ddc - 0x896d9ddc ]
   +0x014 KernelRoutine    : 0x80af2e9a     void  nt!ExpTimerApcRoutine+0
   +0x018 RundownRoutine   : (null)
   +0x01c NormalRoutine    : 0x7340a79a     void  +7340a79a
   +0x020 NormalContext    : (null)
   +0x024 SystemArgument1  : 0x3218d5d4 Void
   +0x028 SystemArgument2  : 0x01db94bc Void
   +0x02c ApcStateIndex    : 0 ''
   +0x02d ApcMode          : 1 ''
   +0x02e Inserted         : 0x1 ''


    ExTimer = CONTAINING_RECORD(Apc, ETIMER, TimerApc);


//
// Executive timer object structure definition.
//

typedef struct _ETIMER {
    KTIMER KeTimer;
    KAPC TimerApc;
    KDPC TimerDpc;
    LIST_ENTRY ActiveTimerListEntry;
    KSPIN_LOCK Lock;
    LONG Period;
    BOOLEAN ApcAssociated;
    BOOLEAN WakeTimer;
    LIST_ENTRY WakeTimerListEntry;
} ETIMER, *PETIMER;

1: kd> dt _etimer 893b13b0-28
nt!_ETIMER
   +0x000 KeTimer          : _KTIMER
   +0x028 TimerApc         : _KAPC
   +0x058 TimerDpc         : _KDPC
   +0x078 ActiveTimerListEntry : _LIST_ENTRY [ 0x896d9f8c - 0x896d9f8c ]
   +0x080 Lock             : 0
   +0x084 Period           : 0n0
   +0x088 ApcAssociated    : 0x1 ''
   +0x089 WakeTimer        : 0 ''
   +0x08c WakeTimerListEntry : _LIST_ENTRY [ 0x0 - 0x5000000 ]
1: kd> dx -id 0,0,89601250 -r1 (*((ntkrnlmp!_KAPC *)0x893b13b0))
(*((ntkrnlmp!_KAPC *)0x893b13b0))                 [Type: _KAPC]
    [+0x000] Type             : 18 [Type: short]
    [+0x002] Size             : 48 [Type: short]
    [+0x004] Spare0           : 0x220 [Type: unsigned long]
    [+0x008] Thread           : 0x896d9da0 [Type: _KTHREAD *]
    [+0x00c] ApcListEntry     [Type: _LIST_ENTRY]
    [+0x014] KernelRoutine    : 0x80af2e9a [Type: void (*)(_KAPC *,void (**)(void *,void *,void *),void * *,void * *,void * *)]
    [+0x018] RundownRoutine   : 0x0 [Type: void (*)(_KAPC *)]
    [+0x01c] NormalRoutine    : 0x7340a79a [Type: void (*)(void *,void *,void *)]
    [+0x020] NormalContext    : 0x0 [Type: void *]
    [+0x024] SystemArgument1  : 0x3218d5d4 [Type: void *]
    [+0x028] SystemArgument2  : 0x1db94bc [Type: void *]
    [+0x02c] ApcStateIndex    : 0 [Type: char]
    [+0x02d] ApcMode          : 1 [Type: char]
    [+0x02e] Inserted         : 0x0 [Type: unsigned char]
1: kd> dx -id 0,0,89601250 -r1 (*((ntkrnlmp!_LIST_ENTRY *)0x893b1400))
(*((ntkrnlmp!_LIST_ENTRY *)0x893b1400))                 [Type: _LIST_ENTRY]
    [+0x000] Flink            : 0x896d9f8c [Type: _LIST_ENTRY *]
    [+0x004] Blink            : 0x896d9f8c [Type: _LIST_ENTRY *]

0x896d9f8c-0x896d9da0=0x1ec


第二部分:    ExAcquireSpinLockAtDpcLevel(&ExThread->ActiveTimerListLock);之后

ExAcquireSpinLockAtDpcLevel(&ExThread->ActiveTimerListLock);之前
1: kd> dt eTHREAD 896d9da0
ntdll!ETHREAD
   +0x000 Tcb              : _KTHREAD
   +0x1c8 CreateTime       : _LARGE_INTEGER 0x0edca5e1`45f8e6e0
   +0x1c8 NestedFaultCount : 0y00
   +0x1c8 ApcNeeded        : 0y0
   +0x1d0 ExitTime         : _LARGE_INTEGER 0x896d9f70`896d9f70
   +0x1d0 LpcReplyChain    : _LIST_ENTRY [ 0x896d9f70 - 0x896d9f70 ]
   +0x1d0 KeyedWaitChain   : _LIST_ENTRY [ 0x896d9f70 - 0x896d9f70 ]
   +0x1d8 ExitStatus       : 0n0
   +0x1d8 OfsChain         : (null)
   +0x1dc PostBlockList    : _LIST_ENTRY [ 0x896d9f7c - 0x896d9f7c ]
   +0x1e4 TerminationPort  : 0xe15ae778 _TERMINATION_PORT
   +0x1e4 ReaperLink       : 0xe15ae778 _ETHREAD
   +0x1e4 KeyedWaitValue   : 0xe15ae778 Void
   +0x1e8 ActiveTimerListLock : 0
   +0x1ec ActiveTimerListHead : _LIST_ENTRY [ 0x893b1400 - 0x893b1400 ]

ExAcquireSpinLockAtDpcLevel(&ExThread->ActiveTimerListLock);之后

1: kd> dt eTHREAD 896d9da0
ntdll!ETHREAD
   +0x000 Tcb              : _KTHREAD
 
   +0x1e8 ActiveTimerListLock : 0x896d9da1

第三部分:RemoveEntryList(&ExTimer->ActiveTimerListEntry);之后


RemoveEntryList(&ExTimer->ActiveTimerListEntry);之前

1: kd> dt eTHREAD 896d9da0
ntdll!ETHREAD
   +0x000 Tcb              : _KTHREAD
   +0x1c8 CreateTime       : _LARGE_INTEGER 0x0edca5e1`45f8e6e0
   +0x1c8 NestedFaultCount : 0y00
   +0x1c8 ApcNeeded        : 0y0
   +0x1d0 ExitTime         : _LARGE_INTEGER 0x896d9f70`896d9f70
   +0x1d0 LpcReplyChain    : _LIST_ENTRY [ 0x896d9f70 - 0x896d9f70 ]
   +0x1d0 KeyedWaitChain   : _LIST_ENTRY [ 0x896d9f70 - 0x896d9f70 ]
   +0x1d8 ExitStatus       : 0n0
   +0x1d8 OfsChain         : (null)
   +0x1dc PostBlockList    : _LIST_ENTRY [ 0x896d9f7c - 0x896d9f7c ]
   +0x1e4 TerminationPort  : 0xe15ae778 _TERMINATION_PORT
   +0x1e4 ReaperLink       : 0xe15ae778 _ETHREAD
   +0x1e4 KeyedWaitValue   : 0xe15ae778 Void
   +0x1e8 ActiveTimerListLock : 0
   +0x1ec ActiveTimerListHead : _LIST_ENTRY [ 0x893b1400 - 0x893b1400 ]

1: kd> dx -id 0,0,89601250 -r1 (*((ntkrnlmp!_LIST_ENTRY *)0x893b1400))
(*((ntkrnlmp!_LIST_ENTRY *)0x893b1400))                 [Type: _LIST_ENTRY]
    [+0x000] Flink            : 0x896d9f8c [Type: _LIST_ENTRY *]
    [+0x004] Blink            : 0x896d9f8c [Type: _LIST_ENTRY *]


RemoveEntryList(&ExTimer->ActiveTimerListEntry);之后

1: kd> dt eTHREAD 896d9da0
ntdll!ETHREAD
   +0x000 Tcb              : _KTHREAD

   +0x1e8 ActiveTimerListLock : 0x896d9da1
   +0x1ec ActiveTimerListHead : _LIST_ENTRY [ 0x896d9f8c - 0x896d9f8c ]


1: kd> dx -id 0,0,89601250 -r1 (*((ntdll!_LIST_ENTRY *)0x896d9f8c))
(*((ntdll!_LIST_ENTRY *)0x896d9f8c))                 [Type: _LIST_ENTRY]
    [+0x000] Flink            : 0x896d9f8c [Type: _LIST_ENTRY *]
    [+0x004] Blink            : 0x896d9f8c [Type: _LIST_ENTRY *]

第四部分:    ExReleaseSpinLockFromDpcLevel(&ExThread->ActiveTimerListLock);之后
1: kd> dt eTHREAD 896d9da0
ntdll!ETHREAD
   +0x000 Tcb              : _KTHREAD

   +0x1e8 ActiveTimerListLock : 0

第五部分:      ExReleaseSpinLock(&ExTimer->Lock, OldIrql1);之后
1: kd> dt _etimer 893b13b0-28
nt!_ETIMER
   +0x000 KeTimer          : _KTIMER
   +0x028 TimerApc         : _KAPC
   +0x058 TimerDpc         : _KDPC
   +0x078 ActiveTimerListEntry : _LIST_ENTRY [ 0x896d9f8c - 0x896d9f8c ]
   +0x080 Lock             : 0x896d9da1
   +0x084 Period           : 0n0
   +0x088 ApcAssociated    : 0 ''
   +0x089 WakeTimer        : 0 ''
   +0x08c WakeTimerListEntry : _LIST_ENTRY [ 0x0 - 0x5000000 ]

    ExReleaseSpinLock(&ExTimer->Lock, OldIrql1);之后

1: kd> dt _etimer 893b13b0-28
nt!_ETIMER
   +0x000 KeTimer          : _KTIMER
   +0x028 TimerApc         : _KAPC
   +0x058 TimerDpc         : _KDPC
   +0x078 ActiveTimerListEntry : _LIST_ENTRY [ 0x896d9f8c - 0x896d9f8c ]
   +0x080 Lock             : 0
   +0x084 Period           : 0n0
   +0x088 ApcAssociated    : 0 ''
   +0x089 WakeTimer        : 0 ''
   +0x08c WakeTimerListEntry : _LIST_ENTRY [ 0x0 - 0x5000000 ]


http://www.ppmy.cn/devtools/172230.html

相关文章

如何在WordPress中限制用户登录到一台设备

在当今的互联网环境下,许多用户习惯共享账户信息,虽然看似无害,却可能对网站运营产生负面影响。尤其是对于那些经营会员网站和在线课程的平台,限制用户同时登录的设备数量显得尤为重要。本文将详细探讨如何在WordPress中限制用户登…

【NLP 50、损失函数 KL散度】

目录 一、定义与公式 1.核心定义 2.数学公式 3.KL散度与交叉熵的关系 二、使用场景 1.生成模型与变分推断 2.知识蒸馏 3.模型评估与优化 4.信息论与编码优化 三、原理与特性 1.信息论视角 ​2.优化目标 3.​局限性 四、代码示例 代码运行流程 核心代码解析 抵达梦想靠的不是狂热…

蓝桥杯嵌入式赛道复习笔记8(eeprom读写)

原理学习 自己看一下江科大的存储器的读取,原理是一样的。只是使用了IIC原理是不变的 代码 cubeMX的配置 代码 eeprom层代码的书写 #include "eeprom_display.h" uint8_t data; uint8_t eeprom_read(uint8_t addr){I2CStart();I2CSendByte(0xa0);I2…

如何在 Postman 中传递请求参数?Query、Path 和 Body 详解

在 Postman 中如何有效地传递请求参数,以便更轻松地进行 API 测试和开发。在 Postman 中传递查询参数(Query)、路径参数(Path)和请求体参数(Body)。 在 Postman 中传递请求参数(Que…

2024年3月全国计算机等级考试真题(二级C语言)

😀 第1题 下列叙述中正确的是 A. 矩阵是非线性结构 B. 数组是长度固定的线性表 C. 对线性表只能作插入与删除运算 D. 线性表中各元素的数据类型可以不同 题目解析: A. 矩阵是非线性结构 错误。矩阵通常是二维数组,属…

【商城实战(93)】商城高并发实战:分布式锁与事务处理深度剖析

【商城实战】专栏重磅来袭!这是一份专为开发者与电商从业者打造的超详细指南。从项目基础搭建,运用 uniapp、Element Plus、SpringBoot 搭建商城框架,到用户、商品、订单等核心模块开发,再到性能优化、安全加固、多端适配&#xf…

2025年渗透测试面试题总结-某快手-安全工程师(题目+回答)

网络安全领域各种资源,学习文档,以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具,欢迎关注。 目录 快手-安全工程师 一、SQL注入漏洞类型及利用技术扩展 1. SQL注入漏洞分类 2. SQL注入写入Web Shell的…

数据库基础之DDLDML

目录 一.SQL分类 二.DDL 2.1 数据库操作 2.2 表操作 2.2.1 表操作-数据类型(基于MYSQL) 2.2.2 表操作-修改 2.2.3 表操作-删除 三.DML 3.1 添加数据 3.2 修改数据 3.3 删除数据 一.SQL分类 分类全称说明DDLData Definition Language 数据定义语言,用来定…