Files
rt-4d/research/verify2.py
T
viktorиClaude Opus 4.8 ae36c3b729 RT-4D: реверс прошивки, русификация, кастомный UI, флешеры
- Полный RE стока V3.25 (Cortex-M4F) + FM100B: карта памяти, протокол, codeplug, UI-архитектура
- Русификация: свой CP1251-шрифт + патч рендера, перевод меню и надписей, ребренд Ru-4D V3.25
- Блюпринт переделки UI + C-тулчейн (clang thumbv7em), доказан инъекцией
- Готовые флешеры: WebSerial .html и Windows .exe со вшитой прошивкой
- Дамп SPI рации, стоковая прошивка, инструменты сборки

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-08 15:47:22 +09:00

46 строки
1.7 KiB
Python

import struct, sys, io
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
DUMP = r"C:/Users/vikto/Documents/Claude/rt-4d/radio-spi-dump.bin"
data = open(DUMP, "rb").read()
CT_BASE = 0x05C000; ZN_BASE=0x01C000
def hx(b): return " ".join(f"{x:02X}" for x in b)
def parse_bcd(bcd):
if all(b==0xFF for b in bcd): return 0
r=0
for bv in reversed(bcd):
hi=(bv>>4)&0xF; lo=bv&0xF
if hi==0xF: hi=0
if lo==0xF: lo=0
r=r*100+hi*10+lo
return r
# Scan contacts region for any non-FF records
print("CONTACTS scan (non-0xFF b0):")
cnt=0
for i in range(2048):
off = CT_BASE + i*32
d = data[off:off+32]
if all(b==0xFF for b in d): continue
name = bytes(b for b in d[0x10:0x20] if b!=0xFF).decode('gbk','ignore').strip()
dmr = parse_bcd(d[0x02:0x06])
print(f"ct{i} @0x{off:06X} b0={d[0]:02X} type(b1)={d[1]} dmr(BCD@2)={dmr} name={name!r}")
print(" raw:", hx(d))
cnt+=1
if cnt>=8: break
print("total non-FF contact records:", sum(1 for i in range(2048) if not all(b==0xFF for b in data[CT_BASE+i*32:CT_BASE+i*32+32])))
print("\nZONES:")
for i in range(256):
off=ZN_BASE+i*512
d=data[off:off+512]
if d[0]==0xFF: continue
name=bytes(b for b in d[0x04:0x14] if b!=0xFF).decode('gbk','ignore')
count=d[0]|(d[1]<<8)
print(f"zone{i} @0x{off:06X} count={count} curA={d[2]} curB={d[3]} name={name!r}")
print(" head:", hx(d[0:0x14]))
chans=[d[0x14+k*2]|(d[0x15+k*2]<<8) for k in range(min(count,30))]
print(" chans:", chans)
print(" scan@0x1A4:", hx(d[0x1A4:0x1A4+25]))
# dump any nonzero bytes between end of chan list and scan
print(" 0x194-0x1A4:", hx(d[0x194:0x1A4]))