Files
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

49 строки
1.8 KiB
Python

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)
REC = 0x70 # 112
# marker pair at rec+0x02..0x0f (0x22 within a record starting at 0x20). Let's define records start at 0x20?
# But 0x00..0x1f is a header. Actually let's test both: if records start at 0, marker would be at 0x22 within rec0 -> offset 0x22.
# If records start at 0x20, then rec starts 0x20, marker at rec+0x02.
# Let's align records to start where the marker pair begins minus 2.
# positions of the FIRST marker of each pair: 0x22, 0x92, 0x102 ... step 0x70. So record_base = 0x22-0x02 = 0x20.
# Header region 0x00..0x1f (32 bytes).
hdr = cal[0:0x20]
print("HEADER 0x00-0x1f:")
print(" ".join(f"{b:02x}" for b in hdr))
print()
# number of records that fit: (0x1000-0x20)/0x70
base = 0x20
nrec = (0x1000 - base)//REC
print("records fit:", nrec, "leftover:", (0x1000-base) - nrec*REC)
# How many are non-zero (populated)?
def dump_rec(idx):
off = base + idx*REC
r = cal[off:off+REC]
print(f"--- record {idx} @ 0x{off:03x} ---")
for i in range(0, REC, 16):
row = r[i:i+16]
hexs = " ".join(f"{b:02x}" for b in row)
asc = "".join(chr(b) if 32<=b<127 else "." for b in row)
print(f" +{i:02x} {hexs} {asc}")
# Show all record byte0 (first byte) which seems to be an index/counter: 0a,11,00,00,...
print("\nrecord first bytes (offset +0x00) and +0x01:")
for idx in range(nrec):
off = base+idx*REC
print(f" rec{idx:2d} @0x{off:03x}: b0={cal[off]:02x} b1={cal[off+1]:02x}")
# detect last populated record (non all-zero)
last = -1
for idx in range(nrec):
off = base+idx*REC
if any(b!=0 for b in cal[off:off+REC]):
last = idx
print("last populated record index:", last)