Wie man ein Playstation-Spiel knackt
PSX-Crack-Tutorial
Lektion 1 von ???
von B.A.D.
Best Amiga Dominator(s)
aus dem Italienischen von mAlaexyz
Mit diesem Dokument hoffe ich die Neugier all derjeniger zu befriedigen, die mir geschrieben haben mit der Frage nach Informationen über die neuen Kopierschutzmechanismen für PSX und über die Methoden, diese zu hintergehen; es handelt sich klarerweise nicht um eine komplette Anleitung zum Cracken, aber ich hoffe, es kann dennoch jenen nützlich sein, die, mit angemessenen Grundkenntnissen, die Absicht haben , sich an diesem Typ der „Arbeit“ zu versuchen.
Voraussetzungen
Vor allem ist eine gute Kenntnis des Assembler der R3000-CPU der PSX nötig: wer bereits auf dem Amiga Erfahrung hat, dürfte keine große Schwierigkeiten antreffen, es reicht sich der Funktionsweise einer RISC-CPU anzupassen; wer hingegen nur die Theorie des Assembler x86 kennt, wird vielleicht ein paar Probleme mehr haben. Man braucht dann eine ganze Reihe unentbehrlicher Tools: Assembler, Disassembler, Debugger etc..., sowie einige Informationen über die spezifische Hardware der PSX.
Alle Dokumentationen und die Tools, die von mir verwendet werden, sind bei den angegebenen Adressen am Ende dieses Dokuments zu finden.
Prinzipielle Funktionsweise von LibCrypt
Wie jede andere Art von Kopierschutz ist auch LibCrypt aus zwei verschiedenen Routinen zusammengesetzt: die erste führt eine Kontrolle der Disc aus um zu ersehen, ob es sich um eine Kopie handelt, die zweite, basierend auf dem Ergebnis des Resultats der ersten, entschlüsselt einen Datenblock und blockiert im Falle eines fehlerhaften Ergebnisses die PSX.
Auf dem selben Code basierend, wurden die beiden Routinen mehrere Male verändert, jetzt zum Zeitpunkt der letzten Entwicklungsstufe (LC3; LibCrypt 3 Anm. d. Übers.) haben sie fast nichts mehr gemein mit dem ursprünglichen Code.
Alles ist in reinem Assembler geschrieben, unter direkter Verwendung der Hardwareregister der PSX : Es gibt keine Standard-Systemabfrage und es ist jede Vorsichtsmaßnahme ergriffen worden um zu verhindern, daß das Programm zurückverfolgt und damit „verstanden“ werden kann.
Die Routine, welche den Check der Disc ausführt, benutzt direkt die Hardwareregister des CD-ROM (1F80180X) und legt die temporären Daten im Scratchpad Memory (Bereich des Arbeitsspeichers für zusätzliche Daten, 1F800000-1F8003FF, Anm.) ab, berechnet dann mit rekursivem Algorithmus eine 16Bit lange Nummer (das MagicWord!), wobei es als Parameter für die Subroutinen die in einigen Registern des COP0 (System-Coprozessor) abgelegten Werte verwendet, um schließlich abschließend das MagicWord im unteren Teil des BPC-Registers abzulegen.
Klarerweise wird das BPC einen abweichenden Wert haben für den Fall, daß die CD nicht das Original ist! Dieser massive Gebrauch der Eigenarten der Hardware läßt die Routine auf jedem PSX-Emulator fehlschlagen, weil aktuell keiner den Zugriff auf den unteren Bereich des CD-ROM unterstützt, aber, noch wichtiger, der Gebrauch der COP0-Register verhindert dem Action Replay, das Programm Schritt für Schritt zu verfolgen, und verhindert auch dessen normale Funktion, weil das A. R. sich des Scratchpad Memory bedient, um den aktuellen Status der PSX zu sichern und deshalb die Daten in diesem Bereich des Speichers verändert. Wenn man hingegen ein Pro Action Replay hat, ausgestattet mit RAM und folglich immun gegenüber dem Problem der gemeinsamen Aufteilung des Scratchpad Memory, dann ist immer noch eine Routine vorhanden welche die PSX blockiert, sobald das P.A.R. (Pro Action Replay) aktiviert wird; diese abschließende Routine ist die einzige, die bis jetzt unverändert geblieben ist.
Um die Sache darüberhinaus zu verkomplizieren, ist von LC2 (LibCrypt 2) an ein „Autocheck“ der gleichen Routine eingeführt worden, der enthüllt, ob Letztere verändert worden ist.
Die zweite Routine, diejenige die das Vorhandensein des MagicWord im BPC kontrolliert, ist auf unterschiedliche Art und Weise in die verschiedenen Spiele eingebaut worden: Einige führen sofort den Check aus (z. B. FF8), weitere warten einige Level (Spyro 2), andere wiederum führen den Check zyklisch aus während etlicher CD-Ladevorgänge (Soul Reaver) oder zu gewissen Zeitpunkten (Mulan).
Wie man den LibCrypt umgeht
Die einfachste Lösung scheint nun die zu sein, die zweite Routine zu suchen und sie dazu zu bringen, sich so zu verhalten, als ob das BPC das MagicWord enthalten würde.
In der Tat ist diese Routine fast immer gut sichtbar während des ganzen Hauptprogramms, und sie ist leicht identifizierbar, weil dort die PSX blockiert.
Leider ist es nicht gesagt, daß von dieser Kontrollroutine nur eine einzige existiert, vielmehr waren in Soul Reaver drei enthalten und es ist nicht gesagt, daß davon nicht weitere geladen werden können bis zum abschließenden Level! (Anm. d. Übers.: Aus diesem Grund war auch der erste Soul Reaver Crack von Paradox fehlerhaft, was sich aber erst später im Spiel zeigte!)
Die beste Möglichkeit wäre es jetzt, die erste Routine so zu verändern, sie glauben zu lassen, die CD sei das Original. Jedoch fehlen einer Kopie leider einige der auf dem Original vorhandenen Daten, und ich habe keine Methode gefunden, die Routine dazu zu bringen, das MagicWord ohne das Vorhandensein dieser Daten zu produzieren.
Die passende Methode bisher besteht ganz einfach darin, das MagicWord aus einer PSX herauszulesen, während eine funktionierende CD (Original) eingelegt ist. Dies hat den Vorteil, das Originalprogramm auf minimalste Art und Weise zu verändern; es genügt, den richtigen Wert im BPC einzutragen nach Abschluß der ersten Routine.
Es gibt klarerweise auch Nachteile: es ist nötig, eine funktionierende CD (Original) zur Verfügung zu haben, und in Anbetracht dessen, daß die MagicWords im allgemeinen von einer regionalen Version des Spiels zur anderen verschieden sind, ist es nicht möglich, „universelle“ Cracks zu realisieren.
Außerdem schreibt jedes neue Spiel seine eigene Geschichte, in der Hinsicht, daß es jedesmal nötig ist, das Programm (mit einem Debugger) zu zerpflücken auf der Suche nach den geeignetsten Punkten, das MagicWord zuerst zu lesen und dann zu erzwingen. Das ist das Schwierigste angesichts der Tatsache, daß heutzutage (LC3; LibCrypt 3 Anm. d. Übers.) jede Subroutine verschlüsselt (xor) und „unsichtbar“ für das Hauptprogramm ist; ist erst einmal ein passender Punkt für das Auslesen des MagicWord gefunden, ist es nötig, den Eintrag seines Werts in irgendeinen Speicherbereich zu veranlassen, außer im BPC-Register, weil man es klarerweise von dort nicht direkt unter Verwendung des A.R. (Action Replay, Anm. d. Übers.) lesen kann.
Ein praktisches Beispiel
Ich nehme als Beispiel die Routine, welche die PSX bei Vorhandensein eines A.R. blockiert, einerseits, weil deren Entfernung zuallererst notwendig ist, andererseits, weil es die einzige ist, die bislang unverändert geblieben ist (wenn auch verschlüsselt).
Das ist die Routine, wie sie sich bei der Ausführenden Datei von Mulan (ital. Version, Anm. d. Übers.) zeigt.
1) 8003a054 lui v0,0x1f00
2) 8003a058 mtc0 v0,BPC ; BPC= BreakPoint on execute address
3) 8003a05c lui v0,0x1ffc
4) 8003a060 mtc0 v0,BPCM ; BPCM= BreakPoint on execute address Mask
5) 8003a064 mtc0 v0,BDA ; BDA = BreakPoint on data access address
6) 8003a068 lui v0,0x8004
7) 8003a06c addiu v0,v0,0xa084
8) 8003a070 mtc0 v0,BDAM ; BDAM= BreakPoint on data access address Mask
9) 8003a074 lui v0,0xe180
10) 8003a078 mtc0 v0,DCIC ; DCIC= BreakPoint on control register
11) 8003a07c jr ra
12) 8003a080 nop
(1) (2) - laden $1f000000 in BPC, der Anfangswert für das MagicWord ist folglich Null (der Teil unterhalb des BPC)
(3) (4) (5) - laden $1ffc0000 in BPCM und BDA
(6) (7) (8) - laden die Adresse $80035f7c in BDAM
(9) (10) - laden $e1800000 in DCIC, und schließlich
(11) (12) - veranlassen die Rückkehr aus der Subroutine
Die Werte, die in BPC und BPCM geladen werden, werden wahr, wenn sich eine Exception nachweisen läßt; wenn eine in den ersten 256k Speicherbereich vorhandene beliebige Anweisung ausgeführt wird von Beginn der Adresse $1f000000 an; genau dort also, wohin sich das EEPROM des Action Replay positioniert.
Die in BDA und BDAM eingetragenen Werte variieren, da sie im folgenden verwendet werden, als ob es sich um normale Register handelt, in der Tat aktiviert der in DCIC geladene Wert nur den „BreakPoint on Execute“ und nicht den „BreakPoint on data access“.
Um zu vermeiden, daß das A.R. die PSX blockieren läßt, ist folgendes nötig, falls nicht aktivierte BreakPoints in dessen Speicherbereich sind: angesichts dessen, daß man die eingetragenen Werte im BPC und BPCM nicht verändern kann, weil sie im folgenden verwendet werden, besteht die banalste Lösung im Entfernen (austauschen mit nop) der Anweisung (10), so wird kein Register verändert, aber die BreakPoints werden nicht aktiviert. (Es hätte auch genügt, $e080 an Stelle von $e180 zu setzen, aber ein nop ist einfacher ☺ )
Dieser kleine „Patch“ am Code ist lediglich nötig, um das A.R. benutzen zu können, somit ist es besser, daß es nicht beim endgültigen Patch eingesetzt wird, weil es zumindest den Originalcode ändert. Und man kann nie wissen, wenn man vielleicht am letzten Level des Spiels angekommen ist, prüft das Programm den enthaltenen Wert im DCIC Register doch noch nach ☺
Links
Dieser Teil enthält die Links zu drei Sites; diese bieten, bezüglich der Entwicklung von Anwendungen auf der PSX, jede Art von Material an, eine jede davon enthält wiederum einen Bereich mit Links, von wo aus man weitere vergleichbare Sites erreichen kann.
Natürlich darf der PsEmuPro nicht vergessen werden, welcher trotz seiner vielen Einschränkungen ein sehr nützliches Instrument ist: dank des integrierten Debugger und Simulator von Action Replay verspricht er die Verfolgung des Codes soweit es geht, und Schritt für Schritt ein Programm auszuführen läßt einen die Funktionsweise der R3000 viel schneller verstehen, als es nur mit dem Lesen der Dokumentation möglich wäre.
Napalm http://napalm.intelinet.com
Hitmen http://hitmen-console.org
NetYaroze http://www.geocities.co.jp/Playtown/2004/psx/ny_e.htm
Anmerkungen zur Übersetzung
Diese Übersetzung wurde mit größter Sorgfalt aus dem italienischen Original übertragen, welches auf der Homepage von B.A.D. erhältlich ist. Soweit es mir in einzelnen Punkten erforderlich schien, habe ich kurze Anmerkungen eingefügt, welche jedoch klar als solche erkennbar sind. Für den Inhalt verantwortlich ist B.A.D. Die Original-HTML-Datei ist als Anhang Teil des ZIP-Archivs und damit Teil dieser Dokumentation.
Mein Dank gilt:
Abraham van Helsing (AvH) von PDX für die Überprüfung der Rohübersetzung
Mike + Zweifeld von Gamefreax für die Unterstützung
Back für das Zusenden des italienischen Originaltextes und der spanischen Übersetzung.
Links:
B.A.D. http://www.bad-hq.com
mAlaexyz http://members.tripod.de/malaexyz
Paradox http://www.paradogs.com
Gamefreax http://www.gamefreax.de
© mAlaexyz 15.01.00