Modder, GBA çökme sesinden oyun ROM’unu geri yükledi
(arstechnica.com)- TheZZAZZGlitch, Game Boy Advance çökme sesini kaydederek kartuş içindeki oyun verilerinin tanımlanabileceğini ve sonunda aynı ROM’un geri yüklenebileceğini gösterdi
- Temel nokta, çökmeden sonra çıkan sesi ROM verisi olarak yorumlamak; ancak kaynak biçimlerine göre çok fazla ayar gerektiği için bunu genel amaçlı bir dump aracı olarak kullanmak zor
- 4 saati aşan kaydın yaklaşık 1 saat 50 dakika noktasında karakteristik bir dalga biçimi ortaya çıktı; ardından oyunun enstrüman sesleri ve ses örnekleri sırayla duyuldu
- Python betiği ve hizalama düzeltmesiyle %99,76 doğruluğa ulaşıldı, ancak boot başarısız oldu; 3 kayıt çoğunluk oyu algoritmasıyla birleştirilince doğruluk %99,979’a yükseldi
- 7 kaydın birleştirilmesi ve boş alanların filtrelenmesinin ardından %100 eşleşme sağlandı; yalnızca çökme sesiyle GBA ROM’unun geri yüklenebileceğine dair deneysel olasılık doğrulandı
Çökme sesinden ROM verisi okuma deneyi
- TheZZAZZGlitch, GBA’nın yazılım çökmesinden sonra çıkardığı seste oyun verilerinin bulunabileceğini gösterdi
- Çöken bir GBA, kartuş içindeki verilere dayalı ses üretmeyi sürdürebilir; özel donanım ve kodla bu ses analiz edilirse hangi oyun olduğu belirlenebilir
- Ancak bu yöntem, kartuş verilerini kolayca dump etmenin bir yolu değil ve hemen kullanılabilecek bir çözüm de değil
- Farklı kaynak biçimlerine göre çok sayıda ince ayar gerekiyor
Uzun kayıtta ortaya çıkan dalga biçimi
- GBA çökertildikten sonra 4 saatten fazla kayıt alındığında, yaklaşık 1 saat 50 dakika noktasında karakteristik bir dalga biçimi belirdi
- Sonraki bölümlerde oyunda yer alan gerçek enstrüman sesleri ve ses örnekleri sırayla duyuldu
- Verinin geri kalanı 13.100Hz’lik 8 bit veri gibi duyuluyor; bazı bölümler ise oldukça tuhaf geliyor
Python betiği ve ilk geri yükleme denemesi
- TheZZAZZGlitch, “2 gün boyunca bug düzelttikten sonra” temiz bir GBA çökme dump kaydını okuyabilen bir Python betiği hazırladı
- ROM verilerinde büyük 0 baytlık bölümler bulunuyor; bu kısımlar sessizlik gibi göründüğü için sesten ayrıştırılması zor
- Orijinal ROM içindeki konumlara göre bölümleri yeniden hizalayan ayrı bir betik çalıştırıldıktan sonra, geri yüklenen ROM %99,76 doğruluğa ulaştı
- Bu ROM hâlâ boot etmedi ve bilinen ROM verilerini kullanarak bilinmeyen verileri ortaya çıkardığı için teknik olarak “hile” sayılıyor
- Tamamen kör ilerlenmesi durumunda bile uygulanabilecek bazı varsayımlar ve çıkarımlar mevcut
Birden çok kaydı birleştirerek doğruluğu artırma
- Sonraki aşamada kayıt kalitesini iyileştirmeye odaklanıldı
- 3 kez yapılan kayıtların sonucu “çoğunluk oyu” algoritmasıyla birleştirilince doğruluk %99,979’a çıktı
- Bu çıktı ROM boot etmeyi başardı, ancak metinler bozuldu ve başlık ekranında çökme yaşandı
- Daha sonra 7 kayıt birleştirilip boş alanlar filtrelenince %100 eşleşme elde edildi
Fiziksel donanım ve ek deneyler
- Videonun ikinci yarısında bu yöntemin fiziksel donanımda nasıl çalıştığı da doğrulandı
- Başka oyunlarda da deneyler yapıldı; klon kartuş içindeki ARM koduyla ilgili gizem de ayrıca takip edildi
- Daha iyi kayıt elde etmenin yolları da denendi
- Bunlardan biri, sesi tek kanala kaba şekilde mixdown yapan “cursed adapter” kullanımıydı
1 yorum
Hacker News yorumları
Uzun süre devam eden
0x00dizilerindeki sorun, clock recovery ile ilgilidirBazı dijital veri akışları, özellikle disk sürücüsü manyetik kafalarından gelen ham veriler ya da Ethernet gibi yüksek hızlı seri iletişimler, ayrı bir clock sinyali olmadan iletilir
Alıcı, yaklaşık bir frekans referansından bir clock üretir ve faz kilitlemeli döngü (PLL) ile clock fazını veri akışındaki geçişlere hizalar
Bunun çalışabilmesi için, PLL osilatöründeki kaymayı düzeltecek kadar veri geçişinin yeterince sık gelmesi gerekir; geçiş olmadan ne kadar süre dayanılabildiğine maksimum ardışık aynı rakam (CID) spesifikasyonu denir
https://en.wikipedia.org/wiki/Clock_recovery
Daha sonra 64/66b gibi, büyük bit bloklarına kısa bir başlık ekleyerek clock geçişlerini garanti eden ve tamamını sözde rastgele bir scrambler'dan geçiren yöntemlere geçildi
Clock kusursuz biçimde senkronize olsa bile, uzun bir aralıkta neredeyse tamamen 1 olan sinyal ile neredeyse tamamen 0 olan sinyal sonunda ayırt edilemez hale gelir
Ses analogdur ve bir bit akışı olarak decode etmek için DAC gerekir; ayrıca 44.1kHz veya 48kHz gibi sabit bir frekansta, özel bir senkronizasyon olmadan iletilir
https://en.wikipedia.org/wiki/Wireless_Set_Number_10
Yaklaşık 20 yıl önce, 4. nesil iPod firmware'inin piezo hoparlör ile dump edildiği orijinal iPodLinux hack'i aklıma geldi
https://web.archive.org/web/20140810083116/http://www.newscientist.com/article/dn7085
Tesadüfen bu sayede iPod'da GBA oyunları da çalıştırılabiliyordu, ama click wheel ile Doom oynamak ve siyah-beyaz video izlemek bile fazlasıyla tatmin ediciydi
Hâlâ bir iPod Classic'im var; pili yükselttikten sonra içine 4 adet 256GB MicroSD kart taktım
Yakın zamanda Bluetooth ekleyen bir mod da gördüm ama arka kasayı değiştirmek gerektiği için o kadar ileri gitmeyeceğim sanırım
Hem tasarımında hem de müzik dosyalarının kopyalarına bizzat sahip olma hissinde zamana meydan okuyan bir taraf var
Bunun burada daha fazla ilgi görmesine sevindim
Birkaç gün önce de paylaşılmıştı ama arada kaynadı: https://news.ycombinator.com/item?id=39037104
Orijinal videoda, bu kısa yazıda olmayan çok daha fazla şey var; ayrıca hacker'ın DS'de uygun ses kalitesi elde etmek için kesip biçerek yaptığı özel adaptör de gösteriliyor
https://www.youtube.com/watch?v=0-7PSmYYHF0
Zzazz her yıl bir 1 Nisan yarışması/etkinliği düzenliyor ve genelde içinde belli ölçüde retro hackleme veya tersine mühendislik bulunuyor
Katılmanızı tavsiye ederim
Geçmiş yarışmalar GitHub'da bulunuyor
Nintendo'nun ses mimarisi her zaman ilginç olmuştur
Orijinal NES'te, rastgele dalga biçimleri üretebilen bir sample generator vardı ve bu iki şekilde sürülebiliyordu
Birincisinde, bir bellek adresi veriliyor, cihaz bitleri okuyup bunu çok basit bir dalga biçimi olarak işliyordu; 1, “değeri bir artır”, 0 ise “değeri bir azalt” anlamına geliyordu, bu yüzden düz bir dalga biçimi üretmek için
10101010gibi tekrarlar gerekiyorduDiğerinde CPU, “başlangıç değeri”ni sürekli doğrudan yazarak çipi bizzat sürüyordu; pratikte bu, ses sürücüsünün bitleri RAM'den okumasından daha hızlıydı
Sorun şu ki bu yöntem tüm CPU çevrimlerini tüketiyordu, bu nedenle yalnızca başka bir iş yapılmadığında kullanılabiliyordu
Battletoads gibi oyunlar bunu kullanarak aksiyon durduğunda daha yüksek kaliteli davul vuruşları çaldı; başlık ekranında, düşmana son darbe vurulduğunda tüm aksiyonun kısa süreliğine durduğu o “çıtır” efektte ve akılda kalan duraklatma müziğinde bundan yararlandı
Oyunun doğrudan sürüş modu ile çipin sample okuduğu mod arasında geçiş yaptığını gösteren bir demo burada. Retro Game Audio, emülatörle düzenlediği bir video yükleyerek doğrudan sürüş alt yordamına girildiği anı gösteriyor: https://www.youtube.com/watch?v=JGT0FM3yh-w
En başta bunun neden olduğunu merak ediyorum
Bu oyunların durumu ses olarak dump etmesi yaygın bir şey mi? Oyun geliştiricileri için kasıtlı bir debug aracı mı?
Temelde GBA sesi, RAM’deki bir tampondan sesi akış halinde verir ve bir interrupt’ın donanıma tamponu baştan yeniden okumasını söylemesi gerekir
Ancak oyunun çökmesi gibi bir durumda interrupt oluşmazsa ses akışı tamponun ötesine geçip belleğin başka bölgelerini okumaya başlar
[1] https://www.youtube.com/watch?v=wSWNkpqjtQY&t=361s
Teorik olarak GBA, oyun çöktüğünde mimariyi “durdurabilir” ya da periyodik olarak çalışması gereken durum güncellemelerini maskelenemeyen interrupt’a bağlayıp bu güncellemeler durursa yeniden başlatan bir watchdog kullanabilirdi
Ama böyle özellikler ek maliyet getirdiği için GBA’da yok
Nintendo, eski oyun kartuşu üreticilerinin geleneksel yaklaşımını seçmiş gibi görünüyor: “Oyunumuzda bug yoksa donanımın tanımsız durumlarda ne yaptığını dert etmemize gerek yok.”
Bu yüzden bir GBA oyunu interrupt’ların devre dışı olduğu sonsuz döngü gibi bir çökme durumuna girerse, ses çipi sistemin çöktüğünü fark etmeden RAM’in ardışık bitlerini okuyup sese dönüştürme işini sürdürür
Normal çalışmada okuma işlemini yöneten toparlama rutini ortadan kalktığı için okumaya devam eder ve sonunda kartuş ROM’unun değerlerini temsil eden bitlere kadar ulaşır
Gerçekten saçma derecede etkileyici
Burada kullanılan çoğunluk oylaması algoritması gibi teknikler, sanki birçok sektörde yeterince değerlendirilmiyor
Manyetik depolama ortamları temelde bu hack ile aynı prensiple çalışır
https://en.wikipedia.org/wiki/Partial-response_maximum-likelihood
Aynı fikir burada da uygulanabilir; çünkü GBA ROM içeriğinin güçlü bir önyargıya sahip olması beklenir
Çoğunluk oylaması çok fazla bilgiyi boşa harcar
Tüm fotoğrafları üst üste koyup her piksel için yalnızca medyanı bırakmanız yeterlidir[1]
[1]: https://patdavid.net/2013/05/noise-removal-in-photos-with-median_6/
Disk imajı tekrar tekrar okunur, yeter sayı değerlendirmesi yapılır ve checksum’ı geçen bir sonuç çıkınca düzgün çalışıp çalışmadığına bakılır
Dosya imzaları gibi daha üst düzey checksum’lar varsa ek doğrulama için daha da iyidir
Bazı havacılık ve uzay uygulamalarında da kullanılır
Kusursuz bir master yerine hasar görmüş olabilecek sinema gösterim kopyalarıyla uğraşıldığı için, birden fazla kopya kullanarak çizikleri vb. temizlemek mümkün olsaydı sonradan elle düzeltme için harcanan zamanı muazzam ölçüde azaltabilirdi
0xFF’nin 0x00’a dönüşmesi DC blokaj kapasitörü ya da yüksek geçiren filtreleme yüzünden olabilir
Ses devresi duyulamayan içerikler için pek uygun değildir
Şanslıysanız, yonganın ses çıkışına doğrudan dijital bir osiloskop bağlamak yakalama doğruluğunu artırabilir, ama yine de boot edilebilir bir imaj elde etmiş olmaları oldukça etkileyici
Bu yüzden düzgün bir veri kaydı yapan osiloskop kullanmak yerine, hataları ortalamak için tekrar tekrar yakalama yaparak saatler harcamışlar
Manchester kodlaması gibi basit bir yöntem bile çok yardımcı olur
Bu yetmezse NRZ hatta evrişimsel kodlama bile kullanılabilir
Ayrıca sinüs dalgası göndermek ya da bu mümkün değilse en azından kare dalga frekansını AC kuplaj kapasitörüne takılmayacak kadar yükseltmek gerekir
Bütün bunların içindeki en etkileyici kısım bana göre, korsancıların ROM+uçucu depolama belleği yerine yazılabilir flash üzerinden oyun çalıştırmak için kodu değiştirme biçimi
Aslında bu tür patch’ler üretmek de o kadar zor değildir
Korsancılar, oyunun kodunun nereye kayıt yaptığını biraz tersine mühendislikle bulup oyuna özel patch’ler yazarak kayıt verisini yazılabilir flash’a flush eder
Ancak resmi GBA oyunları kayıt için her zaman Nintendo SDK’nın fonksiyonlarını kullandığından, bu fonksiyonları hook’lamak pil gerektirmeyen kopya kartuşlarda herhangi bir GBA oyununun kayıt yapmasını sağlayan genel amaçlı bir patch üretmeyi oldukça kolaylaştırır
Bunu yapan bir patcher yazdım; burada görülebilir
https://github.com/metroid-maniac/gba-auto-batteryless-patcher
TheZZAZZGlitch’in emülatörü, oyunun yanlış bir adrese atlamaya çalıştığını bildirdiğinde içeride tam olarak ne olduğunu bilen var mı?
Game Boy Advance’te kullanılan ARM7 işlemcisine aşina değilim ama atlama çağrısını yanlış bir değerle nasıl kurmanın mümkün olduğunu gözümde canlandırmakta zorlanıyorum
Ayrıca TheZZAZZGlitch’in hatalı şekilde geri yüklediği ROM’lardan birini gerçek bir Game Boy’da çalıştırırsanız ne olacağını da merak ediyorum
bxkomutu kullanılırsa, register’da tutulan rastgele bir adrese atlanabilirVe hatalı geri yüklenmiş ROM’u gerçek bir Game Boy’da çalıştırırsanız çöker ve sonunda ROM’u hoparlörden çalmaya başlar
Videonun özü bu zaten :)
Gerçek donanımda ne olacağına gelince… kim bilir :)