Защита на игрите GameBoy Advance от емулация
Някои от вас може би си спомнят серия от забележителни игри Game Boy Advance, пуснати през 2004 г. Светлосивите касети с прости етикети бяха много различни от обичайните, тъмносиви с многоцветни етикети. Те продаваха игри, пренесени от оригиналната Nintendo Entertainment System. Известни като Classic NES Series в САЩ, тези игри са интересни по няколко причини.
Те са особено интересни по отношение на GBA емулация. Обикновено игрите Game Boy Advance са невероятно проблематични, а самата платформа съдържа много средства за защита срещу сривове. Следователно, за да стартирате игри, емулаторите трябва да са съвместими с грешките на оригиналния хардуер. В серията Classic NES обаче разработчиците отидоха по-далеч и се опитаха да защитят играта от стартиране в емулатори.
Ако сте опитвали да играете с някой от по-старите емулатори, вероятно сте виждали екрана за грешка в Game Pak. Както се оказа, тези игри използват трикове и недефинирано поведение, което усложнява емулацията. Изглежда, че е бил умишлен опит за защита срещу копиране за такива игри. В интерес на точността на емулацията, аз старателно проучих, внедрих и записах всички необичайни действия, извършвани в тези игри.
Трик 1: Отразяване на паметта
Трик 2: код във VRAM
Трик 3: STM в DMA регистри
Трик 4: Скриване на типове запис
Трик 5: Нарушение на Prefetch
Трик 6: нехомогенности в аудио FIFO буфера
Има обаче една трудност: въпреки че игрите могат да се играят, звукът е безнадеждно повреден. Решението изискваше малко коригиране и този трик също беше уникален за серията Classic NES и следователно беше приложен малко неправилно поради непълни съвпадения на спецификациите. Game Boy Advance има шестаудио канали: четири канала процедурно генерирано аудио (разширени канали на оригиналния Game Boy) и два канала PCM аудио. Доколкото разбирам, игрите от серията Classic NES използват само един канал, един от PCM каналите. PCM аудио каналите се управляват от малък вътрешен FIFO, който стартира DMA трансфер на данни, когато се достигне определена точка. Игрите ги конфигурират да записват по 32 бита наведнъж в I/O регистрите, свързани с всеки канал. Тъй като PCM каналите са само 8 бита широки, 32-битов запис всъщност е четири проби. Но класическите игри от серията NES са малко по-различни: те записват само 16 бита наведнъж, наполовина, а не в целия регистър. Тъй като предположих, че игрите могат да записват само 32 бита наведнъж, това доведе до това, че емулаторът записва две проби наведнъж, от които играта се нуждае, и две празни проби. Този банален пропуск напълно изкриви звука в игрите. След проста корекция игрите започнаха да работят нормално.
Постигнахме успех, но защо толкова трудности?
Не знам защо Nintendo ще премине през всичко това за обичайните портове на NES игри. Пълнофункционалните NES емулатори съществуват от дълго време, като добри примери датират от 1997 г. Докато игрите от серията Classic NES бяха първите, които се играят на ръчна конзола, емулацията на Game Boy Advance на други ръчни устройства съществува от няколко години. Освен това, докато проблемите, които изброих, са предотвратили емулация в някои проекти, тази защита се прилага само за серията Classic NES. Не разбирам защо отидоха толкова много, за да осуетят разработчиците на емулатора в този конкретен случай, но за мен това доведе до няколко дълги вечери на последователен анализ на функциите на кода на играта, докато нещата не станаха наистина зле.
Въпреки това следкоригирайки всички тези проблеми, играта стартира и работи на 100%. Най-актуалните поправки са направени във версия 0.1.0, но някои големи промени са отложени за по-късно. Игрите ще бъдат напълно поддържани във версия 0.2.0 след пускането й и вече могат да се играят във вечерни версии.
Hardcore conf в C++. Каним само професионалисти.