Sehr erfreulich zu sehen, wie der Assembler-Kurs hier im Forum zum Lernen und Umsetzen motiviert. Top!
Als "Cracken" würde ich das Obige allerdings nicht bezeichnen - "Patchen" oder (ansatzweise) "Modden" trifft es viel eher. Cracken ist das Analysieren eines geschützten Programms und Entfernen des Programm- bzw. Kopierschutzes, dazu kam in den guten alten Zeiten von C64 und Amiga i.a. auch noch das Packen des vom Kopierschutz befreiten Programms und seiner Daten und das Einbinden eines netten Cracker-Intros. War das ursprüngliche Original eine Tape-Version, wurde es normalerweise auch gleich zur Diskettenversion "konvertiert" (Nachlader etc.).
Kleine Zwischenfrage. Wie haben das eigentlich die Jungs in den 80ern gemacht, bevor es Freezer-Module gab ?
Damals musste man die Programme noch schrittweise und mit den zur Verfügung stehenden Programmen auseinandernehmen oder sich selbst passende Tools schreiben. Unabdingbar war da ein *mehr* als fundamentales Wissen über den 6502/6510-Prozessor (anfangs reichte noch das "normale" Know-How, später waren dann Sachen wie die "illegalen" Opcodes auch gefragt), Tiefenwissen über die C64-Architektur und viel Logik.
Hatten die den Speicherinhalt manuell durchsucht oder wurde ein geändertes Kernal mit Monitor benutzt und dann nach einem Warmstart-Reset durchstöbert ??
Das war je nach Programm und Kopierschutz unterschiedlich... individuell halt. Ein geändertes ROM lässt sich aushebeln, indem man das ROM insgesamt abschaltet (dafür ist in der Zeropage Adresse $01 da) - Assemblercode braucht grundsätzlich erstmal kein ROM, solange er alle Routinen selbst mitbringt.
Vereinfachter Exkurs:
Der C64 bringt volle 64 Kilobyte RAM im Bereich von $0000-$FFFF mit. Damit ist der volle Adressraum des Prozessors mit RAM belegt. Um hier aber auch noch das ROM mit dem Betriebssystem und die Register des Chipsatzes (CIAs, VIA) unterzubringen, lassen sich über die Zeropage-Adresse $01 (Bits 0 bis 2) die entsprechenden Chips "über" das vorhandene RAM einblenden. Sind die ROMs aktiv (BASIC von $A000-BFFF, KERNAL von $E000-$FFFF, Zeichensatz-ROM von $D000-DFFF), bringt ein Auslesen einer Adresse im ROM-Bereich den Inhalt des ROMs, aber ein Schreibzugriff erfolgt immer auf das darunterliegende RAM. So kann man z.B. das BASIC-ROM ins darunterliegende RAM kopieren, es modifizieren oder austauschen und dann durch Schreiben eines entsprechenden Wertes "umschalten". Oder man nutzt den "versteckten" Speicher in Assembler wie normalen Speicher für Daten, indem man bei Lesezugriff immer oder kurzzeitig das ROM ausblendet.
Besonders ist allerdings der Bereich $D000-$DFFF, weil er quasi 3fach belegt ist: hier wird auch der I/O-Bereich eingeblendet (CIAs, Videocontroller, SID), der normalerweise aktiv ist. Lesezugriffe liefern bei eingeschaltetem I/O-Bereich dann die Inhalte der I/O-Register (in $D020 z.B. die Rahmenfarbe), Schreibzugriffe gehen dann allerdings nicht ins RAM, sondern eben auch in die I/O-Register - sonst könnte man keinerlei Geräte etc. ansteuern...
/Exkurs Ende
Viele Spiele "überladen" also die ROMs durch eigene Routinen im RAM darunter und schalten dann das ROM schlicht ab. Ansonsten wäre ein geändertes ROM (als Eprom etc.) aber ein gutes Mittel zum Anfang. Vor allem läßt sich darüber auch ein simpler Reset-Schutz des originalen ROMs aushebeln: Module am Cartridge-Port des C64 starten automatisch, weil das Betriebssystem im ROM prüft, ob ab $8000 im RAM die Zeichenfolge "CBM80" vorhanden ist. Dort wird nämlich bei gestecktem Modul dessen Speicher eingeblendet. Hinter der Kennung folgt dann die Einsprungadresse des Moduls, und schon läuft das dort gespeicherte Programm. Ein Originalprogramm kann nun bei gestecktem Modul den eigenen Start verweigern, ansonsten kann es aber die Kennung selbst im RAM ablegen und dahinter auf seine eigene Reset-Routine etc. verweisen.
Zurück zur Frage wieder...
Erstmal sollte man das zu knackende Programm ein paarmal starten / spielen. Nur so bekommt man ein Gefühl dafür, welche Schritte beim Laden und direkt danach anstehen, was für die nachfolgend zwingend notwendige Codeanalyse erforderlich ist. Wie lange dauert das Laden? Gibt es Pausen (= mehrere Dateien nacheinander geladen)? Kommt eine Grafik und danach direkt das Spiel, oder wird bei stehendem Titelbild nachgeladen? Usw...
Dann schaut man sich den Loader des Programms (meist ja ein Spiel) an und versucht, einen Autostart zu verhindern. Schon das ist hochgradig individuell, meist werden durch "absolutes" Laden (von Disk per ",8,1") bestimmte Adressen der Zeropage überladen und Vektoren ausgetauscht, so dass die Laderoutine direkt in das eben geladene Programm einspringt / zurückkehrt und der Loader sofort übernimmt. Hat man den Loader seziert, kann man ihn entweder im Speicher (vor allem bei Tapes) oder auf Disk so anpassen, dass er nach dem Ladevorgang wieder in den Monitor/Debugger des Crackers springt oder zumindest das nachgeladene Programmteil nicht ausführt.
Schon hier hilft nur noch Hardcore-Wissen über den Prozessor UND die Eigenheiten des C64 weiter. Viele Kopierschutzmechanismen sind ziemlich kreativ - eigene Packalgorithmen, timerbasierte Ladezeitverifizierung, Prüfsummen über Dateien oder Teile des geladenen Codes, eigene Tape- oder Disketten-Formate, illegale 6510-Opcodes, selbstmodifizierender Code, das alles kann man finden. Hat aber wirklich Spaß gemacht und war irgendwie auch sportlicher Ansporn, diese Tricks herauszufinden und dem Programmierer bzw. der Firma zu zeigen, dass man auch sowas cracken konnte...
Herausforderung war, die Programme ggf. auch zu verbessern. Trainer einzubauen. Mehrteilige Programme mit eigenen Laufzeit-Packern zu einteiligen Programmen machen. Einen (technisch meist ambitionierteren) Vorspann einbinden. Die Musik von "Commando" war übrigens echt klasse - die konnte man modular extrahieren und per Interrupt auch in eigenen Intros im Hintergrund einbinden...
Bevor das nun hier noch ein eigener Kurs zum Thema wird, mach ich mal lieber im Büro meine "richtige" Arbeit weiter.
Good old times...
Grüße,
Ralph.