C++ 怎么使用 APC(异步过程调用)注入将代码排队注入到目标系统线程中

胖雪姑娘_5758

胖雪姑娘_5758

2026-11-03

662人浏览

原创

APC注入的核心限制是目标线程必须处于可唤醒的等待状态;QueueUserAPC仅对WaitSleepJoin或Alertable状态线程生效,需调用SleepEx、MsgWaitForMultipleObjectsEx等可警报函数,否则回调永不执行。

c++ 怎么使用 apc(异步过程调用)注入将代码排队注入到目标系统线程中

APC 注入的核心限制:目标线程必须处于可唤醒的等待状态

Windows APC(Asynchronous Procedure Call)注入不能“强行”插入任意线程——QueueUserAPC 只对处于 WaitSleepJoin、Alertable 状态的线程生效。这意味着目标线程必须主动调用如 WaitForSingleObjectEx、SleepEx、MsgWaitForMultipleObjectsEx(且传入 bAlertable = TRUE)等可警报等待函数,否则 APC 永远不会被执行。

常见误判是以为只要线程活着就能注入,结果 QueueUserAPC 返回成功(非零值),但回调从未触发——本质是目标线程根本没进入 alertable wait。

  • 检查目标线程是否真的在 alertable 等待:可用 GetThreadContext 查看 EIP/RIP 是否落在 ntdll!NtDelayExecution 或类似系统调用内;或用 Process Hacker / x64dbg 观察线程状态是否为 “Waiting (Alertable)”
  • GUI 线程天然适合:消息循环中 GetMessage 本身不 alertable,但 MsgWaitForMultipleObjectsEx + INFINITE + bAlertable=TRUE 是常见模式
  • 控制台/服务线程需改造:若你控制目标进程,可插入 SleepEx(1, TRUE) 循环;若不可控,则基本无法可靠注入

注入步骤:分配内存 → 写入 Shellcode → 排队 APC 回调

APC 注入不是直接执行代码,而是让目标线程在它自己的上下文中调用你提供的函数(即 APC 函数)。该函数必须位于目标进程地址空间,且通常需自行完成重定位和导入解析(除非只用 kernel32/ntdll 的固定地址导出)。

典型流程如下:

  • 用 OpenProcess 获取目标进程句柄(需 PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_CREATE_THREAD 权限)
  • 用 VirtualAllocEx 在目标进程中申请可执行内存(PAGE_EXECUTE_READWRITE)
  • 用 WriteProcessMemory 将 shellcode(如加载 DLL 的 stub)写入该内存
  • 用 QueueUserAPC 向目标线程排队:第一个参数是 shellcode 地址(即 LPTHREAD_START_ROUTINE),第二个是目标线程句柄,第三个是 NULL(APC 参数,一般不用)

注意:QueueUserAPC 的回调函数签名必须是 VOID CALLBACK apc_func(ULONG_PTR dwParam),不能带其他参数或返回值;且它运行在目标线程上下文中,栈和寄存器均属目标线程。

Shellcode 必须自包含:不能依赖调用方栈或外部变量

APC 回调函数被系统调度时,你无法预知目标线程当前的栈深度、寄存器状态或 SEH 链。任何基于局部变量、未初始化指针、或假设特定寄存器值的逻辑都会崩溃。

C++14
C++14

C++14 对 C++11 的修正与增强版本,适合旧系统维护和较老工具链兼容。

下载

安全做法是:shellcode 全部硬编码或使用位置无关方式(PIC),所有 API 地址通过手动解析 ntdll.dll 和 kernel32.dll 的导出表获取(即 “API hashing + 手动 PE 解析”),避免调用 LoadLibrary 等高风险函数(它们可能触发 TLS 回调或加载器锁)。

  • 推荐最小化功能:仅实现 LoadLibraryA 加载一个 DLL 路径(路径字符串需写死在 shellcode 中,或从 APC 参数传入——但需确保参数地址在目标进程有效)
  • 避免使用 C 运行时:不要用 printf、malloc、异常处理等;纯汇编或手写 C 内联 asm 更可控
  • 调试技巧:先用 CreateRemoteThread 测试同一段 shellcode 是否能跑通,再切换到 APC 方式——排除 shellcode 本身问题

权限与兼容性陷阱:SeDebugPrivilege 和 Wow64

没有 SeDebugPrivilege,OpenProcess 会失败(错误码 ERROR_ACCESS_DENIED);而启用该权限需先调用 OpenProcessToken + LookupPrivilegeValue + AdjustTokenPrivileges,缺一不可。

32 位进程向 64 位进程注入(或反之)完全不可行:VirtualAllocEx 和 WriteProcessMemory 会返回 ERROR_PARTIAL_COPY 或直接失败。APC 注入同样受此限制——架构必须严格匹配。

  • 检查目标进程位数:用 IsWow64Process(32 位进程查 64 位)或 GetNativeSystemInfo + GetSystemInfo 对比
  • UAC 提权后仍需显式启用 SeDebugPrivilege:即使你是 Administrator 组,该权限默认也是 disable 状态
  • Windows 10 RS5+ 引入 PPL(Protected Process Light):对某些系统进程(如 csrss.exe、winlogon.exe),即使有 debug 权限也无法打开,OpenProcess 直接返回 NULL

真正难的从来不是怎么调用 QueueUserAPC,而是让目标线程老老实实停在 alertable 状态、并确保你的 shellcode 在它那个陌生的栈和寄存器环境下活过前 10 条指令。

C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!

相关专题

更多
c++和c语言的区别有哪些
c++和c语言的区别有哪些

c++和c语言的区别:1、面向对象编程(OOP)支持不同;2、新增特性不同;3、标准库不同;4、编译方式不同;5、命名空间不同等等。想了解更多c++的相关内容,可以阅读本专题下面的文章。

2024.03.14

2288

9

c++和python学习顺序推荐
c++和python学习顺序推荐

一般建议先学习C++,再学习Python,因为这样可以逐步从较为底层的编程语言向更高级的语言过渡。想了解更多python的相关内容,可以阅读本专题下面的文章。

2024.03.14

1039

6

python和c++学习性价比分析
python和c++学习性价比分析

Python易于学习,广泛应用于Web开发、数据科学和人工智能等领域,但性能较低。C语言性能高,适用于对性能要求较高的场景,如游戏开发和系统编程,但学习曲线陡峭,错误处理复杂。想了解更多python的相关内容,可以阅读本专题下面的文章。

2024.03.14

447

5

c语言和c++一样吗
c语言和c++一样吗

c语言和c++是两种不同的编程语言,虽然有相似之处,但存在显著差异。c语言专注于过程式编程和系统级开发,以简洁、高效著称。c++作为c语言的超集,引入了面向对象编程,增强了代码组织和管理能力,但学习曲线也更陡峭。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.03.14

347

5

c语言和c++先学哪个好
c语言和c++先学哪个好

初学者选择学习c语言还是c++语言,需要根据个人学习目标、背景以及编程兴趣和预期应用方向来决定。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.03.14

426

5

c语言和c++的区别和联系
c语言和c++的区别和联系

c语言和c++是计算机科学领域应用广泛的编程语言。虽然它们有着相似的基础,但它们在语言类型、语法功能和内存管理方面存在着显著差异。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.03.14

600

5

c++软件中文更改教程
c++软件中文更改教程

对于 ide,可通过打开设置,找到语言设置,选择中文,并保存更改。对于非 ide 应用程序,可查找设置或选项,选择语言设置,更改为中文,并保存更改。想了解更多c++的相关内容,可以阅读本专题下面的文章。

2024.03.21

1429

9

python和java和c++学习性价比分析
python和java和c++学习性价比分析

Python以其易学性、丰富的库和活跃的社区而著称,适合数据科学、人工智能和Web开发。Java以其跨平台性、企业级应用开发和Android应用开发而闻名。C++以其底层控制能力、高效性能和游戏开发而著称。选择哪种语言取决于个人兴趣、职业方向和特定需求。想了解更多python和java和c++的相关内容,可以阅读本专题下面的文章。

2024.03.22

1237

7

c++和c语言学习顺序推荐
c++和c语言学习顺序推荐

对于初学者,建议先学习C语言,掌握编程基础后再转入C++,便于理解面向对象编程概念。有编程经验者可直接学习C++,快速接触高级编程技术。想了解更多c++和c语言的相关内容,可以阅读本专题下面的文章。

2024.03.25

1325

9

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C++ Core Guidelines
C++ Core Guidelines

共0课时 | 0人学习

C++ Reference
C++ Reference

共0课时 | 0人学习

C++ 官方标准说明
C++ 官方标准说明

共0课时 | 0人学习