Windows Sysinternals 文件工具学习笔记(12.10):PendMoves + MoveFile 实战------重启后文件替换的安全姿势
- [Windows Sysinternals 文件工具学习笔记(12.10):PendMoves + MoveFile 实战------重启后文件替换的安全姿势](#Windows Sysinternals 文件工具学习笔记(12.10):PendMoves + MoveFile 实战——重启后文件替换的安全姿势)
-
- [一、为什么一定要学会 PendMoves / MoveFile?](#一、为什么一定要学会 PendMoves / MoveFile?)
- [二、核心原理:Session Manager + PendingFileRenameOperations](#二、核心原理:Session Manager + PendingFileRenameOperations)
- [三、MoveFile 实战:如何排队一个"重启后替换 DLL"的操作?](#三、MoveFile 实战:如何排队一个“重启后替换 DLL”的操作?)
-
- [3.1 场景设定](#3.1 场景设定)
- [3.2 使用 MoveFile 排队替换](#3.2 使用 MoveFile 排队替换)
- [四、PendMoves 实战:怎么确认计划排进系统了?](#四、PendMoves 实战:怎么确认计划排进系统了?)
- 五、典型实战套路:升级/替换系统文件的安全流程
-
- [5.1 推荐步骤(适合写到你的批处理中)](#5.1 推荐步骤(适合写到你的批处理中))
- 六、批量升级脚本示例(多台服务器/多文件)
- 七、常见坑与注意事项
-
- [7.1 必须有管理员权限](#7.1 必须有管理员权限)
- [7.2 操作顺序与依赖要考虑](#7.2 操作顺序与依赖要考虑)
- [7.3 不要一次写太多高风险操作](#7.3 不要一次写太多高风险操作)
- [7.4 与杀毒/EDR 的配合](#7.4 与杀毒/EDR 的配合)
- [八、与其他 Sysinternals 工具的组合拳](#八、与其他 Sysinternals 工具的组合拳)
- 九、小结
Windows Sysinternals 文件工具学习笔记(12.10):PendMoves + MoveFile 实战------重启后文件替换的安全姿势
本篇可以理解成:把 12 章前面的 Strings / Streams / Junction / FindLinks / DU / PendMoves / MoveFile,真正落地到"重启后替换系统文件"的实战篇。
一、为什么一定要学会 PendMoves / MoveFile?
Windows 上有一堆正在使用中的文件:
- 正在被系统或服务锁定(DLL、驱动、EXE)
- 被杀毒软件、备份软件 Hook 住
- 某些文件只有在系统启动前/关机过程中才会释放
这时候如果你:
- 直接复制覆盖 → 失败 / "文件正在被另一个程序使用"
- 强行卸载 / Kill 进程 → 可能直接把系统搞蓝屏、应用搞崩
PendMoves / MoveFile 的作用就是:
- 不和正在运行的系统"硬刚"
- 而是把文件操作排队到下次重启时、内核启动早期由系统执行
- 支持:移动 / 重命名 / 删除 等操作
简单理解:
👉 你先写好"TODO 清单"(MoveFile)
👉 让系统在下次启动时执行这份清单(PendMoves 负责查看/验证)
二、核心原理:Session Manager + PendingFileRenameOperations
Sysinternals 书里讲得很清楚:
这俩工具本质都是对这个注册表键做读写:
txt
HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\PendingFileRenameOperations
系统启动时:
- Session Manager(
smss.exe)读取该键的内容 - 按顺序执行文件移动/删除
- 执行完成后,相关项会被清空
MoveFile :往这个键写入变更计划
PendMoves:从这个键读出当前排队的变更
所以它们是一个"写操作器 + 查看器"的组合。
三、MoveFile 实战:如何排队一个"重启后替换 DLL"的操作?
3.1 场景设定
- 你要升级某个应用的 DLL:
C:\App\foo.dll - 新版本已放在临时目录:
C:\Temp\foo_new.dll foo.dll正在被服务占用,无法直接覆盖
3.2 使用 MoveFile 排队替换
cmd
MoveFile C:\Temp\foo_new.dll C:\App\foo.dll
含义:
- 源文件 :
C:\Temp\foo_new.dll - 目标文件 :
C:\App\foo.dll - 系统下次重启时会:
- 删除旧的
C:\App\foo.dll - 把
C:\Temp\foo_new.dll移到C:\App\foo.dll
- 删除旧的
想要重启后删除文件 ,可以把目标写成 NUL:
cmd
MoveFile C:\App\old_driver.sys ""
某些版本可以用空字符串或 NUL,书中与帮助信息里有具体说明,实际操作建议先用测试机验证。
四、PendMoves 实战:怎么确认计划排进系统了?
刚写入 Pending 项之后,你肯定想确认一下:
cmd
PendMoves
典型输出(伪示例):
txt
C:\Temp\foo_new.dll -> \??\C:\App\foo.dll
C:\App\old_driver.sys -> (delete)
看到这两条,就说明:
- 替换 DLL 的操作已经排队成功
- 删除驱动的动作也会在下次启动前执行
习惯做法:每次用 MoveFile 写入变更后,立刻用 PendMoves 看一下,并且截图/保存日志,方便审计和回滚。
五、典型实战套路:升级/替换系统文件的安全流程
5.1 推荐步骤(适合写到你的批处理中)
-
备份旧文件
cmdcopy C:\App\foo.dll C:\Backup\foo.dll.bak -
放置新文件(不要直接覆盖)
cmdcopy C:\Package\foo_new.dll C:\Temp\foo_new.dll -
使用 MoveFile 排队重启后替换
cmdMoveFile C:\Temp\foo_new.dll C:\App\foo.dll -
用 PendMoves 核对任务
cmdPendMoves > C:\Logs\pendmoves_foo_upgrade.log -
记录变更说明/变更单编号
-
在维护窗口内重启机器
cmdshutdown /r /t 60 /c "DLL升级:foo.dll 将在本次重启中被替换" -
重启后验证版本
- 用
sigcheck/ 文件属性 / 哈希检查 - 或用 ProcMon 验证程序已加载新 DLL
- 用
六、批量升级脚本示例(多台服务器/多文件)
假设你在一台服务器上,需要升级多个 DLL,可以写成类似这样:
bat
@echo off
setlocal enabledelayedexpansion
:: 升级清单:old->new
set PAIRS=foo.dll,foo_new.dll;bar.dll,bar_new.dll
for %%A in (%PAIRS%) do (
for /f "tokens=1,2 delims=," %%I in ("%%~A") do (
set OLD=%%I
set NEW=%%J
echo [INFO] 处理 !OLD!
copy C:\App\!OLD! C:\Backup\!OLD!.bak >nul
copy C:\Package\!NEW! C:\Temp\!NEW! >nul
MoveFile C:\Temp\!NEW! C:\App\!OLD!
)
)
PendMoves > C:\Logs\pendmoves_batch_upgrade.log
echo [INFO] 所有替换已加入重启队列,请在维护窗口内重启系统
endlocal
配合 PsExec 可以批量在多台机器上远程执行这段脚本,就是一个比较稳妥的"重启后升级"方案。
七、常见坑与注意事项
7.1 必须有管理员权限
- 修改
PendingFileRenameOperations属于系统级操作 - 在普通 CMD 中执行往往会失败,建议:
- 用"以管理员身份运行"的 CMD / PowerShell
- 或用 PsExec
-s/ 计划任务等高权限方式执行
7.2 操作顺序与依赖要考虑
- 系统在启动时是按队列顺序执行变更
- 多个文件之间存在依赖关系时,建议:
- 使用脚本明确写入顺序
- 尽量在同一批操作中完成
7.3 不要一次写太多高风险操作
- 特别是涉及驱动、系统核心 DLL 的删除/替换
- 建议:
- 一次只做一个组件
- 先在测试环境验证
- 生产环境严格走变更审批
7.4 与杀毒/EDR 的配合
- 某些安全软件会监控
PendingFileRenameOperations - 可能会误拦截"删除系统文件"的行为
- 生产环境实战前,建议:
- 与安全团队确认策略
- 必要时提前白名单或临时放宽
八、与其他 Sysinternals 工具的组合拳
这一章的工具其实可以组合成"完整链路":
- 用 DU 找出占用空间/需要清理的目录
- 用 Streams/Junction/FindLinks 查清楚真正引用关系(ADS、Junction、硬链接)
- 用 PendMoves/MoveFile 负责"重启后替换/删除"的执行
再结合前面章节的:
- Process Monitor 看谁在锁文件
- PsTools 远程下发脚本
- Sigcheck 校验签名与版本
就是一整套相对干净、可审计、可回滚的Windows 文件级变更流水线。
九、小结
这一篇的核心,可以压缩成一句话:
MoveFile 负责"写计划",PendMoves 负责"看计划",系统重启时帮你"执行计划"。
掌握这两个工具之后:
- 升级/替换被占用的 DLL、驱动、EXE 就不再靠"撞运气"
- 变更可记录、可审计、可批量,适合纳入企业运维流程
- 配合前面 12 章的那些工具,你已经基本具备一套
"看清文件 → 理解引用 → 安全变更 → 重启落地"的完整套路
后面如果你愿意,我们可以专门写一篇"从 ProcMon 日志到 PendMoves/MoveFile 的实战闭环",把排障和变更放在同一条时间线上,做成你自己的"Windows 故障剧本库"。