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)
|
||||
|
||||
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)
|
||||
Ссылка в новой задаче
Block a user