Portmon是唯一能直接捕获Windows内核层串口IRP请求的免费工具,需以管理员身份运行并禁用驱动签名强制策略;通过过滤Serial/IRP_MJ_READ/IRP_MJ_WRITE、指定进程名,可精准定位通信流;结合配对分析、Stack Trace验证及Buffer比对,可准确解析真实Modbus等协议交互。

要在Windows系统中用Portmon实时捕获串口(COM)设备底层的数据收发行为,必须绕过应用层串口助手的抽象封装,直接观察Windows内核I/O管理器对Serial.sys驱动发出的IRP请求——Portmon正是唯一能完成这项任务的免费工具,它不依赖目标程序是否开启调试符号,也不要求修改被监控进程。
安装Portmon并启用内核模式捕获
从Sysinternals官网下载最新版Portmon(v3.04或更高),解压后以管理员身份运行Portmon.exe;首次启动时会自动弹出驱动安装提示,点击“Yes”允许加载Portmon.sys内核驱动;若提示“Driver not found”,说明当前系统启用了驱动程序强制签名(DSE),需临时禁用:重启进入高级启动→疑难解答→启动设置→重启后按F7选择“禁用驱动程序强制签名”;Portmon界面左上角状态栏显示“Capturing”即表示已成功挂载到I/O子系统。
过滤并定位目标串口通信流
点击菜单栏“Filter”→“Include”,在弹出窗口中勾选“Serial”和“IRP_MJ_WRITE”“IRP_MJ_READ”两项;取消勾选“IRP_MJ_CREATE”“IRP_MJ_CLOSE”,避免淹没有效数据;在下方“Process”栏输入你正在调试的程序名(如“SSCOM.exe”或“ComHelper.exe”),确保只捕获该进程的串口操作;此时Portmon开始滚动显示原始IRP记录,每条记录包含时间戳、进程PID、设备对象地址、操作类型、字节数及缓冲区十六进制快照——注意:串口写入的IRP_MJ_WRITE条目中,Data字段末尾常含\r\n或\x00,这是多数设备协议的帧结束标志,漏看此处会导致误判数据未发出。
AI 领域系统学习体系。管理知识图谱、深度学习笔记、实战复盘和关联网络。触发场景:学习计划、知识图谱更新、深度研究某个 AI 主题、实战复盘总结、调研后沉淀知识、每周学习回顾。当用户说'学了什么'、'总结一下'、'沉淀知识'、'复盘'、'更新图谱'、'深入研究'、'写笔记'、'学习回顾'、'review what...
解析关键IRP字段识别真实通信行为
方法一:追踪IRP_MJ_WRITE → IRP_MJ_READ配对
当看到某进程发出IRP_MJ_WRITE(Length=12)后,紧随其后出现同一PID的IRP_MJ_READ(Length=8),且两者时间间隔小于50ms,基本可判定为一次完整问答交互;
方法二:检查Stack Trace中的DeviceObject
双击任一条IRP记录,在弹出窗口底部查看“Stack Trace”,若第二行显示“serial!SerialReadWrite”或“serenum!SerenumDispatch”,说明该IRP确实由系统串口驱动处理,而非虚拟串口软件(如VSPD)伪造;
方法三:比对Buffer Data与应用层发送内容
在你的C#程序中用SerialPort.Write(new byte[]{0x01,0x03,0x00,0x00,0x00,0x06},0,6)发送Modbus帧,Portmon中对应IRP_MJ_WRITE的Data字段应精确显示“01 03 00 00 00 06”,若出现额外填充字节(如多出0x00 0x00),说明上位机代码存在缓冲区未清空或WriteTimeout设置过短导致截断。
导出日志用于离线协议逆向分析
点击菜单栏“File”→“Save As”,保存为.pml格式日志文件;该格式可用Portmon自带回放功能逐帧重演,也可用文本编辑器打开提取Hex数据段;若需导入Wireshark进一步分析,先用PowerShell执行:Get-Content -Path "log.pml" | Select-String "Data:" | ForEach-Object { $_.Line.Split(':')[1].Trim() } | Out-File -FilePath "raw.hex" -Encoding ASCII;生成的raw.hex文件可被CyberChef等工具直接解析为ASCII/Modbus帧结构。

















