fix: variable-offset theory falsified (fixed layout @0x3C/0x34/0x30 confirmed); single-frame verbatim rejected outside stream context 鈥?gating is stream-level
This commit is contained in:
parent
a4a3ed916f
commit
b644bdae79
|
|
@ -677,15 +677,20 @@ AECH 质询须源自 192.168.123.113(真机固件过滤,§3.7)。
|
|||
- **AECH 握手成功 ≠ 会话数据通道打通**——认领(47B/AERE 全过)后,自构造的
|
||||
type=4 帧(DMX/RDM)仍被静默丢弃;而 verbatim 重放 SL 的历史会话帧立即全通
|
||||
(遥测/RDM 应答恢复)→ Butler 在帧级校验某种我们尚未破解的会话一致性
|
||||
- **RDM 请求帧的消息起始位置可变**(UN_MUTE@0x3A vs UNIQUE_BRANCH@0x3C,
|
||||
前+len16 字段位置随之浮动 2B)——固定偏移构造的 RDM 帧必被拒;变长规则未破解
|
||||
(实用绕过: 直接重放 SL 原帧)
|
||||
- **~~RDM 请求帧消息起始位置可变~~(09-11 更正:解析错误,实为固定)**:
|
||||
深夜复核证实所有 RDM 请求帧布局恒定——SubSC/msgLen@0x3C、len16(msgLen+1)@0x34、
|
||||
flag@0x30(00 独立/01 副本,配对 srcUID 末字节 ff/fe,UN_MUTE 同样成对)、
|
||||
counter@0x1A、qseq@0x22、TN@0x4A。此前"0x3A vs 0x3C 变长"系手工解析错位
|
||||
- **★单帧 verbatim 在流外仍被拒**(slbisect 突变实验:SL 原版 GET→NFS 帧单独
|
||||
发送 → 零应答;同一帧在完整流重放中 → 正常应答)→ **门控在会话流上下文**
|
||||
(疑似流级防重放指纹/状态机,具体算法未破解)——实用方案即完整流重放
|
||||
- 1947 端口"密钥报文"实为 **40B ASCII 许可令牌**(`BlZRQphA…`,恒定值,双目标
|
||||
21 帧 @200ms 每 ~34s 一轮);EUCE 实为全程每 6s 的许可信标
|
||||
- 真机认领门控行为(当晚早段观察): 灯具 MUTE 态跨会话持久(SL 遗留的 mute
|
||||
挡住后续 branch 查询);SymphoLight 关闭无释放帧,DMX 流直接消失
|
||||
|
||||
**遗留**:RDM 帧变长结构规则(破解后可用纯自构造帧完成发现,摆脱对 SL 原帧的依赖)。
|
||||
**遗留**:会话流上下文门控的具体算法(破解后可用纯自构造帧完成发现,摆脱对
|
||||
SL 原帧重放的依赖——当前 slfull 重放方案已可复现全部功能,不影响使用)。
|
||||
|
||||
**历史过程记录(假设-证伪链,供复盘)**:完整冷启动前奏(45s)/绑定帧×4/EUCE 6s 节奏/
|
||||
新鲜时间戳宣告/1947 密钥/会话保持 2h 模型——均单因素排除;最终由 verbatim 重放
|
||||
|
|
|
|||
113
src/hostdemo.rs
113
src/hostdemo.rs
|
|
@ -594,6 +594,119 @@ pub fn run(target: &str, bind_ip: &str, secs: u64) {
|
|||
return;
|
||||
}
|
||||
|
||||
// slbisect: SL 原帧逐字段突变 — 定位 Butler 拒收我们 RDM 帧的确切字段
|
||||
// 突变序列: verbatim(对照) → counter → TN → qseq → 全部 → 纯我们构造
|
||||
if std::env::var("HOSTDEMO_MODE").unwrap_or_default() == "slbisect" {
|
||||
// 认领
|
||||
let o2: Vec<u8> = bind_ip.split('.').map(|x| x.parse().unwrap()).collect();
|
||||
sock.send_to(&load_template("announce144"), &dst).unwrap();
|
||||
std::thread::sleep(Duration::from_millis(300));
|
||||
let nonce = rng.next();
|
||||
let bc = rng.next();
|
||||
let mut ch = load_template("claim_h112");
|
||||
ch[0x1A..0x1E].copy_from_slice(&[o2[3], o2[2], o2[1], o2[0]]);
|
||||
ch[0x88..0x8C].copy_from_slice(&nonce.to_le_bytes());
|
||||
ch[0x8C..0x90].copy_from_slice(&bc.to_le_bytes());
|
||||
sock.send_to(&ch, &dst).unwrap();
|
||||
std::thread::sleep(Duration::from_millis(500));
|
||||
println!("[B] 认领完成 B12=0x{:08x}", bc);
|
||||
// verbatim DMX 背景流 + 突变 branch 查询
|
||||
let path = std::env::var("REPLAY_FILE")
|
||||
.unwrap_or_else(|_| "C:/Users/tonycao/AppData/Local/Temp/opencode/replay_frames.txt".into());
|
||||
let data = std::fs::read_to_string(&path).expect("replay file");
|
||||
let mut dmxf: Vec<Vec<u8>> = Vec::new();
|
||||
for line in data.lines() {
|
||||
let p: Vec<&str> = line.split('|').collect();
|
||||
if p.len() < 4 { continue; }
|
||||
let hex = p[3];
|
||||
if hex.len() != 1084 * 2 { continue; }
|
||||
let byte = |o: usize| u8::from_str_radix(&hex[o * 2..o * 2 + 2], 16).unwrap();
|
||||
if byte(0x18) == 1 && byte(0x20) == 1 && byte(0x21) == 1 && byte(0x3c) != 1 {
|
||||
let mut fb = Vec::new();
|
||||
for i in (0..hex.len()).step_by(2) { fb.push(u8::from_str_radix(&hex[i..i + 2], 16).unwrap()); }
|
||||
dmxf.push(fb);
|
||||
}
|
||||
}
|
||||
let sl_branch = std::fs::read_to_string("C:/Users/tonycao/AppData/Local/Temp/opencode/sl_branch_exact.hex")
|
||||
.unwrap_or_else(|_| String::new());
|
||||
let mut slb: Vec<u8> = Vec::new();
|
||||
{
|
||||
let h = sl_branch.trim();
|
||||
for i in (0..h.len()).step_by(2) { slb.push(u8::from_str_radix(&h[i..i + 2], 16).unwrap()); }
|
||||
}
|
||||
// NFS1K2D GET DEVICE_INFO 探针 (被 MUTE 的设备也须应答 GET — 应答可观测)
|
||||
let sl_get = std::fs::read_to_string("C:/Users/tonycao/AppData/Local/Temp/opencode/sl_get_exact.hex")
|
||||
.unwrap_or_default();
|
||||
let mut slg: Vec<u8> = Vec::new();
|
||||
{
|
||||
let h = sl_get.trim();
|
||||
for i in (0..h.len()).step_by(2) { slg.push(u8::from_str_radix(&h[i..i + 2], 16).unwrap()); }
|
||||
}
|
||||
let known: [[u8; 6]; 3] = [
|
||||
[0x01, 0x07, 0x34, 0x67, 0x01, 0x25],
|
||||
[0x01, 0x07, 0x34, 0x88, 0x09, 0x00],
|
||||
[0x08, 0x99, 0x50, 0x00, 0x26, 0xc9],
|
||||
];
|
||||
println!("[B] 开始突变序列 (GET→NFS; 每步 1s DMX 背景 + 发送 + 500ms 侦听)");
|
||||
let mut di = 0usize;
|
||||
let mutations = ["verbatim对照", "counter=ours", "TN=ours", "qseq=ours", "全突变"];
|
||||
for round in 0..2 {
|
||||
for (mi, mname) in mutations.iter().enumerate() {
|
||||
let seg = Instant::now();
|
||||
while seg.elapsed() < Duration::from_millis(1000) {
|
||||
let f = &dmxf[di % dmxf.len()];
|
||||
di += 1;
|
||||
let _ = sock.send_to(f, &dst);
|
||||
if di % 30 == 0 { let _ = sock.send_to(&load_template("heartbeat"), &dst); }
|
||||
std::thread::sleep(Duration::from_millis(33));
|
||||
while sock.recv_from(&mut buf).is_ok() {}
|
||||
}
|
||||
let mut f = slg.clone();
|
||||
let ctr = (di as u32).wrapping_add(9000);
|
||||
match mi {
|
||||
1 => { f[0x1A..0x1E].copy_from_slice(&ctr.to_le_bytes()); }
|
||||
2 => { f[0x4A] = 0x77; }
|
||||
3 => { f[0x22] = 0x55; f[0x23] = 0x00; }
|
||||
4 => {
|
||||
f[0x1A..0x1E].copy_from_slice(&ctr.to_le_bytes());
|
||||
f[0x4A] = 0x78;
|
||||
f[0x22] = 0x56; f[0x23] = 0x00;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
let _ = sock.send_to(&f, &dst);
|
||||
let mut f2 = f.clone();
|
||||
f2[0x30] = 0x01;
|
||||
f2[0x49] = f2[0x49].wrapping_sub(1);
|
||||
let _ = sock.send_to(&f2, &dst);
|
||||
let mut info = false;
|
||||
let mut any = 0usize;
|
||||
let w = Instant::now();
|
||||
// ★边发 DMX 边侦听 (Butler 仅在 DMX 流持续时吐应答, 停流即饿死)
|
||||
while w.elapsed() < Duration::from_millis(500) {
|
||||
let f = &dmxf[di % dmxf.len()];
|
||||
di += 1;
|
||||
let _ = sock.send_to(f, &dst);
|
||||
if di % 30 == 0 { let _ = sock.send_to(&load_template("heartbeat"), &dst); }
|
||||
while let Ok((n, src)) = sock.recv_from(&mut buf) {
|
||||
if src.ip().to_string() != target { continue; }
|
||||
let b = &buf[..n];
|
||||
any += 1;
|
||||
if let Some((false, d)) = rdm_region(b) {
|
||||
if d.len() >= 0x18 + 19 && d[0] == 0xCC && d[0x15..0x17] == [0x00, 0x60] {
|
||||
info = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
std::thread::sleep(Duration::from_millis(33));
|
||||
}
|
||||
println!(" [B] r{} {:<14} → 收帧 {} DEVICE_INFO={}", round, mname, any, info);
|
||||
}
|
||||
}
|
||||
let _ = known;
|
||||
return;
|
||||
}
|
||||
|
||||
let mut b12 = rng.next();
|
||||
let mut claim_ok = false;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user