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>
Этот коммит содержится в:
@@ -0,0 +1,48 @@
|
||||
import struct
|
||||
|
||||
DUMP = r"C:/Users/vikto/Documents/Claude/rt-4d/radio-spi-dump.bin"
|
||||
with open(DUMP, "rb") as f:
|
||||
cal = f.read(0x1000)
|
||||
|
||||
# The header +0x02: 37 a0 38 6b and +0x06: 40 ab ... Let's test freq*100000 interpretation.
|
||||
# But RT-4D VHF band 136-174, UHF 400-480. As MHz*100000: 136MHz=13600000=0x00CF8500.
|
||||
# header bytes 37 a0 38 6b 40 ab don't look like that. Try as MHz*? Let's see 0x6b38a037? no.
|
||||
# Maybe the header tail 16 bytes [58,60,63,65,68,71,74,75,76,77,78,79,80,81,82,128] are the
|
||||
# 15-point + terminator for RX/AGC or S-meter. The last is 0x80.
|
||||
|
||||
# KEY INSIGHT: tag bytes: rec0=0x0a, rec1=0x11. In the header at 0x0c-0x0f we saw "0a 00 05 00".
|
||||
# Header +0x08: 05 00 05 00 0a 00 05 00 => (5,5,10,5). rec0 tag=0x0a=10, rec1 tag=0x11=17.
|
||||
# Let's look: maybe tag = number of active frequency points? rec0=10, but table0 rec0 has 8 distinct then flat.
|
||||
|
||||
# Re-examine: table0 rec0: 2f 2d 2d 32 33 35 37 3e | 3e repeated? no: 3e then 37 37...
|
||||
# Actually first 8 vary, last 8 are flat=0x37. rec0 tag=0x0a=10.
|
||||
# rec1 tag=0x11=17, table0 rec1 all 16 vary (55..62..61).
|
||||
# Hypothesis: tables have 16 columns = 16 frequency calibration points spanning the band.
|
||||
|
||||
# Let's just present the 6 tables clearly and label by likely meaning based on value ranges.
|
||||
base=0x20; REC=0x70
|
||||
labels_guess = ["TX_power_low? / bias","?","?","TX_power_high?","?","?"]
|
||||
for idx in [0,1]:
|
||||
off=base+idx*REC; r=cal[off:off+REC]
|
||||
print(f"REC{idx} tag=0x{r[0]:02x}({r[0]}) flag=0x{r[1]:02x}")
|
||||
for t in range(6):
|
||||
tab=list(r[0x10+t*16:0x10+t*16+16])
|
||||
rng=f"min={min(tab)} max={max(tab)}"
|
||||
print(f" t{t} +0x{0x10+t*16:02x}: {tab} {rng}")
|
||||
print()
|
||||
|
||||
# Check equality relationships between tables within rec1
|
||||
r=cal[base+REC:base+2*REC]
|
||||
t=[list(r[0x10+k*16:0x10+k*16+16]) for k in range(6)]
|
||||
print("rec1 t3==t5?", t[3]==t[5])
|
||||
r0=cal[base:base+REC]
|
||||
t0=[list(r0[0x10+k*16:0x10+k*16+16]) for k in range(6)]
|
||||
print("rec0 t3==t5?", t0[3]==t0[5])
|
||||
print("rec0 t0 first8 vary, last8:", t0[0][8:])
|
||||
|
||||
# Reference const 12 e2 34 40 2a 4f b3 : could be a float? 40 34 e2 12 as BE float:
|
||||
import struct as s
|
||||
be = s.unpack(">f", bytes([0x40,0x34,0xe2,0x12]))[0]
|
||||
le = s.unpack("<f", bytes([0x12,0xe2,0x34,0x40]))[0]
|
||||
print("const first4 as float BE:", be, "LE:", le)
|
||||
# 2a 4f b3 remaining
|
||||
Ссылка в новой задаче
Block a user