ZABEZTUR - rekonstrukcja ROM-u z pomieszanymi liniami adresowymi/danych
Dziś w wątku temat nieco odbiegający od tego, co zwykle tutaj prezentuję - postanowiłem zająć się czymś, co męczyło mnie od dłuższego czasu...
Zacznijmy może od tego że na stronie ś.p. Jerzego Soboli, w dziale schematy, na dole strony znajdują się również dumpy różnych ROM-ów. Jeden z nich opisany jest opisany tak:
zabeztur.zip - ROM kartridża TURBO 2000 zabezpieczający przed kopiowaniem nagrane programy.
Jakiś czas temu mnie to mocno zaintrygowało. Niestety zawartość dumpa wyglądała na kompletną sieczkę - losowy, nieczytelny ciąg bajtów. Przez długi czas odkładałem temat, bo brakowało zarówno czasu, jak i sensownego pomysłu, jak się za to zabrać. Zacząłem się nawet zastanawiać, czy dump nie jest po prostu uszkodzony. Nie chciałem również zawracać głowy Jerowi taką błahostką, odkładając temat na później. Jak się okazało nie zdążyłem zapytać i już nie będę miał takiej możliwości :(
Mimo wszystko temat nie dawał mi spokoju. Wracało co jakiś czas, aż w końcu stwierdziłem, że pora spróbować jeszcze raz - tym razem bardziej metodycznie. Nie chciało mi się jednak zaczynać całkowicie od zera, więc postanowiłem wspomóc się dużym modelem językowym (padło na ChatGPT 5.4). Pomógł mi on przygotować podejście do analizy danych oraz zaproponować metody, których ręczne opracowanie zajęłoby sporo czasu.
Zakładałem, że JER poprawnie odczytał zawartość EPROM-u, ale wszystko wskazywało na to, że:
- albo EPROM był uszkodzony i dump faktycznie jest błędny,
- albo PCB miało celowo pozamieniane ścieżki.
Coraz bardziej prawdopodobne wydawało się to drugie - czyli przemieszane linie adresowe i/lub danych.
Brute force wszystkich możliwości nie wchodził w grę - to daje (8+12)! permutacji, czyli coś około 2432902008176640000 możliwości :P
Zamiast tego zastosowałem podejście etapowe.
1. Dane (D0..D7)
Na początek założyłem, że problem może dotyczyć wyłącznie permutacji bitów danych.
Przetestowałem wszystkie 8! permutacji, czyli 40320 możliwości, ale zamiast przeszukiwać wszystkie i sprawdzać "czy działa", użyłem heurystyki:
- histogram wartości bajtów
- częstość występowania typowych opcode-ów 6502 (A9, 20, 4C, 60, D0, F0 itd.)
Dobra permutacja szybko się wyróżnia - rozkład bajtów przestaje wyglądać losowo i zaczyna przypominać kod maszynowy.
2. Dolne linie adresowe (A0..A3)
Po poprawieniu danych ROM nadal był niespójny, ale już "prawie wyglądał jak 6502".
Kolejny krok to "brute force" dla A0..A3 (11880 przypadków, bo 12P4 = (12!)/(12-4)! = 12 × 11 × 10 × 9 = 11880) z oceną lokalnej składni:
- dopasowanie sekwencji typu:
A9 xx
20 xx xx
4C xx xx
8D xx xx
D0 xx
60
Na tym etapie pojawił się pierwszy "żywy" kod - nadal rozbity globalnie, ale lokalnie sensowny.
3. Środkowe linie (A4..A7)
Tutaj zaczęły pojawiać się fragmenty tekstów, więc do punktacji dodałem:
- premię za ciągi ASCII
- dopasowanie fragmentów słów (np. "TURBO", "format", "plik")
Obraz ROM-u stawał się coraz bardziej czytelny, choć napisy nadal były porozrywane.
4. Górne linie (A8..A11)
Przełomowy moment nastąpił, gdy zauważyłem, że fragmenty napisów istnieją, ale są rozdzielone między różnymi obszarami pamięci.
Przykład:
"Zly fo" ... "rmat pliku"
Czyli dane były poprawne, ale większe bloki (strony) były źle ułożone.
Na tym etapie wystarczyło brute force dla 4! = 24 wariantów i dopasowanie pełnych stringów:
- "Zly format pliku"
- "TURBO COPY"
- "dlugosc"
- itd.
Jeden wariant wyraźnie się wyróżnił - i to był właściwy kierunek.
Wynik
Po odwróceniu wszystkich permutacji:
- ROM jest w pełni poprawny
- system uruchamia się w emulatorze
- teksty i logika programu są spójne
Finalne mapowania
Dane:
CART -> EPROM 2732
-------------------------
D0 -> D1
D1 -> D0
D2 -> D5
D3 -> D4
D4 -> D7
D5 -> D6
D6 -> D2
D7 -> D3
Adresy:
CART -> EPROM 2732
-------------------------
A0 -> A2
A1 -> A10
A2 -> A11
A3 -> A9
A4 -> A3
A5 -> A8
A6 -> A7
A7 -> A6
A8 -> A5
A9 -> A4
A10 -> A0
A11 -> A1
Podsumowanie
Plik, który początkowo wyglądał jak losowy szum, koniec końców okazał się poprawnym zrzutem pamięci EPROM. Nie wiem, czy pozamieniane linie adresowe/danych miały być rodzajem zabezpieczenia, czy raczej ułatwieniem prowadzenia ścieżek na płytce drukowanej. Niestety nie widziałem oryginału, z którego JER wykonywał dump, więc mogę się jedynie domyślać.
Całość udało się odtworzyć wyłącznie na podstawie:
- analizy statystycznej danych
- struktury kodu 6502
- oraz fragmentów tekstów obecnych w ROM-ie
Początkowo zakładałem, że nie uda mi się odkryć tajemnicy tego pliku, ale w końcu udało się ją rozwiązać i przestało mnie to "męczyć", teraz mogę stwierdzić że była to fajna zagadka - zdecydowanie warta poświęconego czasu! Naprawdę cieszę się, że cała ta zabawa zakończyła się sukcesem, mimo że odkrycie zawartości wywołało u mnie raczej uśmiech na twarzy, bo po tej całej walce moim oczom ukazał się następujący obraz:

^^^ zatem z dużym prawdopodobieństwem można przyjąć, że to nie jest: "ROM kartridża TURBO 2000 zabezpieczający przed kopiowaniem nagrane programy", tylko raczej: "ROM kartridża TURBO 2000 zabezpieczony przed kopiowaniem". Zabezpieczeniem był nietypowy układ ścieżek na płytce cartridge ;) Cart z identyczną zawartością był już opisany w tym wątku, a dokładniej w tym poście: Turbo 2000 COPY <--- z tym że ten cart nie miał pozamienianych linii danych/adresowych.
Dla porządku oczywiście wrzucam link do tego, co udało się zdekodować: WZab_2T12_recovered.bin.zip
Skróty plików zgadzają się w 100% z tymi, które są udostępnione w w/w poście:
MD5 : b74515156ce99bbb658ef342a91f051f
SHA256 : 2821fec46fb1caf4ad75f0f2f5905987671df0d5d18c7f9d098d95a23ae7154b
A dla jeszcze większego porządku - aby każdy zainteresowany mógł samodzielnie zdekodować plik ze strony JER-a - dodaję skrypt w Pythonie: descramble_WZab_2T12.py, przykład użycia:
python3 descramble_WZab_2T12.py WZab_2T12_scrambled.bin -o WZab_2T12_recovered.bin
Gotowe.
Wejscie : WZab_2T12_scrambled.bin
Wyjscie : WZab_2T12_recovered.bin
Dane : (1, 0, 5, 4, 7, 6, 2, 3)
Adresy : (2, 10, 11, 9, 3, 8, 7, 6, 5, 4, 0, 1)
Skróty pliku wynikowego:
MD5 : b74515156ce99bbb658ef342a91f051f
SHA256 : 2821fec46fb1caf4ad75f0f2f5905987671df0d5d18c7f9d098d95a23ae7154b
I to chyba tyle na dziś - dobranoc wszystkim!