Eabusham2/CMD-spy
GitHub: Eabusham2/CMD-spy
CMD-spy 利用 ETW/WMI 实时捕获并记录 Windows 上所有控制台与脚本宿主进程的详细信息,即使是仅存活一毫秒的弹窗也能完整留存。
Stars: 0 | Forks: 0
# CMD-spy
[](https://github.com/Eabusham2/CMD-spy/actions/workflows/build.yml)
**捕捉每一个命令提示符窗口——即使是那些只闪烁一毫秒的窗口——并记录关于它们的所有信息。**
一些程序(安装程序、脚本、计划任务,偶尔也包括恶意软件)
会生成一个 `cmd.exe` 窗口,其出现和消失的速度太快,根本无法读取。CMD-spy
会实时监控这些弹出窗口。默认情况下,它会监控**所有已知的
控制台、终端和脚本宿主** —— `cmd.exe`、`powershell.exe`、`pwsh.exe`、
`conhost.exe`、`wscript.exe`、`cscript.exe`、`mshta.exe`,以及 Windows
终端应用(`wt.exe`、`WindowsTerminal.exe`、`OpenConsole.exe`)—— 并为
每一个记录:
- **任务信息** —— 进程名、PID、映像路径、用户和会话
- **命令行** —— 在窗口内运行的完整命令
- **原因** —— 生成它的父进程(名称、PID、路径及其自身的命令行)
- **动作** —— 弹出窗口存活期间启动的子进程
- **网络** —— 该进程拥有的 TCP/UDP 连接(尽力而为的快照)
- **时间** —— 本地和 UTC 时间戳
- **距启动时间** —— 弹出窗口是在机器开机后多长时间出现的,以及开机时间和系统正常运行时间
- **生命周期** —— 窗口存在的精确毫秒数及其退出代码
所有内容都会写入**日志文件**,并在 **GUI** 中实时显示。
## 它是如何捕捉存活仅一毫秒的窗口的
轮询进程列表是无法看到一个只存在一毫秒的进程的——
它在下一次轮询之前就已经消失了。CMD-spy 转而使用**实时的、事件驱动**
检测:
1. **ETW 内核进程跟踪(主要方式)。** CMD-spy 会打开一个 Event Tracing for
Windows 内核会话——这与 Sysmon 和 Process Monitor 使用的机制相同。
内核会传递一个*进程启动*事件,其中包含**创建那一刻的命令行和
父 PID**,因此弹出窗口在消失之前就已经被完整记录。
一个匹配的*进程停止*事件会给出确切的生命周期和
退出代码。**需要管理员权限。**
2. **WMI 进程启动跟踪(备用方式)。** 如果无法打开
ETW 会话(通常是因为 CMD-spy 未被提权),它会回退到
`Win32_ProcessStartTrace` / `Win32_ProcessStopTrace`。它们同样是
事件驱动的(而非轮询),因此仍然能看到存活时间短的进程,但
它们不携带命令行——CMD-spy 会尽力从 WMI 中恢复它。
为了获得最高的准确性,**请以管理员身份运行 CMD-spy。**
## 项目结构
```
CmdSpy.sln
src/
CmdSpy.Core/ Reusable capture engine (no UI)
Models/ CmdEvent, ProcessInfo, NetworkConnectionInfo
Monitoring/ ETW + WMI watchers, network inspector, boot-time helper
Logging/ EventStore (JSON-lines + human-readable .log)
Formatting/ Text renderer shared by the log and GUI
CmdSpyEngine.cs Orchestrator: detect -> filter -> enrich -> store
CmdSpyOptions.cs Configuration (targets, network, log directory, ...)
CmdSpy.App/ WinForms GUI dashboard (build output: CmdSpy.exe)
tests/
CmdSpy.Core.Tests/ xUnit tests for options, logging and formatting
```
## 构建说明
CMD-spy 的目标是 **.NET 8** 和 **Windows** (`net8.0-windows`)。WinForms、ETW 和
WMI 仅限 Windows 使用,因此该应用只能在 Windows 上运行。
### 在 Windows 上(常规途径)
安装 [.NET 8 SDK](https://dotnet.microsoft.com/download),然后:
```
dotnet build CmdSpy.sln -c Release
```
或者在 Visual Studio 2022 中打开 `CmdSpy.sln` 并进行构建。
### 测试
```
dotnet test CmdSpy.sln -c Release
```
测试项目涵盖了平台无关的逻辑——目标匹配、
日志往返(包括初始写入*之后*捕获的细节)以及
显示格式化。CI 会在每次推送时运行它。
### 在 Linux/CI 上交叉编译
如果添加
`EnableWindowsTargeting`,这些项目可以在非 Windows 主机上编译(但不会在那里*运行*):
```
dotnet build CmdSpy.sln -c Release -p:EnableWindowsTargeting=true
```
## 运行
```
# 右键点击 -> “以管理员身份运行”以获得完整的 ETW 保真度
src\CmdSpy.App\bin\Release\net8.0-windows\CmdSpy.exe
```
该应用**以提权状态运行**:它的清单会请求管理员权限,如果
在未提权的情况下启动(例如通过 `dotnet CmdSpy.dll`,这会忽略
exe 清单),它会通过 UAC 提示重新启动自身。它会自动开始监控
并显示一个捕获到的弹出窗口的实时表格。选择一行即可查看
完整详情(命令行、原因、动作、网络、时间)。工具栏:
- **开始 / 停止** 监控
- **目标 ▾** —— 默认情况下,每个控制台/终端/脚本宿主都会受到监控
(`cmd.exe`、`powershell.exe`、`pwsh.exe`、`conhost.exe`、`wscript.exe`、
`cscript.exe`、`mshta.exe`、`wt.exe`、`WindowsTerminal.exe`、
`OpenConsole.exe`);取消勾选任何你不需要的项,并切换网络 /
子进程捕获
- **过滤** —— 对命令行、进程、父进程和用户进行实时子字符串搜索
- **打开日志文件夹** / **导出…** (文本报告或 JSON lines)
- 状态栏显示监控来源、事件计数、开机时间和实时正常运行时间
## 日志存放位置
默认情况下,CMD-spy 会将内容写入:
```
%ProgramData%\CmdSpy\logs\
cmdspy-YYYYMMDD.jsonl one JSON object per line (machine-readable)
cmdspy-YYYYMMDD.log formatted, human-readable blocks
```
文件会按日期滚动。`.jsonl` 文件会在首次捕获到弹出窗口时写入一个完整对象,
然后每次获取到新细节(子进程、
新连接或其退出 + 生命周期)时重新写入完整对象。保留**每个事件 `id` 的最后一行**
即可获取完整的最终记录。`.log` 文件在
首次看到弹出窗口时会获得一个信息块,并在它退出时获得一个最终信息块。
### `.log` 条目示例
```
============================================================
#42 CMD POPUP CAPTURED (id 7f3c...)
============================================================
-- Time --------------------------------------------------
Local time : 2026-07-06 14:03:11.284 -07:00
UTC time : 2026-07-06 21:03:11.284
System boot time : 2026-07-06 08:15:02
Since bootup : 05:48:09.282
System uptime : 20889.3 s
-- Task info ---------------------------------------------
Process : cmd.exe (PID 9184)
Image path : C:\Windows\System32\cmd.exe
User : DESKTOP-ABC\alice
Session : 1
Detected via : ETW
-- Command line ------------------------------------------
cmd.exe /c "ping -n 1 example.com >nul & whoami"
-- Cause (parent process) --------------------------------
Parent : powershell.exe (PID 6012)
Parent image : C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
Parent cmdline : powershell.exe -File .\deploy.ps1
-- Lifetime ----------------------------------------------
Exited at (UTC) : 2026-07-06 21:03:11.331
Lived for : 47 ms
Exit code : 0
-- Actions (child processes) -----------------------------
* [9210] whoami.exe
* [9211] PING.EXE
-- Networking --------------------------------------------
(no connections captured)
```
## 注意事项与限制
- **仅限 Windows。** ETW、WMI 和 IP Helper API 在其他操作系统上不存在。
- **建议使用管理员权限。** 如果没有提权,CMD-spy 会回退到 WMI,并且
可能会错过那些存活时间最短的进程的命令行。
- **网络捕获是一个快照。** 一个在一毫秒内退出的窗口通常
还没有打开 socket,因此它的网络列表通常是空的——这是
预期的。存活时间较长的弹出窗口及其子进程会被更完整地捕获。
- 这是一个**防御性 / 诊断性**工具:它观察并记录本地机器上的进程
活动。它不会阻止、终止或修改任何内容。
标签:ETW, SQL, WMI, 系统审计, 系统运维