攻防篇第一部分先不急着做具体技术细节,而是把“为什么会有注入”“注入和 PE 加载有什么关系”“一个安全实验工具应该怎么组织输入、输出、校验和日志”这些基础问题整理清楚。

这篇笔记只用于个人复盘、授权实验和防护理解。凡是涉及跨进程执行、内存修改、ShellCode 或规避检测的内容,后续都只记录概念、痕迹和边界,不写成可直接照抄运行的流程。

01.0 Windows 逆向攻防篇前置要求(一)

攻防篇默认前面两篇已经补过一遍。

前置内容 需要掌握到什么程度
C/C++ 基础 能读懂结构体、指针、函数指针、内存申请和文件读写
Windows API 知道进程、线程、模块、句柄、权限和错误码是基本对象
PE 结构 能理解 DOS 头、NT 头、节表、导入表、重定位和入口点
汇编基础 能看懂调用、跳转、栈帧、寄存器和常见 x64 调用约定
调试工具 能使用 VS、x64dbg、IDA 观察模块、线程、内存和调用栈
安全边界 只分析自写程序、课程样本和明确授权目标

攻防篇不是脱离基础知识的“技巧集合”。很多技术看起来名字不同,本质上都在围绕同几件事:进程空间、线程执行、模块加载、地址解析和系统事件。

01.1 Windows 逆向攻防篇前置要求(二)

学习这部分时,最好先把实验环境和记录方式固定下来。

项目 建议
实验对象 自写控制台程序、课程提供样本、虚拟机里的授权程序
实验环境 Windows 虚拟机,快照可回滚
工具记录 每次实验记录进程名、PID、模块、线程、内存区间和日志
防护观察 同时观察系统日志、ETW/WMI、调试事件、进程树和模块变化
代码边界 不整理规避检测、隐蔽执行和未授权持久化流程

复盘习惯

每看一个技术点,都问自己四个问题:

  1. 它利用了 Windows 哪个正常机制?
  2. 它在进程、线程、模块或内存上留下什么变化?
  3. 调试器、日志或安全工具能看到什么?
  4. 如果我是防守方,应该在哪个环节做限制或告警?

01.2 Windows 平台应用层注入基本概念

应用层注入可以先理解成:把外部代码、模块或执行逻辑引入另一个进程的地址空间,并让目标进程中的线程执行相关逻辑。

概念拆解

组成 含义
目标进程 被观察或被操作的进程,必须限定在授权环境
载荷内容 可能是 DLL、ShellCode、函数地址或一段待执行逻辑
内存承载 目标进程中需要有一块可承载数据或代码的空间
执行触发 需要某种方式让目标进程中的线程进入目标逻辑
清理与恢复 实验结束后恢复资源、释放句柄、记录结果

这里先只建立概念,不整理具体实现调用链。真正重要的是把“进程地址空间”和“线程执行流”分开理解:写入内容是一件事,让线程执行又是另一件事。

防护视角

观察点 可能关注什么
进程关系 是否存在异常父子关系或跨进程操作
句柄权限 是否有进程/线程高权限句柄打开行为
内存属性 是否出现异常可执行页、可写可执行页或属性突变
线程行为 是否出现异常线程入口、上下文变更或异步回调
模块变化 是否加载了不常见模块或路径异常的 DLL

01.3 注入框架思路及 PE 加载修复流程

很多注入技术都绕不开 PE 加载的基本问题。正常情况下,Windows 加载器负责把 PE 文件从磁盘映射到进程内存,并完成导入、重定位、节区保护和入口点转移。

正常 PE 加载中的关键动作

动作 说明
映射文件 把文件中的节区映射到内存中的对应 RVA
修复导入 根据导入表找到 DLL 和 API 地址
修复重定位 实际基址和首选基址不同,则修正绝对地址
设置权限 根据节属性设置读、写、执行权限
执行入口 从入口点进入模块逻辑

攻防技术里常见的“手动加载”“反射式加载”“内存映像转换”,都可以理解为在某些环节部分模拟加载器行为。

复盘重点

问题 应该回到哪里
为什么要修导入? 导入表、IAT、DLL/API 解析
为什么要重定位? ImageBase、RVA、Relocation Directory
为什么节区权限重要? .text.rdata.data 与内存页保护
为什么入口点敏感? OEP、模块初始化、线程执行流

01.4 注入系统控制台版本开发思路

课程里的控制台框架可以当成“安全实验工具外壳”来理解,不必把重点放在具体攻击动作上。

一个安全实验工具应该具备的模块

模块 作用
配置模块 保存实验模式、目标信息、日志路径和开关
输入模块 接收用户输入,并进行严格校验
展示模块 清楚显示当前模式、实验对象和风险提示
任务模块 把不同实验动作拆成独立函数
日志模块 记录时间、参数、结果和错误码
清理模块 释放资源、关闭句柄、恢复状态

这种框架对后续学习很有用:无论是线程实验、Hook 实验还是 ETW/WMI 监控,都可以复用同一套输入、输出和日志结构。

01.5 控制台程序属性初始化

初始化阶段不应该急着执行核心逻辑,先把环境状态准备好。

初始化内容 说明
控制台标题 标识当前工具和实验模式
输出颜色 区分普通信息、警告、错误和成功
日志文件 每次运行单独保存结果,方便复盘
参数结构 用结构体统一保存用户输入和运行状态
权限提示 明确提示只允许在授权环境中使用

建议结构

1
2
3
4
5
6
7
AppContext
- mode
- target_name
- target_pid
- log_path
- dry_run
- last_error

这里的 dry_run 很重要。很多实验可以先做“只展示计划、不执行动作”的预演模式,用来减少误操作。

01.6 控制台程序输出标题润色封装

输出不是装饰,它直接影响复盘效率。一个好的实验输出,应该让自己回来看的时候能快速知道当时发生了什么。

输出类型 内容
标题 当前课程模块、实验名称、时间
环境 操作系统、架构、权限状态、调试模式
目标 目标进程名、PID、路径、架构
风险提示 是否需要管理员权限、是否会修改目标状态
结果 成功、失败、错误码和下一步建议

输出风格

1
2
3
4
[INFO] 当前模式:只读检测
[WARN] 当前操作可能改变目标进程状态
[FAIL] 目标进程不存在或权限不足
[OK] 日志已保存

01.7 控制台程序模拟进度加载过程

进度展示可以帮助区分“程序卡住”和“正在执行某个阶段”。但安全实验里不要用进度条掩盖真实步骤,最好把每个阶段都明确打印出来。

阶段 示例输出
参数检查 检查目标输入和运行模式
环境检查 检查架构、权限、工具状态
目标检查 检查进程是否存在、路径是否匹配
任务执行 进入对应实验逻辑
结果保存 保存日志、清理资源

这样后续出错时,能从日志里定位是输入问题、权限问题、目标状态问题,还是实验逻辑问题。

01.8 用户交互及输入信息流程构建

用户输入必须严格校验。攻防实验最怕“随手输入一个 PID 就执行”,因为 PID 可能复用,目标也可能不是自己想象的程序。

输入校验建议

输入 校验点
进程名 是否为空、是否存在多个同名进程
PID 是否为数字、是否仍然存活、是否和进程名匹配
文件路径 是否存在、是否为预期类型、是否在实验目录内
模式选择 是否属于白名单选项
架构 x86/x64 是否和目标一致

防误操作设计

设计 作用
默认只读 默认只做枚举、检测、展示,不改变状态
二次确认 涉及状态修改前,要求明确确认
实验白名单 只允许操作指定实验程序或测试目录
日志必开 所有动作都写入日志,方便回滚复盘

01.9 业务功能统一显示模板

统一显示模板可以让后续所有小实验保持同一种格式。

1
2
3
4
5
6
7
8
模块名称:
实验目的:
目标对象:
执行模式:
风险提示:
预期观察:
实际结果:
复盘记录:

后续每个实验都要补的内容

项目 说明
实验目的 这次实验验证哪个 Windows 机制
观察点 进程、线程、模块、内存、日志、异常中看什么
检测思路 防守侧可以通过哪些现象发现
失败原因 权限、架构、路径、保护机制、输入错误等
安全边界 是否只在授权样本上执行,是否会修改目标状态

本节小结

这部分看起来像“写控制台外壳”,但它其实决定后续笔记能不能复盘清楚。攻防篇的技术点很多,如果没有统一的输入、输出、日志和边界意识,后面很容易变成零散技巧。

我后续整理每一个小节时,都尽量保留三层信息:

  1. 机制:Windows 原本提供了什么能力。
  2. 行为:攻防技术利用这个能力做了什么。
  3. 检测:防守侧能观察到什么痕迹。

学习检查清单

检查项 状态
能说明攻防篇需要哪些前置知识 待复盘
能区分“写入内容”和“触发执行”两个概念 待复盘
能解释注入技术和 PE 加载修复之间的关系 待复盘
能列出进程、线程、模块、内存页和句柄这些观察点 待复盘
能设计一个默认只读、带日志、带二次确认的实验框架 待复盘
能把每次实验整理成目的、目标、风险、观察和结果 待复盘

这一节先把边界立住:后续不是为了堆“攻击招式”,而是为了把 Windows 用户态执行、加载、调试、监控和检测这些机制串起来。