
Alıntı Yap1. Disk yapısını çözmek
ADF'nin 160 track'i var (her biri 5632 bayt). Dolu olanlar 0–101, 102–159 boş. Bootblock'u (track 0) disassemble edince şu zinciri gördüm:
- Bootblock, track 0'ı
$20000'a yükleyip içindeki küçük ByteKiller tarzı decruncher'ı ($20100) çalıştırıyor.- Bununla açılan ikinci aşama (stage 1) da track 1'deki paketi
$C0adresine açıyor. Ben buna "kabuk" diyorum: PRODOS ekranı, yükleyici, kopya kontrolü hep bunun içinde.- Kabuk sırayla şunları yüklüyor:
Decruncher'ı Python'a taşıdım. INFO, INTRO ve final bloğu doğrudan açıldı.
[th]Blok[/th]
[th]Track'ler[/th]
[th]Boyut (açılmış)[/th]INFO 2– 201.746 bayt INTRO 16– 290.576 bayt GAME 50–95 399.556 bayt Final ekranı 96– 46.768 bayt
2. Koruma nerede
Kabuktaki "BU OYUN ORIJINAL DEGILDIR" mesajının çağrıldığı yer$CD4. Oraya giden rutin$BF6: kafayı bir track'e götürüp üç kez okuyor.$D72'deki arama kodu hedef olarak$A4 = 164(yarım adım) kullanıyor, yani silindir 82. Bu, UAE'de sizin gördüğünüzle uyumlu. Silindir 82, ADF'nin 0–159 numaralamasının dışında kalıyor.
Düzeltme: Üç okumanın ikisi özel sync ($B529), biri standart sync ($4489) kullanıyor. "Üçü de özel sync" demiştim, yanlıştı.
Üç okumanın sonucu karşılaştırılıyor ve uyuşmazsa kopya mesajıyla takılıyor. Uyuşursa okunan veriden 16 bitlik bir değer çıkıp$D70'e yazılıyor. Bu değer GAME bloğunun ilk$1600baytının şifresini çözen anahtarın parçası.
İkinci bir koruma daha var: sayı soran, "ŞİFRE:" isteyen bir kontrol. Girilen değer anahtara bir bayt ekliyor.
3. Anahtarı bulmak
Silindir 82'yi okuyamadığım için anahtarı doğrudan hesaplayamadım. Onun yerine tahmin ettim:Bunun kesin kanıtı yok; dayanağım benzersiz çıkması ve çıktının geçerli kod olması.
- GAME'in ilk
$1600baytı, 16 bitlik bir anahtarla 2'şer bayt XOR'lanmış.- 65.536 anahtarı denedim. Çözülmüş başlıkta paket/açılmış boyut mantıklı çıkan ve tam decrunch'ı hatasız biten anahtar tek bir tane çıktı:
0x874B.- Çözülen 399.556 baytlık oyunun başı gerçek 68000 koduna benziyor (
bsr,move.w #1, ...).
4. Yama
Bootblock'taki "ACE ACE..." dolgu alanını kullandım ($20074). Ayrıcajmp $C0'ın adres operandını kancama yönlendirdim. Kanca, kabuk açıldıktan sonra üç yerde RAM'de yama yapıp$C0'a atlıyor:Sonra bootblock checksum'ını yeniden hesapladım. Kickstart bunu kontrol ediyor.
$304:bsr.w $BF6(silindir 82 kontrolü) → 2 adet NOP.$33C: şifre sorma kısmı atlanıyor.moveq #0,d0,move.w #$874B,d1vebra.s $3B2. Şifre çözme döngüsü artık sabit anahtarla çalışıyor.$3D0: ekran satırını 3 geri çeken komut → NOP. Bu sadece görünüm düzeltmesi.
Düzeltme: "Disk verisine dokunmadım" dedim, ama 91 bayt değişti: hepsi bootblock'ta (yama + checksum). INFO, INTRO, GAME ve final blokları birebir aynı.
5. Neyi doğruladım, neyi doğrulamadım
Doğruladım (Unicorn ile 68000 CPU emülasyonu):Doğrulamadım:
- Bootblock'un kancayı çalıştırıp kabuğa üç yamayı RAM'de bire bir beklenen şekilde uyguladığını.
- Yamalı kodun GAME'in ilk
$1600baytını benim bulduğum anahtarla doğru çözdüğünü.- Kabuğun kendi decruncher'ının, yamalı akıştan benim Python çıktımla bire bir aynı 399.556 baytı ürettiğini.
İlk denemeniz için WinUAE'de A500/OCS ve 512 KB chip RAM önerim. Bir yerde takılırsa ekranda ne yazdığını veya ne olduğunu bana yazın.
- Gerçek Amiga donanımı veya WinUAE/FS-UAE: DMA, copper, ses, Kickstart'ın önyüklemesi bu emülasyonda yok. Oyunun sonuna kadar oynandığını da bilmiyorum.
- Gotek'te çalıştığını.
- Oyunun başka yerlerde (oyun içinde, seviye geçişlerinde) ek bir kontrol yapıp yapmadığını. Açılmış GAME, INTRO, INFO ve final bloklarında
$D70,$18AEgibi koruma değişkenlerine referans aramadım sayılır. Sadece belirli adres kalıplarını taradım ve bulamadım, ama bu kesin kanıt değil.
Sayfa 0.020 saniyede 14 sorgu ile oluşturuldu.