ITPub博客

首页 > 移动开发 > IOS > HTTP 抓包都会,裸 TCP/UDP 怎么调试?TraceEagle 实操教程

HTTP 抓包都会,裸 TCP/UDP 怎么调试?TraceEagle 实操教程

原创 IOS 作者:CodeDaily 时间:2026-10-22 16:30:23 0 删除 编辑

抓 HTTP 包,你看到的是请求和响应;抓裸 TCP,你看到的是一串没有边界的字节。UDP 更碎,一个数据报就是一份完整的东西,顺序和到达都不保证。把 HTTP 那套习惯直接搬过来,第一反应基本是:这堆东西哪一段是开头、哪一段是结尾?

这篇按五步走:先抓到、认方向、看字节、拆帧、再谈改写。用的还是 TraceEagle 的网卡直抓和自定义解码。

先抓到:网卡直抓才看得见非 HTTP 流量

代理抓包只认 HTTP 那一套,DNS、QUIC、ICMP、游戏协议、IoT 的长连接,它收不到。想看这些,得走网卡。

在 TraceEagle 里新建会话,选「本机网卡抓包」,再挑一块网卡。工具会自动列出本机所有网卡,也会默认选中当前活动的那块,不知道选哪个就先用默认的。

开抓前可以设一个过滤条件,也可以直接点内置预设:TLS、HTTP、QUIC、DNS、TCP、UDP、ICMP、ARP、SSH。这个过滤只在开始前设定,开始之后改不了;如果想在已经抓到的数据里再筛,用逐包视图的「显示过滤」,语法是 Wireshark 那一套, tcp.port==443、 tls.handshake、 dns 都能用。

抓到之后有两个视图互相配合:逐包视图看单个包的字节和协议分层树,连接视图把散包重组成一条条连接,右键「追踪此连接」能把整条流完整看下来。这一步没什么技巧,选对网卡、过滤开对就行吧。

认方向:一条 TCP 流有两个方向

TCP 是有连接的。三次握手之后,两边可以同时发数据,所以同一条连接上有两个方向:客户端到服务器,服务器到客户端。看流的时候,发送和接收是分开的两列,别把它们当成一条时间线。

UDP 没有连接,每个数据报都是独立的。方向只能从源地址和目的地址判断,丢包和乱序也都是常态。一个请求发出去,等回来的可能是空的,也可能是几条,跟 TCP 的体验完全不一样啊。

TCP 的重传、去重和排序由协议栈处理,应用层看到的是有序的字节流;UDP 没有这些保证,丢包、重复、乱序都得应用自己扛。这也是为什么很多实时音视频、游戏会选 UDP——宁可丢一帧,也不想等重传。

方向这件事不只是看着舒服。自定义解码器会对发送流和接收流分别跑一遍,并自动给每条消息标方向;改写也一样,要选是改上行还是下行。方向认错,后面的拆帧和改写都会歪。

看字节:hex 和文本之间来回切

原始字节的查看方式就两种:hex 和文本。工具里可以随时切,未解密或者非 HTTP 的数据,就靠这两个视图。

看字节的目标不是把整条流读懂,是先找规律。几个常见的线索:

  • 魔数:开头几个字节是固定的。比如 1f 8b 是 gzip, 50 4b 是 zip, 89 50 4e 47 是 PNG。
  • 长度字段:前面四个字节读出来,刚好等于后面的剩余长度,基本就是长度前缀协议。
  • 分隔符:文本协议常用换行、 \0 或者某个特殊字符结尾。
  • 可读字符串:hex 旁边那列 ASCII,经常能直接看到协议名、错误码、URL 片段。

二进制协议里,这几样经常同时出现:一个固定头、一个长度、一段负载,负载再压一道。别一上来就按文本去解啊,那样只会得到乱码。

还有一种常见结构:头是固定的,负载长度写在头里的某个字段,负载本身可能是 protobuf 或者压缩过的 JSON。先按头切,再把负载交给工具自动识别,基本就够用了。

拆帧:给字节流找边界

TCP 给的是字节流,不是消息流。「一条消息」是应用层自己定义的,工具必须知道在哪切、切多少,才能把它变成一条一条可看的东西。

它会先自动试一轮常见边界,比如定长的前缀。试不出来,可以手动上模板:长度前缀、Magic 签名边界、分隔符(支持 hex)、定长,还有 gzip 和按类型分派。改几个数字就能跑。

再复杂一点,就写解码器。整个解码器是一个函数,工具把某条连接的剩余字节交给它,它切出一条消息、返回消费了多少字节,然后再问下一次:

1function decode(buf, out) {2  if (buf.byteLength < 4) return 0        // 长度头还没到齐3  const total = 4 + u32be(buf, 0)         // 4 字节头 + 负载4  if (buf.byteLength < total) return 0    // 整条还没到齐5  out.push(sub(buf, 4, total - 4))        // 剥掉头,负载交给自动识别6  return total                            // 消费掉这一条7}

这就是一个最典型的长度前缀协议:前四字节大端读出长度,凑齐了再切。 TraceEagle 会分别对发送流和接收流跑这个函数,方向自动标好;切出来的消息还会再过一遍自动识别,是 protobuf、JSON 还是 plist,能解就继续解。脚本写坏了也不会把会话搞崩,最差就是看到原始字节,改完保存再重解一次,不用重新抓呢。

改写:按方向替换,但先想清楚后果

规则改写里有一类专门给非 HTTP 流量用:裸 TCP / UDP 字节流按方向做替换,和 WebSocket 帧改写是一套逻辑,都是 old=>new。

方向还是那三个:客户端到服务器、服务器到客户端、双向。改客户端请求里的固定字段,选上行;模拟服务器返回一个错误码,选下行。选错方向,帧一点变化都没有。

说清楚一个边界:改写挂在代理会话的规则上,走代理的 TCP/UDP(比如 SOCKS5 的数据报)能按方向替换;网卡直抓更适合看和解码,别指望在原始抓到的包上直接改。两者解决的不是同一个问题。

改之前还得先看一眼协议结构。如果这条消息有长度前缀、校验和、压缩或者加密,直接替换字节可能让后面的帧全乱套:长度对不上,解析器就找不到下一条;校验和不对,服务端可能直接丢掉。稳妥的做法是改完在工具里重新解一遍,确认边界还成立、校验还能过,再往下测。举个具体的:某个自研协议用 4 字节长度头,你想把下行消息里的错误码从 1001 改成 2001。先确认替换不改变长度,再按服务器到客户端的方向替换,改完重新解一遍,看下一条消息还能不能切出来。

和 Wireshark、tcpdump 比一比

Wireshark 的协议解析器库是这几家里最全的,几百种协议开箱就能拆,显示过滤、Follow Stream、专家信息都很成熟。纯看包、做协议层分析,它还是更专业的那一站。它不做流量改写,这也不是它的目标。

tcpdump 胜在轻和无头:ssh 到服务器上跑一条命令,把流量落成 pcap,再拉回本地慢慢看。它只负责抓,解析和改写都得另找工具。

它把网卡抓取、逐包和连接视图、自定义解码、规则改写放在一个界面里,非 HTTP 协议能一路走完抓、看、改,链路是通的。真要比协议解析的广度,它不如 Wireshark;要比无头抓取,它不如 tcpdump 轻。三者搭着用,比互相替代更实际吧。

非 HTTP 抓包的难点不在抓,在认边界。抓到字节只是开头,知道哪一段是一条消息、这条消息往哪个方向走、改完会不会破坏结构,才算真的看懂。

顺序可以记一下:选对网卡,用过滤收窄范围;先认方向,再看 hex 和文本;找到边界就上模板或写解码器;要改的话,先确认长度和校验,再按方向替换,改完重解一遍验证。

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70051050/viewspace-3186479/ ,如需转载,请注明出处,否则将追究法律责任。

下一篇: 没有了~
请登录后发表评论 登录
全部评论
iOS Worder

注册时间:2026-08-11

  • 博文量
    18
  • 访问量
    17700