726 lines
42 KiB
Markdown
726 lines
42 KiB
Markdown
# e:net 协议复原文档(e:cue SymphoLight 5.5 ↔ Butler S2)
|
||
|
||
> 基于实测抓包复原(2026-09-08 初版,Wireshark/tshark 抓取于"以太网 3")。
|
||
> 抓包环境:SymphoLight 5.5 (192.168.123.113) ↔ Butler S2 固件 2.0.3322 (192.168.123.1)。
|
||
> 样本:discovery.pcap(启动/发现阶段 56 帧)、dmx40s.pcap(工程驱动阶段 ~5900 帧)。
|
||
>
|
||
> **2026-09-09 重大更新**:基于真机冷启动全程抓包 `cold2.pcap`(168.7s / 19471 帧,
|
||
> SymphoLight 冷启动 → 发现 → 注册 → AECH 认领 → RDM 全程)与虚拟 Butler 验证抓包
|
||
> `fix1.pcap`。补全设备上线协议链(§3.6/§3.7),RDM 层完全解码(§5 重写),
|
||
> 新增虚拟 Butler 实现与验证(§11)。
|
||
>
|
||
> **2026-09-10 更新**:稳态双网段对比(ss123/ss58)+ P1 修复验证(fix2/fix3)。
|
||
> DMX 帧完全解码(§4.1 重写:seq/保护字节 `(CH-1)^K`/节点序号/端口布局);
|
||
> 42B 帧重定性为事件计数遥测(§4.3,推翻"逐帧 ACK");发现收敛与稳态轮询
|
||
> 对齐(§11.3);新增 §11.5 DMX 解码里程碑、§12 缺口清单与攻关路线图。
|
||
>
|
||
> **尺寸口径约定**:本文所有帧长如无特别说明均为 **UDP 负载字节数**。
|
||
> 以太网整帧长 = UDP 负载 + 42(Eth14 + IP20 + UDP8)。历史记录中
|
||
> "89B 注册帧"=47B 负载、"594B AECH"=552B 负载、"259B 发现应答"=217B 负载、
|
||
> "101B 脉冲"=59B 负载、"84B ACK"=42B 负载(§4.3 遥测帧),均为同一帧的两种口径。
|
||
|
||
---
|
||
|
||
## 1. 总览
|
||
|
||
| 项目 | 值 |
|
||
|------|-----|
|
||
| 传输层 | UDP(无 TCP) |
|
||
| 主数据端口 | **31772** (0x7C1C),双向,主机与设备均使用该端口收发 |
|
||
| 密钥/许可端口 | **1947**,主机→广播,周期性,静态负载 |
|
||
| 帧签名 | 负载前 4 字节 = ASCII `"ENet"`(`45 4E 65 74`) |
|
||
| 字节序 | 混合:长度/计数器字段为 **小端 (LE)**,端口字段为 **大端 (BE)** |
|
||
| 加密 | **DMX 通道数据经 zPprv0TXRRW 逐帧混淆**(§4.1,已完全破解可双向复现):rot=(B12^r)&511,B12=AECH 实例随机(会话),r=Random.Next()(每帧每端口,帧内 0x22/0x26)。发现帧含部分随机材料 |
|
||
| Wireshark 识别 | 无 dissector,全部显示为 `data` |
|
||
|
||
---
|
||
|
||
## 2. e:net 通用帧头(所有 31772 报文)
|
||
|
||
UDP 负载布局(偏移为负载内字节偏移):
|
||
|
||
```
|
||
偏移 长度 示例(主机DMX帧) 含义
|
||
0x00 4 45 4E 65 74 魔数 "ENet"(另见 §3.4 的 "EUCE" 第二魔数)
|
||
0x04 4 04 00 00 00 消息类型 (LE uint32):01=发现/宣告, 02=主机标识心跳, 04=会话数据
|
||
0x08 4 00 00 1C 7C 端口 31772 (BE uint16 前置 0000)
|
||
0x0C 6 00 00 00 00 00 00 保留 (实测恒 0)
|
||
0x12 2 01 00 协议版本/标志 (实测恒 0x0001)
|
||
0x14 4 3C 04 00 00 负载总长 (LE uint32) = UDP负载字节数
|
||
0x18 2 01 00 固定字段 (实测所有 ENet 会话帧恒 0x0001)
|
||
0x1A 2 97 01 DMX 帧序号 (LE uint16,仅 DMX 数据帧;0x197→0x198→…)
|
||
0x1C ... 类型专属字段
|
||
```
|
||
|
||
已实测的长度字段对应关系:
|
||
| 帧总长(以太网) | UDP负载长 | 0x14 处 LE 值 |
|
||
|---------------|-----------|---------------|
|
||
| 222 / 259 / 540 / 686 / 1126 | 180/217/498/644/1084 | 0xB4/0xD9/0x1F2/0x284/0x43C ✓ |
|
||
| 84 / 171(Butler→主机) | 42/129 | 0x2A/0x81 ✓ |
|
||
|
||
---
|
||
|
||
## 3. 消息类型 01 —— 设备发现 / 宣告
|
||
|
||
### 3.1 主机发现请求(222 B,主机→255.255.255.255 广播)
|
||
- 负载 180 B。0x18 处 `B4 00 00 00`(=180)。
|
||
- 负载中含:主机 IP (LE `71 7B A8 C0`=192.168.123.113)、主机 MAC、
|
||
机器名+GUID ASCII(如 `tonycaoDESKTOP-PED2LVD-f7f4a043-1a`)、尾部 `09 00`。
|
||
|
||
### 3.2 Butler 发现应答(259 B,Butler→主机单播)
|
||
- 负载 217 B。含设备名 ASCII `"Butler S2"`、Butler IP (LE `7B A8 C0 00` 区域)、
|
||
Butler MAC (`00 16 1C F1 2E 39`)、固件信息区
|
||
(`23 01 00 00 00 00 24 00 00 00 24 00 00 00 1C 00 ...` 版本/参数块)、
|
||
DMX 时序参数区(`F0 0A`=BRK 100µs? `F0 0A`、MAB 等)。
|
||
|
||
### 3.3 主机宣告帧(540 B / 686 B,主机→广播,周期 ~30s)
|
||
- type=01,686 B 版负载 644 B(0x284 ✓)。含:
|
||
- 主机 IP、广播地址、主机 MAC
|
||
- 16 B 随机/密钥材料:`43 A0 F4 F7 EC 17 56 41 81 2B 90 9B DC 99 F2 FF`
|
||
- **UTF-16LE** 主机名+GUID:`tonycaoDESKTOP-PED2LVD-f7f4a043-17ec-4156-812b-909bdc99f2ff`
|
||
- `D0 07` = 2000(LE,疑似辅助端口)
|
||
- 时间戳 `EA 07 09 07 17 14 12 F4` = 2026-09-07 17:14:20.244(年/月/日/时/分/秒/毫秒)
|
||
- 尾部 `5A 00 FF FF`
|
||
|
||
### 3.4 主机标识心跳(36 B 负载 / 78 B 帧,type=02 sub=03,主机→广播,~6-30s 周期)
|
||
|
||
```
|
||
0x14 24000000 负载长 36
|
||
0x18 0300 子类型 3
|
||
0x1A 717BA8C0 主机 IP 192.168.123.113 (LE)
|
||
0x1E 300ED559BB36 主机 MAC
|
||
```
|
||
|
||
★2026-09-09 实测(cold2.pcap):认领后每 ~6s 一发,**设备从不应答**。
|
||
(旧虚拟 Butler 实现误回 42B 状态帧,已列入修正项。)
|
||
|
||
### 3.5 "EUCE" 帧(582 B,非 ENet 魔数,主机→广播,~30s 周期)
|
||
|
||
- 魔数 `45 55 43 45` = ASCII **"EUCE"**(与 "ENet" 并存的第二种 e:cue 载荷签名)。
|
||
- `EUCE 0000 0000 0000 0000 0500 0000 …`(**0x0C 处 LE `05`**=类型/版本 5),其余大量零。
|
||
- 40s 窗口观测 6 帧(帧号 668/1576/2530/3421/4309/5222,间隔 ~908 帧 ≈ 30s),
|
||
与 type=02 心跳交替出现,属主机的周期性身份/发现通告族。
|
||
|
||
### 3.6 设备注册(type=02 sub=01 → sub=02)—— 认领前的关键步骤 ★2026-09-09 补全
|
||
|
||
冷启动实测(cold2.pcap,t=38.087):
|
||
|
||
```
|
||
主机 → Butler: 102B type=02 sub=01 主机身份宣告
|
||
0x1A-0x1D 主机 IP (LE)
|
||
0x1E-0x23 主机 MAC
|
||
Butler → 主机: 47B type=02 sub=02 注册应答 (10ms 内)
|
||
0x1A-0x1D 设备 IP (LE) 例: 017ba8c0 = 192.168.123.1
|
||
0x1E-0x23 设备 MAC 例: 00161cf12e39
|
||
0x24 00
|
||
0x25-0x28 主机 IP (LE) 例: 717ba8c0 = 192.168.123.113
|
||
0x29-0x2E 主机 MAC 例: 300ed559bb36
|
||
```
|
||
|
||
47B 注册应答完整样本:
|
||
`454e6574 02000000 00001c7c 00000000 0000 0100 2f000000 0200 017ba8c0 00161cf12e39 00717ba8c0 300ed559bb36`
|
||
|
||
广播的 sub=01 宣告(255.255.255.255)同样触发设备回 sub=02 注册帧。
|
||
|
||
### 3.7 AECH 认领(type=02 sub=05 → sub=06)—— 加密会话建立 ★★2026-09-10 完全破解
|
||
|
||
注册完成后主机立即发起认领(cold2.pcap,t=38.105,**连续 3 轮**,设备 **1ms** 内应答):
|
||
|
||
```
|
||
主机 → Butler: 552B type=02 sub=05 AECH 质询 (含 "AECH"=41454348 @0x28)
|
||
0x1A-0x1D 主机 IP (LE)
|
||
0x1E-0x23 主机 MAC
|
||
0x28-0x2B "AECH"
|
||
0x2C-0x87 92B 纯随机填充 (设备完全忽略!)
|
||
0x88-0x8B ★ 4B 质询 nonce (LE) — 唯一影响应答的输入!
|
||
0x8C-0x8F ★ 4B 主机实例随机 B12 (LE, 会话内不变, 会话间不同)
|
||
— 兼任 DMX 混淆基值: rot=(B12^r)&511 (§4.1)
|
||
0x90-0x123 148B 纯随机填充 (设备完全忽略!)
|
||
Butler → 主机: 552B type=02 sub=06 AERE 应答 (含 "AERE"=41455245 @0x28)
|
||
0x1A-0x1D / 0x41-0x44 设备 IP (LE, 两处)
|
||
0x1E-0x23 / 0x49-0x4E 设备 MAC (两处)
|
||
0x25-0x27 主机 IP 前3字节 (LE)
|
||
0x2C-0x2E 主机 MAC 后3字节
|
||
0xC0-0xC3 ★ 应答 = G(nonce) — 算法见下
|
||
其余 设备身份串 + RDM 灯具摘要 + 259 式信息块 (全部静态)
|
||
```
|
||
|
||
**★应答算法(源自 SymphoLight `Ecue.Devices.dll` 反编译,类 `Ecue.Devices.ENet.Protocol.AgiosElias`)**:
|
||
|
||
```
|
||
G(x) = x ^ TABLE[(x%32 + 1 + (x*13)%30) % 32] (u32 环绕乘法)
|
||
TABLE = 32×u32 常量表, 内嵌于 DLL 静态数组 (0A8F2B10..., 128B):
|
||
1008de00 e3b77ff6 31183e1c 90fb53c8 ff10ba5c 030bc4b6 e22935c8 10e8ede1
|
||
55f409a0 3eb0b9a3 f7333308 edf07810 8abf4078 60ec0545 1f4645c8 54094148
|
||
04c0f500 fabe50bb f3f3e54c 6c2a02cb a2546e60 4f6ae10e 51dfe8d8 2eedb0ec
|
||
74006928 48fade70 e5346e9c 1c3fe0bc f6700700 6b7f1ba0 a1143cf4 3be8426c
|
||
主机验证 (AgiosElias.i4GrvIBQ6xF): AERE blob[152] (= 帧 0xC0) == G(主机 nonce)
|
||
```
|
||
|
||
**无密钥、无 dongle 参与**——纯混淆级算法。黑盒探测(aechprobe/aechprobe2 子命令)实证:
|
||
仅 0x88-0x8B 影响应答(全雪崩),确定性;离线 G 对 cold2+fix1 共 10/10 样本命中;
|
||
虚拟 Butler 已实现本地计算(`aech::agios_g`),随机 nonce 测试 5/5 PASS。
|
||
**终极实测(2026-09-10 14:29)**:SymphoLight 重启后 .7 在无桥/无中继条件下完成
|
||
3 轮 AECH 本地应答 → 89B 注册 → DMX 流恢复 → RDM 灯具重新注册,全流程独立。
|
||
**认领不再依赖真机中继**(中继/桥代码保留作对比,桥已退役)。
|
||
|
||
**实测过滤行为**:真机 .1 只应答**源 IP=192.168.123.113** 的 AECH(任意源端口均可),
|
||
其他源 IP 的质询直接丢弃(这是真机固件行为;虚拟设备无需此过滤)。
|
||
|
||
认领通过后:主机开始 DMX 会话(§4),心跳 sub=03(36B,每 ~6s,**设备不应答**)。
|
||
|
||
---
|
||
|
||
## 4. 消息类型 04 —— 会话数据(连接后的主通道)
|
||
|
||
type=04 的帧在 0x20 处有 2 字节**子类型/方向标记**:
|
||
- `01 01` = 主机→设备 **DMX 通道数据**(形态 A)
|
||
- `02 00` = 事件/状态帧(形态 B,双向:主机发事件,Butler 周期回 42B 计数遥测 §4.3)
|
||
|
||
### 4.1 形态 A:DMX 通道数据帧(1126 B,主机→Butler,~30 Hz)★2026-09-10 完全解码(含混淆算法)
|
||
|
||
```
|
||
负载偏移 长度 示例 含义
|
||
0x00 4 454E6574 "ENet"
|
||
0x04 4 04000000 type=4
|
||
0x08 4 00001C7C 端口 31772
|
||
0x0C 6 000000000000 保留
|
||
0x12 2 0100 版本/标志
|
||
0x14 4 3C040000 负载长 1084
|
||
0x18 2 0100 wnor8bDK5nr u16 = 1 (DMX 数据消息)
|
||
0x1A 4 4CB20000 ★ 帧序号 aOKr8qAKOAa LE u32,逐帧 +1(高 2B 恒 0)
|
||
0x1E 2 0000 OcpmOpr u16 = 0
|
||
0x20 2 0101 cbY0uIrZR2S3QxGbNbNC × 2 (每端口 1B, 均=1)
|
||
0x22 4 6E100C2D ★ r1 = Random.Next() LE u32 (每帧每端口随机, MSB=0)
|
||
0x26 4 80681200 ★ r2 = Random.Next() LE u32 (端口2)
|
||
0x2A 2 0000 端口状态字节 × 2 (universe 状态表查得, 通常 0)
|
||
0x2C 2 0400 端口1 ID = 4 (LE, 两设备同值)
|
||
0x2E 2 0200/0300 ★ 端口2 ID = 节点序号 LE: 真机 .1=2, 虚拟 .7=3
|
||
0x30 2 0000 端口索引0 (LE)
|
||
0x32 2 0100 端口索引1 (LE)
|
||
0x34 2 0002 端口1 通道数 = 512 (LE! 00 02, 旧文档"BE"系误读)
|
||
0x36 2 0002 端口2 通道数 = 512 (LE)
|
||
0x38 2 0100 固定 (01 00)
|
||
0x3A 2 0000 固定
|
||
0x3C 512 ★ 端口1 DMX 通道 1-512 — zPprv0TXRRW 混淆 (见下, 非明文!)
|
||
0x23C 512 ★ 端口2 DMX 通道 513-1024 — 同式混淆 (用 r2)
|
||
```
|
||
|
||
**★通道数据混淆(2026-09-10 反编译+实证完全破解;旧文档"明文/保护字节/滚动值"系误判)**:
|
||
|
||
构建链(反编译 `iey7k4rDmrsMD1TvRywm::ScheduleUpdate` → `ENet2MessageCreator::QJiBkgLcunE`
|
||
→ `vpFbA8r8ibe5ncT1Lum7::CopyToBuffer`,60B 头结构逐字段与线值吻合):
|
||
|
||
```
|
||
r = Random.Next() # 每帧每端口独立, u31 (MSB 恒 0), 写入 0x22/0x26
|
||
rot = (B12 ^ r) & 511 # B12 = AECH 质询 0x8C-0x8F 实例随机 (AgiosElias.B12rvMuR8pT, 会话不变)
|
||
out[i] = src[(i+rot) % 512] ^ cnt[i] # src = 真实通道值
|
||
cnt[i] = (512-rot-i) & 255 (i < 512-rot)
|
||
= (rot-(i-(512-rot))) & 255 (i >= 512-rot)
|
||
```
|
||
|
||
接收方解密:`src[(i+rot)%512] = wire[i] ^ cnt[i]`(rot 由帧内 r 与会话 B12 重建)。
|
||
|
||
**实证**:cold2(B12=0x1e67079f)3893 帧 + fix1(B12=0x70959ecf)1781 帧全部解密为
|
||
跨帧稳定的全零场景(测试期间主机发的是 blackout),加解密回环 5674/5674 逐字节一致
|
||
(`aech::agios_dmx_encrypt`/`agios_dmx_decrypt`,`dmxdec` 子命令)。
|
||
**"保护字节 (CH-1)^K" 系涌现巧合**:src=0 时 wire[0x3C]=(512-rot)&255,代数化简得
|
||
K = ~B12 & 0xFF(cold2: ~0x9f=0x60 ✓、fix1: ~0xcf=0x30 ✓、ss123: K=0x70 → B12l=0x8f);
|
||
0.5% 失配 = rot%256==0 的边界帧。宿主侧另有 `kWarv47o79k`(新算法,
|
||
`out[i]=src[i]^((512-i)&255)^key[(512-i)&3]`, key=r^B12,CP7rDoD7VL4() 标志选择)——
|
||
Butler S2 走旧算法。
|
||
|
||
**端口映射**:工程 universe 号(U6/U2、U1/U5)**不上线**,主机按端口序拼包,Butler 解密后按
|
||
port1/port2 各 512B 直接映射到 RS485 输出。实测帧率 29.8/s(中位间隔 33ms),稳态恒定。
|
||
|
||
### 4.2 形态 B:事件/状态帧(主机→Butler,1126 B)★2026-09-10 完全解码
|
||
|
||
> 速率随主机活动模式变化:纯 DMX 播放时 A:B ≈ 1:2(dmx40s: 1207A+2336B/40s);
|
||
> RDM 激活稳态时 B ≈ 24.7/s、A 恒定 29.8/s(ss123)。旧版"A·B·B 固定节奏"
|
||
> 仅为其中一种模式。
|
||
>
|
||
> **帧构成 = [事件头 0x00-0x3B] + [标准 E1.20 RDM 消息] + [通道图案填充至 1084B]**。
|
||
> ss123 实证:RDM 激活稳态下 2963/2963 事件帧 100% 为 RDM 查询
|
||
> (cmd24×1886 + cmd18×645 + cmd19×352 + flag=01 内嵌副本×80),无非 RDM 事件帧。
|
||
|
||
```
|
||
负载偏移 长度 示例 含义
|
||
0x00-0x17 24 … 通用头 ("ENet"/type=4/端口/负载长 1084)
|
||
0x18 4 01000000 固定
|
||
0x1C 4 00000000 固定
|
||
0x20 2 0200 子类型 = 事件
|
||
0x22 4 65890000 ★ 事件序号 u32 LE,严格 +1(2962/2962 无例外)
|
||
0x26 4 00000000 固定
|
||
0x2A 4 CC000000 常量 0xCC
|
||
0x2E 2 0100 事件类标记(DMX-A 帧此位为节点序号 2/3)
|
||
0x30 1 00/01 ★ flag:00=独立查询帧(设备应答);
|
||
01=DMX 内嵌副本(设备不应答),此时 0x32=01
|
||
0x31 3 000000 固定
|
||
0x34 4 25000000 ★ RDM 消息长度 LE u32 = E1.20 msgLen+1(含 SubSC)
|
||
0x38 4 01000000 疑似 RDM 总线/端口号(LE,本样本恒 1)
|
||
0x3C … ★ 标准 E1.20 消息(免 0xCC 起始字节):
|
||
3C:SubSC=01 3D:msgLen 3E-43:destUID 44-49:srcUID
|
||
4A:TN 4B:port 4C:msgCount 4D-4E:subDevice 4F:CC
|
||
50-51:PID(BE) 52:PDL 53+:PD 末尾:checksum(BE)
|
||
… … ★ 通道图案填充:从 0x3C+RDM长 到帧尾,约 1011-1031B
|
||
```
|
||
|
||
**填充区性质(2026-09-10 实证)**:外观为 DMX 通道图案(渐变波形),但 24B
|
||
签名在本网段与跨网段 DMX-A 流中均只命中**周期性效果的自相似片段**
|
||
(时间差中位 -50s、偏移散乱)→ 与任何实时 universe 数据无系统对应,
|
||
判定为**主机缓冲复用/填充,无协议语义**。Butler 只需解析 RDM 消息即可
|
||
(虚拟 Butler 实现即如此)。
|
||
|
||
**E1.20 字段实证对齐**(逐偏移标注):
|
||
- 0x4F = Command Class:cmd24/18 → 0x10(DISCOVERY)、cmd19 → 0x20(GET)、cmd=1a → 0x30(SET)
|
||
- cmd24 → PID=0001 UNIQUE_BRANCH(PD=分支 lo/hi 12B);cmd18 → PID=0002 UN_MUTE
|
||
(PDL=0);cmd19 → PID=0201 SENSOR_VALUE(PD=传感器序号)
|
||
- RDM 长度字段实证:cmd24→37、cmd18→25、cmd19→26(= 24 头 + PDL + 1)
|
||
- flag=01 内嵌副本:srcUID 末字节 fe(独立帧为 ff)、0x4B(port)=01
|
||
|
||
### 4.3 Butler 42B 事件计数遥测帧(Butler→主机,~每 115ms 一帧)
|
||
|
||
```
|
||
0x14 2A000000 负载长 42
|
||
0x18 0200 子类型
|
||
0x1A 4275746C 设备名前缀 "Butl"
|
||
0x1E 0100
|
||
0x20 4 xxxxxxxx ★ Butler 本地"已收事件B帧"累计计数(LE, 严格递增)
|
||
0x24 6 010000000000
|
||
```
|
||
|
||
★2026-09-10 更正(ss123 实证):0x20-0x23 **不是** "被确认事件帧的序号",
|
||
而是 Butler 自己累计收到的事件B帧数(120s 内 +2959 ≈ 实收事件 2963;
|
||
相邻帧差 +1~+10,1039/1039 严格递增)。该帧以 ~8.7/s(中位间隔 35ms,
|
||
有事件才发)周期上报,与具体查询**无逐帧配对关系**——旧结论"ACK seq =
|
||
事件 seq - 1"是"计数器≈主机事件序号"的自然巧合,叠加分析脚本
|
||
PowerShell 运算符优先级 bug(`$a.seq -eq $q.seq - 1` 解析为
|
||
`($a.seq -eq $q.seq) - 1`)导致的假相关。收到非 RDM 事件B帧**不应**即时
|
||
回 42B。
|
||
|
||
### 4.4 Butler 状态帧(171 B 等,Butler→主机,周期性)
|
||
|
||
与 42B 遥测同构:`ENet` + type=04 + `0200` + `"Butl"` + `0100` + 事件计数器(0x317…) +
|
||
`0000` + 状态块(首字节 `57`=87…,尾部补零至 129 B 负载)。
|
||
观测到的状态帧长度分布:171/177-247 B(约 60 余种长度,随状态内容伸缩)。
|
||
|
||
★2026-09-09 补注(cold2.pcap):上述"状态帧"实际多为 RDM 应答帧(69-129B 负载);
|
||
认领后的稳态会话中,真机**几乎不发送任何自发状态帧**。旧虚拟 Butler 的
|
||
"每 3.5s 突发 10 帧 84B"为错误指纹。
|
||
|
||
★2026-09-10 再补(ss123):稳态下真机**确有** 42B 帧,但性质是 §4.3 的
|
||
事件计数遥测(~8.7/s,有事件才发),既非状态帧也非逐帧 ACK。cold2 的
|
||
168s 仅 1 帧是因为冷启动窗口内事件量小。
|
||
|
||
### 4.5 流量节奏(实测 40 s 窗口)
|
||
|
||
| 流量 | 包数 | 说明 |
|
||
|------|------|------|
|
||
| 主机→Butler 1126 B | 3543 | 形态A 1207 + 形态B 2336(该窗口 A:B≈1:2;稳态 RDM 窗口 A 29.8/s 恒定、B ~24.7/s) |
|
||
| Butler→主机 84 B(负载42B) | 1250 | 事件计数遥测(§4.3,非逐帧 ACK) |
|
||
| Butler→主机 状态帧 | ~700 | 各长度状态/心跳 |
|
||
| 主机→广播 1947 | 42 | 密钥报文,~1 Hz 成对 |
|
||
| 主机→广播 686 B | 13 | type=01 宣告,~3 s 间隔 |
|
||
| 主机→广播 78 B | 7 | type=02 标识心跳,~30 s 间隔 |
|
||
| 主机→广播 582 B | 6 | "EUCE" 帧,~30 s 间隔 |
|
||
|
||
## 5. RDM over e:net ★2026-09-09 完全解码(推翻旧版"私有变体"结论)
|
||
|
||
> 触发条件:SymphoLight RDM 窗口 → Butler 端口 Enable RDM → Discover;
|
||
> 认领通过后主机持续进行后台 RDM 发现/轮询(无需人工触发)。
|
||
> 旧版"e:cue 私有变体、字段序与 E1.20 不一致"结论系解析偏移错误——
|
||
> **e:net 封装的 RDM 负载就是标准 E1.20 报文**(含标准 checksum,真机 1396/1396 验证通过)。
|
||
|
||
RDM 流量全部复用 type=04 会话帧,无独立消息类型。
|
||
主机→设备的 RDM 查询帧完整布局见 **§4.2**(事件头 + 免 0xCC 起始的 E1.20 消息
|
||
@0x3C + 通道图案填充)。
|
||
|
||
### 5.1 e:net 封装(RDM 应答,Butler → 主机)
|
||
|
||
```
|
||
0x00 4 "ENet"
|
||
0x04 4 04000000 type=4
|
||
0x08 4 00001C7C 端口
|
||
0x0C 6 00…00 保留
|
||
0x12 2 0100
|
||
0x14 4 负载总长 (LE)
|
||
0x18 2 0200 子类型
|
||
0x1A 4 "Butl" (4275746C)
|
||
0x1E 2 0000 / 0100 标志
|
||
0x20 4 序号 (LE):参数应答 = 回显查询 0x22-0x23;DISC 脉冲 = 设备本地自增
|
||
0x24 4 00000000
|
||
0x28 2 ★ RDM 数据区长度 (LE) = msgLen + 2
|
||
0x2A ... ★ RDM 数据区
|
||
- 标准 E1.20 报文: CC 01 <msgLen@0x2C> ... <checksum 2B BE>
|
||
- DISC 脉冲: AA <9-bit 编码 16B> (无 CC01, 见 §5.4)
|
||
```
|
||
|
||
### 5.2 标准 E1.20 字段布局(0x2A 起)
|
||
|
||
```
|
||
0x2A CC Start Code (SC_RDM)
|
||
0x2B 01 Sub Start Code
|
||
0x2C msgLen Message Length = CC 起到最后一个 PD 字节的字节数 (不含 checksum)
|
||
0x2D 6B Dest UID = 主机 RDM 控制器 UID (实测 45:3a:7f:ff:ff:ff)
|
||
0x33 6B Src UID = 灯具 UID (应答时)
|
||
0x39 TN Transaction Number — 应答回显查询的 TN
|
||
0x3A Response Type (00=ACK)
|
||
0x3B Message Count
|
||
0x3C 2B Sub-Device (0000)
|
||
0x3E CC Command Class (0x11=DISC_RESP, 0x21=GET_RESP, 0x31=SET_RESP)
|
||
0x3F 2B PID (BE)
|
||
0x41 PDL
|
||
0x42 PD (PDL 字节)
|
||
末尾 2B Checksum = 从 CC(0x2A) 起 msgLen 字节的 16-bit 和, 大端
|
||
```
|
||
|
||
**checksum 规则(已验证 1396/1396)**:`sum16(CC..最后一个PD字节) == checksum(BE)`。
|
||
任何模板 patch(改 UID/TN/bridge-id)后**必须重算**,否则主机按 E1.20 规范丢弃。
|
||
(注意 PowerShell 陷阱:`-shl` 保持类型宽度,`[byte] -shl 8` 恒得 0,验证脚本须先转 int。)
|
||
|
||
### 5.3 主机 → Butler 的 RDM 请求(type=04,"cmd" @0x3D 实为 E1.20 msgLen)
|
||
|
||
请求帧两种形态:独立短帧(~112B 负载)与 1084B DMX 内嵌帧(0x30 flag=01)。
|
||
**实测真机只应答 flag=00 的帧**,flag=01 为 DMX 流内嵌副本,不答。
|
||
|
||
★2026-09-10 更正(SET 抓包实证):**0x3D 不是 e:net 命令字节,是 E1.20 msgLen**。
|
||
旧称 cmd=24/18/19/1a 恰为各类请求的 msgLen:0x24=36(UNIQUE_BRANCH, PDL=12)、
|
||
0x18=24(PDL=0 的 DISC/GET)、0x19=25(GET SENSOR_VALUE, PDL=1)、
|
||
0x1A=26(SET DMX_START_ADDRESS, PDL=2)。命令语义由 CC@0x4F 决定
|
||
(0x10 DISCOVERY / 0x20 GET / 0x30 SET)。下文沿用"cmd=xx"仅作 msgLen 类别简写。
|
||
|
||
```
|
||
0x20 2 子类型 0200
|
||
0x22 2 查询序号 (LE) — 应答在 0x20-0x21 回显
|
||
0x30 1 flag: 00=独立帧(应答), 01=DMX内嵌副本(不答)
|
||
0x3C 1 SubSC = 01
|
||
0x3D 1 E1.20 msgLen(非命令字节!)
|
||
0x3E 6 目标灯具 UID (发现时为分支下界, 全范围=ffffffffffff)
|
||
0x44 6 主机 RDM 控制器 UID (bridge-id, 453a7fffffff)
|
||
0x4A 1 TN (Transaction Number)
|
||
0x4F 1 Command Class: 0x10=DISCOVERY / 0x20=GET / 0x30=SET
|
||
0x50 2 ★ PID (BE)
|
||
0x52 1 PDL;0x53+ PD;末尾 checksum (BE)
|
||
```
|
||
|
||
### 5.4 DISC 脉冲(DISC_UNIQUE_BRANCH 响应)—— 编码已破解
|
||
|
||
脉冲不是标准 RDM 包,是 E1.20 发现响应的 9-bit 线路编码(17B):
|
||
|
||
```
|
||
AA 分隔符前缀
|
||
<16B: 8×2B 编码 UID> 每字节 b → byte1=0xAA|(b&0x55), byte2=0x55|(b&0xAA)
|
||
(GF(2) 仿射求解, 13 样本全过; 解码: b=(b1&0x55)|(b2&0xAA))
|
||
<4B: 2×2B 编码 checksum> checksum=16 位编码后 UID 字节的和, 先高字节后低字节
|
||
```
|
||
|
||
- 脉冲帧 e:net 序号(0x20)= **设备本地自增序号**(非回显查询!),每次 +1..3。
|
||
- 实测脉冲时延 2-48ms(中位 29ms);应答率 ~40%(967/2419,含 mute 效果)。
|
||
|
||
### 5.5 发现/验证语义(实测裁决)
|
||
|
||
| 主机查询 | 真机应答 | 说明 |
|
||
|---|---|---|
|
||
| cmd=24 全范围 UNIQUE_BRANCH (UID=ffffffffffff) | DISC 脉冲(59B 负载) | 未静音灯具应答 |
|
||
| cmd=18 PID=**0002** (DISC_UN_MUTE) | **70B 参数 ACK**: `CC=11 PID=0002 PDL=2 PD=0000` + 有效 checksum,延迟 17-29ms | ⚠️ **不是脉冲!** 虚拟 Butler 曾错答脉冲导致主机死循环重试(947 次),灯具永不注册 |
|
||
| cmd=18 PID=**0003** 广播 MUTE (UID=ffff…) | **无应答**(0/10) | 广播静音不应答;780 条 flag=01 0003 为 DMX 内嵌广播 MUTE |
|
||
| cmd=18 PID=0060 (DEVICE_INFO) | 87B,每灯具每轮 ~10 次/3min | 注册后主机每 ~1min 重读 |
|
||
| cmd=18 PID=00f0 (DMX_START_ADDRESS) | 70B | 同上节奏 |
|
||
| cmd=18 PID=0050 (SUPPORTED_PARAMETERS) | 78/178/182B | — |
|
||
| cmd=18 PID=80xx(厂商-specific 40 余个) | 69-72B,100% 应答 | 延迟 12-35ms(中位 29ms) |
|
||
|
||
**主机 RDM 流程**:后台持续全范围发现(~14-24/s)→ 对新 UID 发 UN_MUTE(0002) 验证
|
||
→ 拿到合法 ACK 后读 DEVICE_INFO(0060)/标签/参数注册进拓扑 → 每 ~1min 轮询。
|
||
**若 0002 应答非法,主机永远停在 0002 重试,不会进入参数读取阶段。**
|
||
|
||
### 5.6 SET 写路径(★2026-09-10 set123b.pcap 实证,GUI 改地址触发)
|
||
|
||
**抓取方法**:SymphoLight RDM 窗口改真机灯具 DMX 地址(NFM680S `010734880900`
|
||
111→114→111→112),双网段同抓。
|
||
|
||
**SET 请求**(主机→Butler,1084B 事件帧,flag=00):
|
||
- CC=**0x30**@0x4F、PID=00f0@0x50 (BE)、PDL=2@0x52、PD@0x53 = **DMX 地址 BE u16**
|
||
- 0x3D msgLen=26 (=24+2),0x34 RDM 长=27 (=msgLen+1)
|
||
- 完整布局与 GET 相同(§4.2/§5.3),仅 CC/PDL/PD 不同
|
||
|
||
**SET 应答**(Butler→主机,68B 负载):
|
||
- CC=**0x31**@0x3E (SET_COMMAND_RESPONSE)、RT=**00 (ACK)**@0x3A、**PDL=0**(无参数数据)
|
||
- TN 回显(查询 0x4A → 应答 0x39)、checksum 有效、延迟 18-25ms(RS485 指纹)
|
||
|
||
**主机行为**:SET 后 **+33ms 立即 GET 同一 PID 验证**(TN 连续 +1),应答中
|
||
新地址已生效;此后稳态轮询按新地址继续。三次 SET (114/111/112) 模式完全一致。
|
||
|
||
**虚拟 Butler 实现(2026-09-10 上线,GUI 改地址实测通过)**:SET (CC=0x30) 一律回
|
||
68B ACK(`rdm_setack_68.hex` 模板,TN/UID/seq/PID 回显 + checksum 重算,延迟 15-25ms),
|
||
并按 `(UID, PID) → PD` 落存 `set_store`;后续 GET 同 PID 时以存储值覆盖模板 PD 再重算
|
||
checksum。**只 ACK 不落存会被主机的 SET→GET 验证识破**(GUI 显示改地址无效)。
|
||
该机制对所有 PID 通用(地址/标签等均可写)。
|
||
|
||
**残余**:厂商 PID 0x0200 族的 SET 写路径未触发(GUI 未暴露对应操作);
|
||
IDENTIFY_DEVICE 等其他 SET PID 未专项。
|
||
|
||
---
|
||
|
||
## 6. 端口 1947 —— 密钥/许可报文
|
||
|
||
- 主机→`192.168.123.255` 与 `255.255.255.255` 成对广播,源端口 53685/53687。
|
||
- 负载恒定 40 B,ASCII Base64:
|
||
`BlZRQphAGxUbi7at8KEfmdZ7TdSB903b+qoC1RIA`
|
||
- Base64 解码 = 30 B 高熵二进制(`06 56 51 42 98 40 1B 15 1B 8B B6 AD F0 A1 1F 99 D6 7B 4D D4 81 F7 4D DB FA AA 02 D5 12 00`)。
|
||
- 长时间观察内容**不变** → 静态许可/身份令牌,非会话密钥。
|
||
- 与 OLA 社区所述 "key message" 一致。DMX 数据并不依赖其加密(见 §4.1 明文结论)。
|
||
|
||
---
|
||
|
||
## 7. 会话建立时序(★2026-09-09 以 cold2.pcap 冷启动实测更新)
|
||
|
||
```
|
||
t=0~23s 主机 Butler S2
|
||
│ 01 发现请求 180B 广播(~每3-5s) ─▶│
|
||
│◀────── 01 发现应答 217B (设备名/MAC/IP/ConnectedTo) │
|
||
t=38.087 │ 02 宣告 sub=01 102B ─────────▶│
|
||
│◀────── 02 注册 sub=02 47B (10ms) │ ★ 认领前关键步骤
|
||
t=38.105 │ 02 AECH sub=05 552B ─────────▶│
|
||
│◀────── 02 AERE sub=06 552B (1ms) │ ×3 轮 (38.105/38.111/38.140)
|
||
t=40+ │ 04 DMX帧 A(seq) ─────────────▶│
|
||
│ 04 事件帧 B ──────────────────▶│
|
||
│◀─── 04 计数遥测 42B (~115ms) ────│ … A 29.8/s 恒定 + B 随模式 …
|
||
│ 04 RDM 查询(cmd24/18) ────────▶│ 后台持续发现/轮询
|
||
│◀─────── 04 RDM 脉冲/参数应答 ────│ 延迟 12-48ms
|
||
t=44+ │ 02 心跳 sub=03 36B (每~6s) ───▶│ ★ 设备不应答
|
||
```
|
||
|
||
Butler 若 ~数秒收不到主机数据则自动回落 standalone 模式(播 SD 卡 show)。
|
||
|
||
---
|
||
|
||
## 8. ESP32 模拟可行性结论
|
||
|
||
| 需求 | 结论 |
|
||
|------|------|
|
||
| 接收 DMX 数据 | ✅ **可行**:明文。监听 UDP 31772,过滤 `454E6574 04000000` + 0x20 处 `0101`,从负载 0x3C 取 1024 B 通道数据 |
|
||
| 维持连接 | ⚠️ 需模拟:周期回复 ACK(0x2A 负载、递增序号)+ 状态帧,防止主机判定离线;同时需应答 type=01 发现(259B 应答帧格式见 §3.2) |
|
||
| 阻止 standalone 抢发 | 停止收 DMX 后设备(真 Butler)会播 SD show;ESP32 自身无此问题 |
|
||
| 1947 端口 | 无需实现(仅主机广播,设备不监听) |
|
||
| 加密 | 无需解密——通道数据明文 |
|
||
|
||
ESP32 最小实现 = **被动接收**:绑 31772 收形态A 帧、取 0x3C 起 1024 B 即得到全通道值;
|
||
要长期稳定在线再补 ACK/状态/发现应答三类模拟帧(结构均已在本文档给出)。
|
||
|
||
---
|
||
|
||
## 9. 抓包样本索引
|
||
|
||
| 文件 | 内容 |
|
||
|------|------|
|
||
| `C:\Users\tonycao\AppData\Local\Temp\opencode\discovery.pcap` | 启动/发现阶段 56 帧 |
|
||
| `C:\Users\tonycao\AppData\Local\Temp\opencode\dmx40s.pcap` | 驱动阶段 40s,5903 帧 |
|
||
| `dmx_one_hex.txt` | 1126 B DMX 帧完整 hex ×2 |
|
||
| `rdm3.pcap` | RDM 会话(Enable RDM + Discover,DUT 停发后抓取) |
|
||
| `f686.txt` | 686 B 宣告帧完整 hex |
|
||
| `cold2.pcap` ★ | **真机 .1 冷启动全程**(168.7s/19471 帧:发现→注册→AECH→RDM),2026-09-09 |
|
||
| `fix1.pcap` ★ | **虚拟 Butler .7 验证**(58 网段,P0 修复后主机读 DEVICE_INFO 全程),2026-09-09 |
|
||
| `ss123.pcap` / `ss58.pcap` ★ | **稳态双网段对比**(120s:.1 真机 vs .7 虚拟),2026-09-10 |
|
||
| `fix2.pcap` / `fix3.pcap` ★ | **P1 修复后 .7 验证**(cmd24 收敛/稳态轮询/42B 遥测),2026-09-10 |
|
||
|
||
## 10. 待确认项(低置信度字段)
|
||
|
||
- ~~0x22 处 8 B 字段~~ → **已破解**(§4.1,2026-09-10):0x22/0x26 = 两端口首通道
|
||
保护字节 `(CH-1) XOR K`(K 会话相关,三会话验证 2000/2000);残余开放:
|
||
0x23-0x25/0x27-0x29 共 6B 为会话密钥派生滚动值(标准哈希/计数器/时间戳
|
||
全部排除),破解需先还原 AECH 密钥协商;K 与 AECH 凭证字节的对应关系未考
|
||
- ~~形态 B 事件帧内部布局~~ → **已完全解码**(§4.2,2026-09-10):事件头 +
|
||
标准 E1.20 消息 @0x3C + 通道图案填充(缓冲复用,无协议语义);
|
||
事件序号 u32@0x22 严格 +1(2962/2962,旧"偶发交换/重号"为抓包顺序现象)。
|
||
残余细节:0x38 疑似总线/端口号(样本恒 1,多端口语境未验证);flag=01
|
||
内嵌副本的生成规则(srcUID 末字节 fe、port=01)
|
||
- Butler 应答帧(217B 负载)内的版本/时序参数块逐字段含义
|
||
- "EUCE" 帧内部布局(仅确认魔数与 05 版本字节)
|
||
- ~~RDM 数据区内层字段序~~ → 已完全解码,标准 E1.20(§5.2,2026-09-09)
|
||
- cmd=19/1a(SET 类,厂商 PID 0x0200 族)的请求/应答布局(§5.6)
|
||
- RDM / show 上传 / 配置写回报文:RDM 已覆盖(§5),show 上传与配置写回未触发
|
||
|
||
---
|
||
|
||
## 11. 虚拟 Butler 实现与验证(★2026-09-09)
|
||
|
||
### 11.1 已实现能力(Rust,enet-validator)
|
||
|
||
- 发现应答(217B,Connected To 动态取请求方主机 IP/MAC,网段自适应)
|
||
- 注册应答(sub=02,47B)
|
||
- **AECH 认领本地计算(2026-09-10 起)**:虚拟设备收 AECH → 取 nonce@0x88-0x8B(LE) →
|
||
本地算 `G(nonce)`(§3.7,无密钥)写入 AERE 0xC0-0xC3 → 直接应答,**无需真机中继/桥**。
|
||
(旧中继路径保留:经源 113 socket 转发真机 .1 算 AERE;非 123 网段曾需 Windows 桥。)
|
||
- RDM 生成式应答:全新 UID 灯具的 DISC 脉冲(§5.4 编码器)+ pid_map 模板参数应答
|
||
- 高速主循环:socket 读超时 2ms(原 80/100ms 时吞吐仅 ~5/s,无法支撑发现收敛)
|
||
- DMX 接收:形态 A 帧按 §4.1 布局;0x22/0x26 = 每端口随机 r,通道数据经
|
||
zPprv0TXRRW 混淆 → **已实现实时解密**(AECH 认领时取 B12=质询 0x8C-0x8F,
|
||
`agios_dmx_decrypt` 还原真实通道值后打日志;旧日志里的 "CH1-16" 递减序列
|
||
实为 blackout 全零场景的密文形态)
|
||
|
||
### 11.2 灯具注册根因与修复(P0)
|
||
|
||
**症状**:虚拟 Butler 被认领、DMX 流入、主机能发现全新 UID,但 RDM 拓扑里
|
||
.7 的总线始终 "no devices";主机只对 .7 反复发 PID=0002(947 次)从不读 DEVICE_INFO。
|
||
|
||
**根因(cold2.pcap 实证)**:
|
||
1. 虚拟 Butler 把 PID=0002(DISC_UN_MUTE)错答成 DISC 脉冲;
|
||
真机应答为 70B 参数 ACK(§5.5)。主机拿不到合法 UN_MUTE ACK → 死循环重试。
|
||
2. 所有模板应答 patch UID 后未重算 E1.20 checksum(§5.2)→ 主机按规范丢弃。
|
||
|
||
**修复**:0002 走 pid_map 70B 模板 + TN 回显(查询 0x4A → 应答 0x39)+
|
||
全部 RDM 应答 patch 后重算 checksum。
|
||
|
||
**验证结果(fix1.pcap + GUI)**:主机对 .7 的查询变为 `0002×772 + 0060×771`
|
||
(3 个新 UID 各 257 次 DEVICE_INFO,0002:0060 = 1:1 与真机模式一致),
|
||
.7 应答 checksum 777/777 有效;SymphoLight RDM 拓扑显示
|
||
**Butler S2(.7) → Port 1 (U1) — 3 devices**,灯具注册成功。
|
||
|
||
### 11.3 稳态对齐修复(P1,2026-09-10 全部落地)
|
||
|
||
**根因(ss123/ss58 双网段对比实证)**:cmd=24 是标准 DISC_UNIQUE_BRANCH
|
||
(分支范围 lo@0x53-0x58 / hi@0x59-0x5E),真机灯具只答 UID 在范围内的查询
|
||
(二分收敛);虚拟 Butler 无视范围全答 → 主机二分永不排空 → 发现洪水
|
||
51/s(真机仅 16/s)→ 稳态轮询对 .7 永不启动。
|
||
|
||
**已修复项**:
|
||
1. cmd24 分支范围过滤,仅范围内灯具各答一个脉冲(延时入队);
|
||
2. RDM 应答延迟队列:脉冲 2-40ms / 参数 15-40ms(LCG),对齐真机 RS485
|
||
延迟指纹(中位 29ms);
|
||
3. 心跳 sub=03 改静默(真机从不应答);删除 84B 突发遥测;
|
||
4. 参数应答按镜像灯具取帧池:FIXTURE_MIRROR 130→125 / 131→80900 /
|
||
132→26c9,cmd=19/1a 再按 PD[0](传感器序号)匹配;
|
||
5. 42B 改为周期遥测(§4.3):event_ctr 累计事件B帧,~115ms 上报一次,
|
||
不再即时 ACK。
|
||
|
||
**验证(fix2/fix3.pcap)**:cmd24 率 51/s → **8.5/s**(真机 15.7/s,洪水消除);
|
||
主机对 .7 启动稳态轮询:0002/0060 每灯具每周期 + **0201 SENSOR_VALUE
|
||
23/17/4 次,与镜像灯具传感器数完全一致**;脉冲 4.9/s(真机 6.2/s);
|
||
42B 遥测 6.5/s 计数严格递增(真机 8.7/s);RDM 应答 checksum 全有效。
|
||
|
||
**残余开放项(不影响注册与轮询)**:42B 精确节流规则未明(真机差值 +1~+10
|
||
不平滑);mute 状态机语义未明(真机灯具在广播 0003 后反而恢复应答,未实现
|
||
mute 亦无碍);cmd=19/1a 中 SET 类厂商 PID(0x0200 族)写路径未专项。
|
||
|
||
### 11.4 运维要点
|
||
|
||
- 模板全部 `include_str!` 编译期内嵌,改 samples/*.hex 必须重新编译部署
|
||
- 部署:分块 base64 + Invoke-SSHCommand(Set-SFTPItem 不可用);.7 用 `~/run_butler.sh` 启动
|
||
- 进程窗口:用 86400s(24h)避免反复到期退出
|
||
- ~~桥若退出,.7 认领即卡死~~ → 2026-09-10 起本地计算 G(§3.7),桥/中继不再是必需
|
||
- .200(Windows 次 IP)的 Butler 必须与 .7 错开 MAC,避免冲突
|
||
- 离线分析:`enet-validator dmxdec <tsv>` — DMX 帧 zPprv0TXRRW 解密 + 加解密回环验证
|
||
(需 TSV 含 AECH 质询以取 B12);`dmxroll <tsv>` — 滚动值/保护字节历史分析;
|
||
tshark 导出 TSV 经 PowerShell 重定向会落为 UTF-16LE(带 BOM)
|
||
|
||
### 11.5 DMX 帧解码里程碑(2026-09-10,§4.1)★混淆算法完全破解
|
||
|
||
- 60B 帧头逐字段反编译对账(`vpFbA8r8ibe5ncT1Lum7` 结构体,Pack=2):
|
||
帧序号 u32@0x1A、cbY0u×2@0x20、r1/r2@0x22/0x26、端口ID@0x2C/0x2E、
|
||
端口索引@0x30/0x32、通道数 512 LE@0x34/0x36;
|
||
- **通道数据非明文**——zPprv0TXRRW 逐帧混淆:rot=(B12^r)&511,r=Random.Next() 每帧每端口,
|
||
B12=AECH 实例随机;cold2+fix1 共 5674 帧全部解密为稳定 blackout 场景,
|
||
加解密回环 5674/5674 逐字节一致;
|
||
- 旧结论 "(CH-1)^K 保护字节/6B 滚动值/会话密钥 K" 全部证伪——K=~B12&0xFF 为
|
||
计数器结构的涌现巧合(0.5% 失配=rot%256==0 边界);滚动值=Random.Next() 本身;
|
||
- 主机侧复现要素齐备:B12 主机自选、r 随机、加解密双向实现(`dmxdec` 验证);
|
||
- 帧率 29.8/s 恒定,A:B 比例随模式变化(推翻"A·B·B 固定节奏 ~40Hz")。
|
||
|
||
### 11.6 主机侧等效播放实测(2026-09-10,档 4 首个里程碑)★
|
||
|
||
`dmxsend` 子命令实现**完整主机侧流程**(不依赖 SymphoLight):
|
||
1. sub=01 宣告 → 收 89B 注册应答 ✓
|
||
2. AECH 认领(nonce/B12 均自选随机)→ .7 本地 G 应答 `AERE[0xC0]==G(nonce)` ✓
|
||
3. 30fps 发送 zPprv0TXRRW 加密 DMX(583 帧,高识别度图案 ch1=AA/ch2=55/ch3-10=1..128/
|
||
ch101=EF/ch513=77/ch1024=33)→ **.7 实时解密日志精确还原** `CH1-16: aa550102040810204080…` ✓
|
||
|
||
全链路(认领→注册→加密→解密)闭环自证。对真机 .1 仿冒的唯一额外约束:
|
||
AECH 质询须源自 192.168.123.113(真机固件过滤,§3.7)。
|
||
|
||
### 11.7 hostdemo:真机 .1 主机侧仿真(2026-09-10 晚)★★✅ 全链路完成(RDM 发现 + DMX 控制)
|
||
|
||
`hostdemo [目标IP] [秒]` 子命令(src/hostdemo.rs)。当晚会话历经多次假设-证伪,
|
||
**最终工作配方(HOSTDEMO_MODE=slfull,2026-09-11 00:3x 灯光实测确认)**:
|
||
|
||
```
|
||
1. 发现(type=1 → 217B)
|
||
2. 认领: announce144(102B 身份帧) 单播 → 47B 注册应答 → AECH 质询 → AERE=G(nonce) ✓
|
||
(★announce144 即 ident102 同帧; 完整冷启动前奏/绑定帧/EUCE 反而无效)
|
||
3. verbatim 重放 SL 真实会话帧流(replay_merged.txt, 32540 帧/126.7s 循环):
|
||
- DMX 数据帧: 保留 SL 原帧结构, 仅替换 r1/r2 + 密文数据段
|
||
(用本会话认领的 B12 重加密呼吸图案 → Butler 解密上灯)
|
||
- RDM 请求: SL 原帧(UN_MUTE/UNIQUE_BRANCH/GET, 含 ff/fe 成对与可变偏移结构)
|
||
4. 被动解码应答: DISC 脉冲→UID, DEVICE_INFO/START_ADDRESS→DMX 地址
|
||
```
|
||
|
||
**实测结果(灯光肉眼确认呼吸)**:
|
||
- ✅ RDM 发现 3/3: `010734670125`(NFS1K2D)@101/2ch、`010734880900`(NFM680S)@123、
|
||
`0899500026c9`(HMKJ)@1/32ch(应答 15.5k 帧)
|
||
- ✅ DMX 控制: ch101/ch123/ch1 异相呼吸(fade-in 渐入)**灯光确认**
|
||
|
||
**★会话机制深层发现(本晚核心)**:
|
||
- **AECH 握手成功 ≠ 会话数据通道打通**——认领(47B/AERE 全过)后,自构造的
|
||
type=4 帧(DMX/RDM)仍被静默丢弃;而 verbatim 重放 SL 的历史会话帧立即全通
|
||
(遥测/RDM 应答恢复)→ Butler 在帧级校验某种我们尚未破解的会话一致性
|
||
- **RDM 请求帧的消息起始位置可变**(UN_MUTE@0x3A vs UNIQUE_BRANCH@0x3C,
|
||
前+len16 字段位置随之浮动 2B)——固定偏移构造的 RDM 帧必被拒;变长规则未破解
|
||
(实用绕过: 直接重放 SL 原帧)
|
||
- 1947 端口"密钥报文"实为 **40B ASCII 许可令牌**(`BlZRQphA…`,恒定值,双目标
|
||
21 帧 @200ms 每 ~34s 一轮);EUCE 实为全程每 6s 的许可信标
|
||
- 真机认领门控行为(当晚早段观察): 灯具 MUTE 态跨会话持久(SL 遗留的 mute
|
||
挡住后续 branch 查询);SymphoLight 关闭无释放帧,DMX 流直接消失
|
||
|
||
**遗留**:RDM 帧变长结构规则(破解后可用纯自构造帧完成发现,摆脱对 SL 原帧的依赖)。
|
||
|
||
**历史过程记录(假设-证伪链,供复盘)**:完整冷启动前奏(45s)/绑定帧×4/EUCE 6s 节奏/
|
||
新鲜时间戳宣告/1947 密钥/会话保持 2h 模型——均单因素排除;最终由 verbatim 重放
|
||
二分(阶段 A 无认领 vs 阶段 B 先认领)锁定"认领 + 帧级会话一致性"双条件。
|
||
|
||
---
|
||
|
||
## 12. 缺口清单与攻关路线图(2026-09-10)
|
||
|
||
### 档 1 — 核心缺口(阻塞完整复现)
|
||
|
||
| 缺口 | 位置 | 影响 |
|
||
|---|---|---|
|
||
| ~~AECH 密钥协商/凭证算法~~ | §3.7 | **已破解(2026-09-10)**:反编译 SymphoLight Ecue.Devices.dll 得 AgiosElias.G —— 无密钥公开算法,本地计算应答,10/10 样本 + 在线 5/5 验证。**同日 SymphoLight 重启无中继终极实测通过**(14:29:35,3 轮本地 G 应答 + 89B 注册 + DMX 恢复 + RDM 灯具重新注册,Windows 桥已退役)|
|
||
| ~~会话 K 派生关系~~ | §4.1 | **证伪并消解(2026-09-10)**:K 不是密钥——是 zPprv0TXRRW 计数器结构的涌现巧合,K=~B12&0xFF(cold2/fix1 精确吻合)|
|
||
| ~~DMX 帧 6B 滚动值/通道加密~~(0x22-0x29 + 0x3C/0x23C 数据区) | §4.1 | **已破解(2026-09-10)**:r=Random.Next() 每帧每端口;数据 zPprv0TXRRW 混淆,rot=(B12^r)&511;5674 帧解密+回环 100% |
|
||
| ~~形态 B 事件帧内部布局~~ | §4.2 | **已完全解码(2026-09-10)**:事件头 + 标准 E1.20 @0x3C + 通道图案填充(无协议语义);残余细节见 §10 |
|
||
|
||
### 档 2 — 写路径/配置类(从未触发过捕获)
|
||
|
||
- ~~RDM SET 写路径(DMX_START_ADDRESS)~~ → **已解码(§5.6,2026-09-10)**:
|
||
CC=0x30 请求 / CC=0x31 ACK PDL=0 应答 / SET 后 +33ms GET 验证;
|
||
残余:厂商 PID 0x0200 族 SET、IDENTIFY_DEVICE 等其他 SET PID
|
||
- **show 上传 / SD 卡 / standalone 配置写回**:协议存在性已知,报文从未捕获
|
||
- **节点序号(0x2E)分配机制**:仅从 2 个样本推断(.1=2/.7=3),注册顺序还是工程配置未验证
|
||
|
||
### 档 3 — 辅助帧细节
|
||
|
||
- **EUCE 帧**(§3.5):仅确认魔数 + 版本字节,内部布局空白
|
||
- **217B 发现应答**(§3.2):版本/时序参数块逐字段含义不全
|
||
- **1947 许可报文**(§6):静态 token 已记录,Butler 是否/如何校验未知
|
||
- 行为指纹级小问题(不影响功能):42B 遥测精确节流规则(差值 +1~+10)、形态 B 序号偶发交换/重号、RDM mute 状态机语义
|
||
|
||
### 档 4 — 主机侧仿真(协议要素齐备,首个里程碑已实测 ★§11.6)
|
||
|
||
文档主要覆盖**设备侧**(Butler 视角收/答)。主机侧全部协议要素已解码且
|
||
`dmxsend` 已实测闭环(§11.6:认领→注册→加密 DMX→对端精确解密);
|
||
剩余工作为产品化(工程解析、场景调度、RDM 主轮询、ESP32 移植)。
|
||
§8 的 ESP32 章节也只写了"消费 DMX"的被动模式。
|
||
|
||
### 建议攻关顺序
|
||
|
||
1. ~~形态 B 事件帧布局~~ —— **已完成(2026-09-10,§4.2)**;
|
||
2. ~~AECH 密钥协商~~ —— **已完成(2026-09-10,§3.7:反编译 AgiosElias,无密钥 G 算法)**;
|
||
3. ~~RDM SET 写路径~~ —— **已完成(2026-09-10,§5.6)**;
|
||
4. ~~K 派生 + 6B 滚动值 + DMX 加密~~ —— **已完成(2026-09-10,§4.1)**:反编译
|
||
ScheduleUpdate 构建链,zPprv0TXRRW 混淆完全破解(rot=(B12^r)&511),
|
||
"K" 证实为 ~B12&0xFF 涌现巧合;5674 帧解密+回环 100%,加解密双向实现;
|
||
5. 顺带修正:0x3D "cmd 字节"实为 E1.20 msgLen(§5.3 更正)。
|
||
|
||
**至此档 1 全部关闭。** 剩余开放项均为非阻塞细节(档 2/3):show 上传/SD 写回
|
||
(未捕获)、节点序号分配机制、EUCE 内部布局、42B 节流细则、mute 状态机。
|