在 Windows 上用 Wireshark 抓包,最烦的是抓完之后不知道哪条流量是目标软件的。
原因不是 Wireshark 不好用,而是它抓包的位置决定的:包在协议栈里流转的时候,TCP/IP 头里没有任何字段记录"这个包是哪个进程发的"。进程信息属于内核的 socket 表,不属于协议。所以抓包工具拿到的是一堆没有归属的字节流,只能靠端口、IP 去猜。
这不是能靠配置解决的问题。Wireshark 里确实有个 _ws.process.id 字段,但它靠 Windows 的 ETW(NDIS 层)把 PID 打进元数据,再在显示时读出来。libpcap 抓包路径拿不到这份元数据,所以在 Wireshark 里直接抓,那个字段永远是空的。
能按进程抓的是 pktmon
Windows 10 1809+ 内置了 pktmon,它在抓包时就把 PID 写进 ETL 里------进程身份是内核在抓包那一刻记录的,不是事后重建的。
管理员终端:
css
pktmon start --capture --pkt-size 4096 --file-name cap.etl
:: 这时候去操作目标软件
pktmon stop
pktmon etl2pcap cap.etl --out cap.pcapng
然后用 tshark 按 PID 过滤(PID 从任务管理器或 tasklist | findstr 软件名 拿):
go
tshark -r cap.pcapng -Y "_ws.process.id == 12345" -w filtered.pcap
filtered.pcap 丢回 Wireshark,里面就只剩目标进程的包了。Statistics → Conversations 这时候才是干净的连接清单,而不是整台机器上所有程序的流量。
它解决什么,不解决什么
解决的是归属问题:哪些包属于哪个进程。
不解决内容问题:HTTPS 还是密文。要明文得做中间人解密,工具选 mitmproxy(免费、可写脚本)或 Charles(图形化、收费),流程是起代理 → 让目标走代理 → 装并信任 CA。
到了代理这一层,过滤问题会以另一种形式回来:mitmproxy 会把所有走代理的流量都记下来,浏览器、微信、系统更新全在里面。有效的做法是拿每个 flow 的客户端源端口,去 psutil.net_connections() 里反查 PID,只留目标 PID 的 flow。这样既拿到明文,又不会混进无关流量。
两个会卡住人的地方:
SSL Pinning。 不少客户端(金融、证券、部分游戏)把服务端证书指纹硬编码在程序里,装了 mitmproxy 的 CA 也没用,握手直接失败。这种情况要上 Frida hook 证书校验函数,属于逆向,不是抓包了。
代理绕过。 桌面软件不一定读系统代理,有的要设 HTTP_PROXY / HTTPS_PROXY 环境变量再启动,有的写死了直连。QUIC 和裸 UDP 完全不经过代理,L3/L4 还能看到,L7 就没了。
封装成了一个工具
我把这套流程做成了 proc-sniffer:pktmon 按 PID 抓包 + 可选的 mitmproxy L7 层(按源端口反查 PID,只记录目标进程的明文)。
CLI 和 MCP server 两个形态,MCP 那边可以直接让 Claude / Cursor 调起来抓包、停止、导出。
rust
process name --psutil--> PID / local ports
L3/L4: pktmon (captures with PID) --> ETL --etl2pcapng--> pcapng --filter by PID--> filtered.pcap
L7 : mitmproxy (proxy, filter by src port -> PID) --> http_traffic.jsonl
export: requests.json / index.md / filtered.pcap / http_traffic.jsonl
bash
# 同时抓 L3/L4 + L7,抓 chrome 30 秒
python proc_sniffer.py chrome 30 full
输出在 %PROC_SNIFFER_WORKDIR%\exports\<app>\:
requests.json/index.md:连接清单filtered.pcap:只含目标进程的包,可以用 Wireshark 打开http_traffic.jsonl:L7 明文,一行一个{method,url,req_*,resp_*}
如果机器上没装 Wireshark,就没有 tshark,_ws.process.id 那条过滤用不了。工具会退回端口采样:抓包期间每秒采一次目标进程占用的本地端口,再按端口过滤。短连接可能漏。
实际踩到的几个坑
- PID 会变。 软件重启、子进程拉起新 PID,得重新解析。按进程名 / exe 名 / cmdline 模糊匹配比精确 PID 稳。
- 必须管理员权限。 抓包和读取所有进程的连接都需要提权。
- etl2pcapng 和 pktmon etl2pcap 有差别。 内置的转换能用,但微软那个独立的
etl2pcapng.exe输出略干净一些,工具会优先找它。 - macOS 和 Linux 没这个问题。
lsof -i加tcpdump,或者ss -tp,直接带进程名。Windows 要绕这一圈,是因为 NDIS 层不带进程语义。
使用范围
工具抓的是本机上运行的软件。只对你自己拥有、或者有书面授权分析的软件使用------做协议对接、兼容性调试、安全研究、学习。抓别人的客户端和接口,技术上做得到,但在多数司法辖区是违法的,也违反用户协议。这不是免责声明,是工具本身的边界。
MIT 协议。
有抓不到的情况可以在评论区说软件名和想看到的结果,我看到了会回。