Загрузчик ловится/держится на Linux (catch link-check + SetBaudRate смена бода). Но read-команды флеша нет (0x03/08/09/0a/0b не дают флеш; 0x08 = битовая карта). Сходится с DMR Upgrade Tool (только erase/write). Дамп только физически (SPI-клипса). Но BK4819 найден -> TX-фикс без дампа. tools/bk_module_dump.py, bk_bootloader_catch.py, bk_read_probe.py. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NikMGoqQWWk9wy2ww2vJAr
66 строки
3.6 KiB
Python
66 строки
3.6 KiB
Python
#!/usr/bin/env python3
|
|
"""Поймать загрузчик модуля (HKLFBOOT) — ТАЙТОВЫЙ спам Connect (как DMR Upgrade Tool).
|
|
|
|
DMR Upgrade Tool: жмёшь Upgrade (спам Connect=01 E0 FC 01 00), затем MENU+включение —
|
|
загрузчик ловит connect в окне до старта приложения. Наш powershell-цикл со Start-Sleep был
|
|
слишком медленный и промахивался. Здесь — спам БЕЗ пауз (тысячи/сек), ловит короткое окно.
|
|
|
|
Процедура: запусти тул, затем зажми MENU и включи рацию. Успех = ответ загрузчика на link-check
|
|
(04 0E 05 ...) и приложение (0x68 06 02) НЕ стартует. Только connect — ни erase, ни write.
|
|
"""
|
|
import argparse, subprocess
|
|
|
|
PS = r'''
|
|
$p = New-Object System.IO.Ports.SerialPort "{port}",115200,"None",8,"one"
|
|
$p.ReadTimeout=1; $p.WriteTimeout=50; $p.ReadBufferSize=8192
|
|
try {{ $p.Open() }} catch {{ Write-Output "ERR:$($_.Exception.Message)"; exit }}
|
|
$lc=[byte[]]@(1,224,252,1,0)
|
|
$sw=[Diagnostics.Stopwatch]::StartNew()
|
|
$acc=New-Object System.Collections.Generic.List[byte]
|
|
$caught=$false
|
|
while($sw.Elapsed.TotalSeconds -lt {sec}){{
|
|
if(-not $caught){{ try {{ $p.Write($lc,0,$lc.Length) }} catch {{}} }}
|
|
$n=$p.BytesToRead
|
|
if($n -gt 0){{
|
|
$b=New-Object byte[] $n; $p.Read($b,0,$n)|Out-Null
|
|
foreach($x in $b){{ $acc.Add($x) }}
|
|
$hex=($b|ForEach-Object{{"{{0:x2}}"-f $_}}) -join ""
|
|
Write-Output ("t"+[int]$sw.Elapsed.TotalSeconds+"|"+$hex)
|
|
# ответ загрузчика на link-check: 04 0e 05 ...
|
|
if($hex -match "040e05"){{ Write-Output "CAUGHT"; $caught=$true }}
|
|
}}
|
|
}}
|
|
$p.Close(); Write-Output "END"
|
|
'''
|
|
|
|
def main():
|
|
ap=argparse.ArgumentParser()
|
|
ap.add_argument("--port", default="COM4"); ap.add_argument("--sec", type=int, default=30)
|
|
a=ap.parse_args()
|
|
print(f"[ТАЙТОВЫЙ спам 01 e0 fc 01 00 на {a.port}, {a.sec}с]")
|
|
print(">>> ЗАЖМИ MENU и включи рацию СЕЙЧАС (как при прошивке модуля) <<<\n")
|
|
r=subprocess.run(["powershell.exe","-NoProfile","-Command",PS.format(port=a.port,sec=a.sec)],
|
|
capture_output=True, text=True)
|
|
banner=app=caught=False; n=0
|
|
for line in r.stdout.replace("\r","").split("\n"):
|
|
line=line.strip()
|
|
if line.startswith("ERR:"): print(line); return
|
|
if line=="CAUGHT": caught=True; continue
|
|
if "|" not in line: continue
|
|
t,hexs=line.split("|",1); n+=1
|
|
try: asc=bytes.fromhex(hexs).decode("latin1")
|
|
except: asc=""
|
|
asc="".join(c if 32<=ord(c)<127 else "." for c in asc)
|
|
print(f" {t}: {asc[:48]} [{hexs[:40]}]")
|
|
if "HKLF" in asc: banner=True
|
|
if "680602" in hexs: app=True
|
|
print()
|
|
if caught: print("✅✅✅ ЗАГРУЗЧИК ПОЙМАН (ответ 04 0e 05)! Держим сессию — можно читать флеш.")
|
|
elif banner and app: print("⚠️ Баннер+приложение стартовало. Окно ещё промахнули — повтори (спам уже без пауз).")
|
|
elif banner: print("✅ Баннер был, приложение не стартовало — возможно, поймали. Проверю ответ.")
|
|
elif not n: print("Тишина — не попал во включение? Порт COM4? Повтори.")
|
|
else: print("Данные без баннера — перезагрузка вне окна. Повтори.")
|
|
|
|
if __name__=="__main__":
|
|
main()
|