Windows APC注入解析

1. 前言

常用的用户态注入通常使用CreateRemoteThread通过在目标进程中创建新线程的方式来远程执行注入代码。但是,相比APC注入直接利用现有线程上下文执行,传统方式存在明显的线程/句柄/权限操作,非常容易被检测。

2. 简介

  • 基本概念

APC(Asynchronous Procedure Call - 异步过程调用)是一种在目标线程"合适时机"异步安排并执行函数的机制。它允许一个线程把一个函数排队到另一个线程上,当那个线程进入可执行 APC的状态时,内核会在适当时机通过KiDeliverApc调度APC。

  • 分类

按照执行上下文而言,分为用户APC(User-mode APC)和内核APC(Kernel APC)两类,也可以继续细分为普通和特殊APC。

其中,内核例程在APC_LEVEL执行,如果存在正常例程,则在PASSIVE_LEVEL执行。

类型 模式 普通例程 内核例程 位置 说明
普通 用户 队列尾部 可警告状态下执行单个APC
特殊 用户 队列头部 win10新增特性,全部顺序执行
普通 内核 队列尾部 全部顺序执行
特殊 内核 --- 队列头部 全部顺序执行

3. 初始化

内核中通过未导出函数KeInitializeApc初始化APC,具体定义如下。

cpp 复制代码
typedef enum _KAPC_ENVIRONMENT {
    OriginalApcEnvironment, // 原始线程
    AttachedApcEnvironment, // 附加线程
    CurrentApcEnvironment,  // 当前线程
    InsertApcEnvironment    // 
} KAPC_ENVIRONMENT;

NTKERNELAPI VOID NTAPI KeInitializeApc(
    _Out_ PRKAPC Apc,                             // APC上下文
    _In_ PETHREAD Thread,                         // 目标线程
    _In_ KAPC_ENVIRONMENT Environment,
    _In_ PKKERNEL_ROUTINE KernelRoutine,          // 通常用于APC正常执行时回收系统资源
    _In_opt_ PKRUNDOWN_ROUTINE RundownRoutine,    // 用于目标线程终止正常内核例程无法执行时回收系统资源
    _In_opt_ PKNORMAL_ROUTINE NormalRoutine,      // 等待执行的APC例程
    _In_opt_ KPROCESSOR_MODE ApcMode,
    _In_opt_ PVOID NormalContext);                // 传递APC例程的第一个参数

从上图代码中可以看出,KeInitializeApc只是简单通过传参初始化APC结构,没有什么复杂业务。

其中相对重要的一个参数就是Environment,它会在插入APC队列时和线程APC状态一起决定要插入的APC队列。

4. 排队

KeInsertQueueApc的主要通过调用KiInsertQueueApcKiSignalThreadForApcKiExitDispatcher三个函数来实现具体的业务功能。

cpp 复制代码
NTKERNELAPI BOOLEAN NTAPI KeInsertQueueApc(
    PRKAPC Apc,
    PVOID SystemArgument1,   // 传递APC例程的第二个参数
    PVOID SystemArgument2,   // 传递APC例程的第三个参数
    KPRIORITY Increment);

通过KiInsertQueueApc实现APC的插入的同时,同时调用KiSignalThreadForApcKiExitDispatcher来更新线程状态和执行特定的APC。

  • KiInsertQueueApc根据线程和APC的状态决定最终插入的APC队列的位置。

    其中Thread->ApcStateIndex 代表线程是否附加到其它线程,SavedApcState用于备份线程的原始APC,ApcState指向当前活跃的APC。从上图可以看到,

  • Apc->ApcStateIndex = 0 && Thread->ApcStateIndex = 1时,将APC插入目标线程的SavedApcState

  • Apc->ApcStateIndex = 0 && Thread->ApcStateIndex = 0时,将APC插入目标线程的ApcState

  • Apc->ApcStateIndex != 0 时,也将APC插入目标线程的ApcState队列中

  • KiSignalThreadForApc函数根据当前线程、APC信息决定是否更新线程状态,优先执行某些内核APC。


  • KiExitDispatcher函数通过调用KiDeliverApc执行内核APC。

5. 执行

内部函数KiDeliverApc负责实际投递和执行 APC。它是 APC 机制的核心调度器。

c 复制代码
VOID KiDeliverApc (
    IN KPROCESSOR_MODE PreviousMode,
    IN PKEXCEPTION_FRAME ExceptionFrame,
    IN PKTRAP_FRAME TrapFrame
    )
  1. 在启用特殊内核APC的情况下,执行所有的内核APC

  2. 第一步的前提下执行普通内核APC,直到普通内核APC被禁用,或者APC正在执行

  1. 第一步的前提下无条件执行所有的特殊内核APC

  2. 执行用户模式APC时遍历APC队列,直到满足条件

  3. 从队列中移除APC,同时将SpecialUserApcPending复位

  4. 执行用户APC内核例程

  5. 通过KiInitializeUserApc修改KTRAP_FRAME获取用户APC执行时机

KiInitializeUserApc函数入口主要包含KiInitiateUserApcKiContinueEx

前者往往从系统调用或者APC中断来执行,而后者则一般用于执行普通APC。

两者的区别在于从KiContinueEx进入时会复用上一次执行APC时的地址,避免反复备份KTRAP_FRAME


  1. KeUserApcDispatcher直接执行APC,或者通过wow64转发,最后调用ZwContinueEx回到内核
  1. KiContinueEx通过flag参数决定是否执行下一个用户APC,或者执行原始的用户线程

通过以上9个步骤,我们可以得出以下结论:

  • 内核APC一次调用全部执行

系统调用/中断 KiDeliverApc

  • 用户特殊APC一次调用执行一个?(此处存疑)

系统调用/中断 KiDeliverApc KiInitializeUserApc KeUserApcDispatcher KiContinueEx 原始线程

  • 用户普通APC唤醒状态一次调用全部执行

Y Y 系统调用/中断 KiDeliverApc UserApcPending KiInitializeUserApc KeUserApcDispatcher KiContinueEx 是否存在用户APC 原始线程

6. 问题

  • 问题1:插入用户APC后可能无法执行

当插入APC的线程处于不可Alertable状态时,APC会一直排队,直到状态变化。用户态可使用SleepExWaitForSingleObjectEx等函数,内核态则推荐KeDelayExecutionThread或者KeTestAlertThread

  • 问题2:使用驱动插入APC,若停止驱动时APC正在执行,则可能会导致BSOD。

当用户自定义的KernelRoutine正在执行时,驱动停止会导致函数不可用,从而引发BSOD。可以通过在KAPC中持有EX_RUNDOWN_REF来保证EX_RUNDOWN_REF完全释放前驱动程序不可卸载。

7.apc_injector

一个简易的内核注入测试工程

相关推荐
AI袋鼠帝9 小时前
Claude4.5+Gemini3 接管电脑桌面,这回是真无敌了..
人工智能·windows·aigc
獨枭10 小时前
Windows 下安装与使用 Miniconda 完整指南
windows
命里有定数11 小时前
保姆级教程:在 Windows (WSL2) 下本地部署 Qwen3-ASR
windows
lucky670714 小时前
Windows 上彻底卸载 Node.js
windows·node.js
编程小白202615 小时前
从 C++ 基础到效率翻倍:Qt 开发环境搭建与Windows 神级快捷键指南
开发语言·c++·windows·qt·学习
凯子坚持 c16 小时前
CANN 性能剖析实战:从原始事件到交互式火焰图
windows·microsoft
开开心心就好17 小时前
发票合并打印工具,多页布局设置实时预览
linux·运维·服务器·windows·pdf·harmonyos·1024程序员节
獨枭17 小时前
PyCharm 跑通 SAM 全流程实战
windows
仙剑魔尊重楼18 小时前
音乐制作电子软件FL Studio2025.2.4.5242中文版新功能介绍
windows·音频·录屏·音乐·fl studio
PHP小志18 小时前
Windows 服务器怎么修改密码和用户名?账户被系统锁定如何解锁
windows