143 lines
7.3 KiB
PowerShell
143 lines
7.3 KiB
PowerShell
|
|
[Console]::OutputEncoding = [Text.Encoding]::UTF8
|
|||
|
|
$ErrorActionPreference = "Stop"
|
|||
|
|
$f = "$env:TEMP\opencode\cold2.tsv"
|
|||
|
|
$lines = [IO.File]::ReadAllLines($f)
|
|||
|
|
|
|||
|
|
function H2B($hex) {
|
|||
|
|
if (-not $hex) { return $null }
|
|||
|
|
$n = $hex.Length / 2
|
|||
|
|
$b = New-Object byte[] $n
|
|||
|
|
for ($i = 0; $i -lt $n; $i++) { $b[$i] = [Convert]::ToByte($hex.Substring(2*$i, 2), 16) }
|
|||
|
|
return $b
|
|||
|
|
}
|
|||
|
|
function G16le($b, $o) { if ($b.Length -lt $o+2) { return -1 }; return $b[$o] -bor ($b[$o+1] -shl 8) }
|
|||
|
|
function G32le($b, $o) { if ($b.Length -lt $o+4) { return -1 }; return $b[$o] -bor ($b[$o+1] -shl 8) -bor ($b[$o+2] -shl 16) -bor ($b[$o+3] -shl 24) }
|
|||
|
|
function Hex($b) { return ($b | ForEach-Object { $_.ToString("x2") }) -join "" }
|
|||
|
|
function UidStr($b, $o) { if ($b.Length -lt $o+6) { return "?" }; return ($b[$o..($o+5)] | ForEach-Object { $_.ToString("x2") }) -join "" }
|
|||
|
|
|
|||
|
|
# checksum 测试: 先用已知 0002 样本验证公式
|
|||
|
|
Write-Host "=========== [0] checksum 公式自验 (0002 样本) ==========="
|
|||
|
|
$sample = H2B "454e65740400000000001c7c00000000000001004600000002004275746c0000a5000000000000001c00cc011a453a7fffffff0899500026c952000000001100020200000729"
|
|||
|
|
$msgLen = $sample[0x2C]
|
|||
|
|
$sum = 0; for ($i = 0x2A; $i -lt 0x2A + $msgLen; $i++) { $sum += $sample[$i] }
|
|||
|
|
$ckOff = 0x2A + $msgLen
|
|||
|
|
Write-Host (" msgLen={0} sum=0x{1:x4} field=0x{2:x4} -> {3}" -f $msgLen, ($sum -band 0xFFFF), (($sample[$ckOff] -shl 8) -bor $sample[$ckOff+1]), $(if (($sum -band 0xFFFF) -eq (($sample[$ckOff] -shl 8) -bor $sample[$ckOff+1])) {"OK"} else {"BAD"}))
|
|||
|
|
|
|||
|
|
# ============ A) .1->113 全帧型直方图 (type x len) ============
|
|||
|
|
Write-Host "`n=========== [A] .1→113 全帧型 (type×len) 直方图 ==========="
|
|||
|
|
$h = @{}
|
|||
|
|
foreach ($l in $lines) {
|
|||
|
|
$p = $l -split "`t"; if ($p.Count -lt 5 -or -not $p[4]) { continue }
|
|||
|
|
if ($p[1] -ne "192.168.123.1") { continue }
|
|||
|
|
$b = H2B $p[4]; if ($b.Length -lt 0x1A) { continue }
|
|||
|
|
$t = G32le $b 4
|
|||
|
|
$k = "type=$t len=$($b.Length)"
|
|||
|
|
if (-not $h.ContainsKey($k)) { $h[$k] = 0 }; $h[$k]++
|
|||
|
|
}
|
|||
|
|
$h.GetEnumerator() | Sort-Object { [int]($_.Value) } -Descending | Select-Object -First 25 | ForEach-Object { Write-Host (" {0} : {1}" -f $_.Key, $_.Value) }
|
|||
|
|
|
|||
|
|
# ============ B) type=2 帧时间线 (注册/AECH/AERE/心跳) ============
|
|||
|
|
Write-Host "`n=========== [B] type=2 帧时间线 (全程, 前 40 条) ==========="
|
|||
|
|
$shown = 0
|
|||
|
|
foreach ($l in $lines) {
|
|||
|
|
$p = $l -split "`t"; if ($p.Count -lt 5 -or -not $p[4]) { continue }
|
|||
|
|
$b = H2B $p[4]; if ($b.Length -lt 0x1A) { continue }
|
|||
|
|
if ((G32le $b 4) -ne 2) { continue }
|
|||
|
|
$sub = G16le $b 0x18
|
|||
|
|
$t = [double]$p[0]
|
|||
|
|
Write-Host (" t={0,8:F3} {1,-26} len={2,-4} sub={3}" -f $t, "$($p[1])->$($p[2])", $b.Length, $sub)
|
|||
|
|
$shown++; if ($shown -ge 40) { break }
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
# ============ C) 发现请求/应答: 180B 请求 vs 217B 应答 全文 ============
|
|||
|
|
Write-Host "`n=========== [C] 180B 发现请求 与 217B 应答 样本 ==========="
|
|||
|
|
$req180 = $null; $resp217 = $null
|
|||
|
|
foreach ($l in $lines) {
|
|||
|
|
$p = $l -split "`t"; if ($p.Count -lt 5 -or -not $p[4]) { continue }
|
|||
|
|
$b = H2B $p[4]
|
|||
|
|
if (-not $req180 -and $p[1] -eq "192.168.123.113" -and $b.Length -eq 180) { $req180 = $b }
|
|||
|
|
if (-not $resp217 -and $p[1] -eq "192.168.123.1" -and $b.Length -eq 217) { $resp217 = $b }
|
|||
|
|
if ($req180 -and $resp217) { break }
|
|||
|
|
}
|
|||
|
|
if ($req180) { Write-Host (" 请求180B: " + (Hex $req180)) }
|
|||
|
|
if ($resp217) { Write-Host (" 应答217B: " + (Hex $resp217)) }
|
|||
|
|
|
|||
|
|
# ============ D) cmd=19 / cmd=1a 查询与应答样本 ============
|
|||
|
|
Write-Host "`n=========== [D] cmd=19 / cmd=1a 样本 (各3条查询+应答) ==========="
|
|||
|
|
foreach ($wantCmd in @(0x19, 0x1a)) {
|
|||
|
|
$cnt = 0
|
|||
|
|
foreach ($l in $lines) {
|
|||
|
|
$p = $l -split "`t"; if ($p.Count -lt 5 -or -not $p[4]) { continue }
|
|||
|
|
if ($p[1] -ne "192.168.123.113" -or $p[2] -ne "192.168.123.1") { continue }
|
|||
|
|
$b = H2B $p[4]; if ($b.Length -lt 0x52 -or $b.Length -gt 2000) { continue }
|
|||
|
|
if ((G32le $b 4) -ne 4 -or $b[0x3D] -ne $wantCmd -or $b[0x30] -ne 0) { continue }
|
|||
|
|
$t = [double]$p[0]
|
|||
|
|
Write-Host (" cmd={0:x2} t={1:F3} UID={2} 查询({3}B): {4}" -f $wantCmd, $t, (UidStr $b 0x3E), $b.Length, (Hex ($b[0x20..0x2F] + $b[0x3C..([Math]::Min($b.Length-1, 0x58))])))
|
|||
|
|
$cnt++; if ($cnt -ge 3) { break }
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
# ============ E) flag=01 PID=0003 帧样本 (780条是什么) ============
|
|||
|
|
Write-Host "`n=========== [E] flag=01 PID=0003 帧样本 (前3条, 含UID) ==========="
|
|||
|
|
$cnt = 0
|
|||
|
|
foreach ($l in $lines) {
|
|||
|
|
$p = $l -split "`t"; if ($p.Count -lt 5 -or -not $p[4]) { continue }
|
|||
|
|
if ($p[1] -ne "192.168.123.113" -or $p[2] -ne "192.168.123.1") { continue }
|
|||
|
|
$b = H2B $p[4]; if ($b.Length -lt 0x52 -or $b.Length -gt 2000) { continue }
|
|||
|
|
if ((G32le $b 4) -ne 4 -or $b[0x3D] -ne 0x18 -or $b[0x30] -ne 1) { continue }
|
|||
|
|
if ($b[0x50] -ne 0 -or $b[0x51] -ne 3) { continue }
|
|||
|
|
$t = [double]$p[0]
|
|||
|
|
Write-Host (" t={0:F3} len={1} flag01 UID={2} hdr: {3}" -f $t, $b.Length, (UidStr $b 0x3E), (Hex $b[0x20..0x33]))
|
|||
|
|
$cnt++; if ($cnt -ge 3) { break }
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
# ============ F) 脉冲时延: cmd=24 查询 → 脉冲 ============
|
|||
|
|
Write-Host "`n=========== [F] cmd=24(flag=00) 查询→脉冲 时延分布 ==========="
|
|||
|
|
$discQ = New-Object System.Collections.ArrayList
|
|||
|
|
$pulses = New-Object System.Collections.ArrayList
|
|||
|
|
foreach ($l in $lines) {
|
|||
|
|
$p = $l -split "`t"; if ($p.Count -lt 5 -or -not $p[4]) { continue }
|
|||
|
|
$b = H2B $p[4]; if ($b.Length -lt 0x2E) { continue }
|
|||
|
|
$t = [double]$p[0]
|
|||
|
|
if ($p[1] -eq "192.168.123.113" -and $p[2] -eq "192.168.123.1" -and $b.Length -gt 0x44 -and $b.Length -lt 2000 -and (G32le $b 4) -eq 4 -and $b[0x3D] -eq 0x24 -and $b[0x30] -eq 0) {
|
|||
|
|
[void]$discQ.Add(@{ t=$t; lo=($b[0x3E..0x43] | ForEach-Object { $_.ToString("x2") }) -join "" })
|
|||
|
|
}
|
|||
|
|
if ($p[1] -eq "192.168.123.1" -and $b.Length -lt 200 -and $b[0x2A] -eq 0xAA) {
|
|||
|
|
[void]$pulses.Add(@{ t=$t })
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
Write-Host (" cmd24查询={0} 脉冲={1}" -f $discQ.Count, $pulses.Count)
|
|||
|
|
$lats = New-Object System.Collections.ArrayList
|
|||
|
|
foreach ($pu in $pulses) {
|
|||
|
|
# 找之前最近的查询
|
|||
|
|
$best = $null
|
|||
|
|
for ($i = $discQ.Count - 1; $i -ge 0; $i--) {
|
|||
|
|
if ($discQ[$i].t -le $pu.t) { $best = $discQ[$i]; break }
|
|||
|
|
}
|
|||
|
|
if ($best -and ($pu.t - $best.t) -lt 0.5) { [void]$lats.Add([int](($pu.t - $best.t) * 1000)) }
|
|||
|
|
}
|
|||
|
|
if ($lats.Count -gt 0) {
|
|||
|
|
$ls = $lats | Sort-Object
|
|||
|
|
Write-Host (" 脉冲时延ms: n={0} min={1} 中位={2} max={3}" -f $ls.Count, $ls[0], $ls[[int]($ls.Count/2)], $ls[-1])
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
# ============ G) cmd=24 查询负载: 分支范围 vs 全范围 ============
|
|||
|
|
Write-Host "`n=========== [G] cmd=24 查询的搜索范围分布 (UID 下界@0x3E) ==========="
|
|||
|
|
$ranges = @{}
|
|||
|
|
foreach ($q in $discQ) {
|
|||
|
|
if (-not $ranges.ContainsKey($q.lo)) { $ranges[$q.lo] = 0 }; $ranges[$q.lo]++
|
|||
|
|
}
|
|||
|
|
$ranges.GetEnumerator() | Sort-Object Value -Descending | Select-Object -First 10 | ForEach-Object { Write-Host (" 范围下界={0} : {1}" -f $_.Key, $_.Value) }
|
|||
|
|
|
|||
|
|
# ============ H) AECH/AERE 帧 (594B) 抓取 ============
|
|||
|
|
Write-Host "`n=========== [H] AECH/AERE (594B type=2) 时间点 ==========="
|
|||
|
|
foreach ($l in $lines) {
|
|||
|
|
$p = $l -split "`t"; if ($p.Count -lt 5 -or -not $p[4]) { continue }
|
|||
|
|
$b = H2B $p[4]; if ($b.Length -lt 500) { continue }
|
|||
|
|
if ((G32le $b 4) -ne 2) { continue }
|
|||
|
|
$sub = G16le $b 0x18
|
|||
|
|
$t = [double]$p[0]
|
|||
|
|
Write-Host (" t={0:F3} {1} len={2} sub={3} hasAECH={4} hasAERE={5}" -f $t, "$($p[1])->$($p[2])", $b.Length, $sub, ((Hex $b) -match "41454348"), ((Hex $b) -match "41455245"))
|
|||
|
|
}
|
|||
|
|
Write-Host "`n分析完成。"
|