Hello, Guest the thread was called13k times and contains 116 replays

last post from Stephan Scheuer at the

Kopierschutzverfahren gelüftet

  • Vieles habe ich nur hier im Forum Released.

    In der Tat gibt es einiges auf der CSDB von mir. Die alten Sachen sind meistens Recracks und SCPU Anpassungen. Seit ich hier im Forum bin, habe ich mir erst mein Wissen

    über ASM, Basic, P-Codes, EasyFlash, REU, GeoRAM angeeignet. Die ersten neuen Cracks waren "Ski or Die" für die 1581 und Gunslinger auch für die 1581. Beide Games waren 256Bytes sektorbasierende Trackloader.


    DTL-Compiler, siehe den Link unten. Einen Decompiler dafür zu coden sollte nach meinem Ermessen recht "einfach" sein. Ich hatte das vor Jahren mal versucht, hatte dann aber aufgrund

    des Mangels von Wissen das Projekt estmal auf Eis gelegt. Ein PetSpeed Decompiler ist auch möglich. Beim Basic64 Compiler von Data Becker kommt es darauf an, welche Parameter zum Kompilieren genutzt wurden.


    Frage zu Insta-Calc

  • Achja, und hier mein aufgegebener CrackVersuch des Austro C128. Da mache ich erst weiter, wenn jemand das Dongle hat und mir einige Basics Compilieren könnte.

    Im C64 P-Code herumzustochern geht ja noch aber der Grcryptete C128 austro P-Code ist einfach nur noch Evil.

    Hier sind ein paar Infos zu finden dazu ...


    https://archive.org/download/64er_sonderheft_12

  • I was questioning the motivation of Heureka for protecting it in the first place like this.

    I'm with you, though we had a minor discussion about this around here a while back - as much as the level of sophistication of this kind of copy protection is borderline ridiculous, as someone pointed out back then: the thing to keep in mind is that this isn't your everyday copy protected game, but educational software instead, which even at the consumer level sold much smaller figures. If these were freely copied between schools for use in classrooms, they'd probably sell next to nothing. And this isn't even the worst of them. We've seen "job training" educational software targeted at an adult professional level that would probably sell even less due to its narrow scope (and at a much higher price too) which was protected with probably just about every kind of approach they could think of, from hardware dongle to disk killer/formating. It's silly in a way, like maybe every copy protection, but I guess it stands to reason to assume they felt the need to protect their revenue stream, which may have already been fairly marginal with this kind of genre to begin with.

  • the level of sophistication of this kind of copy protection is borderline ridiculous

    ... wollte es nur noch mal kurz bildlich darstellen (Bilder überlagert; unten T2 und oben T31) ... die Prüftracks 2 <-> 31 gegeneinander. Was in den hervorstehenden Sektoren passiert, ist weiter zu erörtern, was die gemessene Schreibdichte innerhalb der Tracks betrifft.

  • Wie gut ein Kopierschutz ist, zeigt nicht, ob dieser nun nicht oder schwer kopierbar ist, sondern die Möglichkeit des Aushebelns diesen.

    Ich hatte schon einige gut gemachte Kopierschutzverfahren kennen gelernt. Nur wenn der Floppycode per B-R und M-E oder ähnlich eingelesen und gestartet wird, wobeir der Code

    in dem betreffenden Sektor mit einem EOR#xx verschlüsselt wurde, ist der ganze Programieraufwand für den Po.

    Der Heureka Kopierschutz war dagegen auch sehr gut abgesichert. Ich meine, meine Cracks Anfang der 2000er waren die ersten, die den Heureka Teachware Kopierschutz deaktiviert hatten.


    Wenn man per Google danach sucht, bekommt man z.B. immer das zu sehen "Learning English Orange Line II (1989)(Heureka Teachware)(de)[cr Master]":)

  • Ich meine, meine Cracks Anfang der 2000er waren die ersten, die den Heureka Teachware Kopierschutz deaktiviert hatten.

    :thumbup:

    Möglichkeit des Aushebelns

    :thumbup:

    Orange Line II

    :thumbup:

    zu sehen

    ... Orange Line 1 ... bestimmt schon ein halbe Ewigkeit her ... ;).

  • robak29


    Ich habe gerade das Heureka Teachware "Let's Go 5" analysiert.:)

    Hier gibt es z.B. eine üble Falle gegen das Decompilieren. "Let's Go 5" ist mit dem Austrospeed E5 compiliert worden. Der P-Code Header beginnt bei dem Compiler ab $1EE6.

    Im Bild unten siehst du im Fenster 1 den Austrospeed E1 und im Fenster 2 das "Let's Go 5" Compilat. Hier erkennt man, dass der/die Coder etwas ASM-Code des E1 Compiler in

    dem P-Code eingebunden haben. Das beginnt ab $1F6D und endet bei mindestens $1FA6. Um das zu decompilieren, ohne dass der Decompiler dabei zur Müllcodeschleuder wird,

    muss du von $1F6D bis mindestens $1FA6 den P-Code für CLR = #$15 eintragen. Warun CLR? Dieser Befehl ist der sinnvollste, ohne den Decompilier aus dem Tritt zu bringen.

    Bis mindestens $1FA6 bedeutet, das dass Ende des Fake P-Code unbekannt ist. Falls der Decompiler Müll produziert, dann eine weitere #$15 eintragen, abspeichen und versuchen

    den Code zu decompilieren. Man kann auch alles bis zum nächsten Goto (19+HI&LO Sprungadresse) mit #$15 auffüllen und eine Decompilierung starten. Nach dem Decompilieren

    kann man den Abschnitt entfernen oder anderweitig ersetzen.:)




    "Let's Go 5" richtiger P-Code Header

    -------------------------------------

    $1ee6 18 5d a1 63 a1 63 f2 1e

    $1eee 0f 1f 10 1f bf 10 01 da



    "Let's Go 5" Fake P-Code Header

    -------------------------------

    $1f93 1e 56 0c 57 0c 57 9f 1f

    $1f9b a7 1f a8 1f b3 10 01 da

    $1fa3 aa 00 00 16 ff 15 15 a6

    $1fab 22 33 c0 a8 90 50 00 00

    $1fb3 00 c1 a8 90 7f 80 00 00

  • @robak29


    Und weiter gehts...


    Alle Werte von $1F6D bis $1FA9 Bitte mit #$15 ersetzen, abgespeichern und decompilieren. Danach alle REM-Zeilen suchen. Dabei handelt es sich um Compilierungsfehler in Zeilennummer,

    siehe unten. Es handelt sich immer um den Wert #$5a und an Schluss um #$59. Ein Schelm, wer Böses dabei denkt. Also, alle Werte mit einem Compilierungsfehler durch #$15 ersetzen,

    abgespeichern und nochmals decompilieren. Und nun, das ist ganz wichtig, müssen alle gesetzten #$15 "CLR" wieder aus dem Basic Code entfernt werden. Das war es auch schon.

    Ich hoffe, dass dir das ein wenig hilfreich war.:)



    Recompile error in Zeile

    ----------------------------

    7980 rem 90 $1F2C -> 5a -> 15

    8173 rem 90 $1FED -> 5a -> 15

    8179 rem 90 $1FF3 -> 5a -> 15

    8687 rem 90 $21EF -> 5a -> 15

    10683 rem 90 $29BB -> 5a -> 15

    23828 rem 89 $5D14 -> 59 -> 15

    23830 rem 89 $5D16 -> 59 -> 15

  • Nun angenommen, man möchte den dekompilierten Code zum Laufen bekommen. Wie würde ich da rangehen:

    Erstmal die künstlichen CLRs raus. Dann alle GOTOs und GOSUBs verfolgen, um rauszubekommen, welcher Code gar nicht angesprungen wird.

    Bei jedem nicht angesprungenen Code-Schnipsel zweifeln, ob das so richtig ist.

    Beim ersten Betrachten des Kompilats sehe ich zwar interessanten Code (d.h. einen der nicht nach Müll aussieht), z.B. ab Zeile 8106 ...

    ... der aber nie angesprungen wird. Also würde ich annehmen, dass der Decompiler etwas übersehen hat und würde den Anfang mit dem P-Code vergleichen. Oder?

    Zeile 8110 und 8117 wird auch nie angesprungen, obwohl die Variable uh und al später doch verwendet werden. Nur eine Ablenkungstaktik?


    Die ganzen Bytes, die nun CLRs sind ($5a ..., $59 ...): Kann es nicht sein, dass die Runtime doch irgend etwas damit anstellt (spezielle Opcodes, die ignoriert werden, oder - schlimmer - doch etwas tun)?

    Wie könnte das vor dem Kompilieren ausgesehen haben, im ursprünglichen Basic-Programm?

    Eine Möglichkeit meinst Du wäre, dass man da nach dem Kompilieren einige Bytes geändert hat, um das Dekompilieren zu erschweren.

    Aber woher wusste man, dass man das tun kann, ohne die Runtime instabil zu machen?

  • Wie könnte das aus vor dem Kompilieren ausgesehen haben, im ursprünglichen Basic-Programm?

    Eine Möglichkeit meinst Du wäre, dass man da nach dem Kompilieren einige Bytes geändert hat, um das Dekompilieren zu erschweren.

    Aber woher wusste man, dass man das tun kann, ohne die Runtime instabil zu machen?

    Ja sicherlich ist das möglich. Stell dir vor, Mitte 80er, du Codest monatelang eine Software für den C64 und möchtest die gegen das Decompilieren schützen.:) Naaaahh...8)


    Mit den anderen Dingen hast du auch absolut Recht. Rückverfolgung der Sprungbefehle ect. Hierbei empfehle ich das Renumber bein C128. Das Renumber wird sofort abgebrochen, wenn etwas am Basic Code nicht stimmt. Danach ist auch auch ratsam, das Basic mittels Packer zu verkürzen. Bitte nur den im Bild unten nutzen. Diese produziert recht selten mal ein Fehler.

    Wenn im Condesed Basic zwei GOTOs hintereinanderstehen, hat man schon eine unstimmigkeit gefunden. Diese Tips von mir, dienen nur der schnelleren und besseren Auffindung unnützen Krams im Code. Letztendlich gibt es auch die sehr gute Möglichkeit, duch Kompilieren viele Bugs zu finden. Austro, Petspeed, Basic64, Laserbasic, BasicBoss ect. eignen sich bestens dafür.

    Die CLRs kannst du natürlich im Code belassen und nach dem Kompilieren mit dem Originalwert austauschen. Schau dir aber mal die anderen Decompilate von mir an. Der Anfang des Basic Codes ist

    fast immer gleich oder ähnlich. Übrigens, der Coder muss natürlich vorher wissen, wo die DecompileErrors, falls abgefragt, im P-Code zu finden sind.

    Achja, bei den Heureka-Decompilaten hatte ich noch nie toten Basic Code entdeckt.:)


    Die Zeile 20 kann man nach dem Kompilieren ändern, mit irgendein Fake-Code. Dem RT-Modul ist das wurst.


    10 GOTO 30

    20 PRINT"WIRD NIE ANGESPRUNGEN"

    30 Print"TEST"



    Achja, völlig vergessen. Die künstlichen CLRs rausnehem und mit dem Austrosoeed E5 Kompilieren und testen.

    Achja, das RT-Modul natürlich auch patchen oder den Kopierschutz aus dem Basic Code entferenen.

  • Wer schon immer wissen wollte, wie der
    Kopierschutz der "Heureka Teachware"
    Lernsoftware funktioniert,hier ist
    die Beschreibung dazu.

    Du hast dann in dem Anhang dazu geschrieben:


    Quote

    Es ist auch möglich den Kopierschutz zu deaktivieren :-)

    oder wer im cracken gut ist, decompiliert das Programm

    und entfernt den Kopierschutz.

    Ich habe in meinem dekompilierten ALI V4 nachgesehen, wie ich das gemacht habe (was jetzt nicht heißen soll, dass ich im Cracken gut bin).

    In Zeile 9330 wird in kl ein Messwert eingelesen, der dann in 9433 ausgewertet wird.

    Ich habe den P-Code dann so geändert, dass folgendes draus wird:

    Code
    1. 9433 pokeob,0 : rem (po=0andkl>25.4)+(po>0andkl<33.6)

    Man sieht also schön, dass da eine Toleranz, was den Messwert angeht, vorhanden war.

    Wahrscheinlich bedeutet po=0 Zeitnahme bei dem einen Track und po>0 bei dem anderen.


    Achja, da war noch was:

    Code
    1. ; ------------------------------------ ; checksum routine
    2. 11064 pokeob,0
    3. 11067 pokeob+1,p%
    4. 11072 pokeob+2,j
    5. 11077 pokeob+3,p
    6. 11082 rem sys52968
    7. 11090 j=0:REM j=-1e+09+peek(ob)+256*peek(ob+1)+256^2*peek(ob+2)+256^3*peek(ob+3)-zz
    8. ; ^- patched
    9. 11134 pokeob,j<>0
    10. 11139 return
  • Wer sowas kann, ist im Cracken gut. Du hat ja sicherlich den Text im Intro des andern ALI V4 Cracks gelesen?

    Achja, deine Änderungen im P-Code von ALI V4 musste ich vor dem Decompilieren wieder rückgängig machen. Alle Decopiller hatten das nicht richtig übersetzen können.

    Das wäre auch ein Antidecompilierschutz.


    Das mit der Tolleranz hatte ich mir schon gedacht, weil der Speed meistens von Track 2 und immer von Track 31 gelesen wird. In den beiden Tracks ist je ein Sektor mit einem Illegalen Speedwert, der so hoch ist, dass der Gesammtwert auch über dem des Defaultwertes liegt. Die 1541 kann das zwar noch gut lesen, aber aufgrund der Elektronik ( maximales Timing) kann dieser Speedwert

    nicht geschrieben werden. Die Heureka-Software wurde damals mit Programmierbaren Kopiermaschinen vervielfältigt.

    Die Speedflagwerte hatte der kompilierte Basic Code dann aus dem Floppypuffer gelesen und verglichen. Zudem wird natürlich auch ein Teil des P-Codes in der Prüfung mit einbeschlossen, damit man ja nichts ändern kann. Diese Vergleichsroutine hast du Ausgetrickst.



    Siehe Codefenster.


    Zeile 8982 führt bei Nichtbestehen der Abfrage, in eine Endlosschleife. Bleibt noch 8932 nach Zeile 23796 oder 8954 mit RETURN.

    Ich würde einfach die Zeile 8864 komplett entfernen und durch ein RETURN ersetzen.



    PS: Bei deinem ALI v4 Crack auf der CSDB, bin ich der dritte Kommentrschreiber "more release please, from Heureka Teachware"


    Code
    1. 8864 js=-1e+09+peek(ob+10)+256*peek(ob+11)+256^2*peek(ob+12)+256^3*peek(ob+13)
    2. 8909 ifjs<>lhthenpokeyx,y*nt:ifpeek(28282)<>17thenpokeyx,y
    3. 8932 ifjs<>lhthenpoke214,211:goto23796
    4. 8946 ifpeek(ob+2)<69thenreturn
    5. 8954 pokeob+1,0
    6. 8959 pokeob+2,65
    7. 8965 pokeob+3,0
    8. 8970 pokeob+4,5
    9. 8975 lh=882703904
    10. 8982 goto8035
  • robak29



    Weiter mit "Let's Go 5" Letztes Kapiltel.:)


    Nun habe ich den BasicCode von allen nutzlosen Fake-Codes befreit. Zudem auch den BasicCode der komplette Protection-Abfrageroutine entfernt.

    Danach habe ich das Basic Programm mittels Austrospeed E5 kompiliert. Beim Original, den Heureka Trackloader entfernt und alle Einzeldateien auf

    ein D64-Images gespeichert. Die kompilierte Datei in "LEA" umbenannt und auch in das D64 eingefügt. Getestet und funktioniert.:)8)


    Das einzige, was man am Basic Code noch verbessern könnte, wären die ganzen nutzlosen "FOR...NEXT" schleifen. Zeile 10195 und Zeile 10306 können kommentarlos entfernt werden. Um alle durch

    einen Decompilerbug erstellen xx=yy zu finden, bitte mit dem Notepad++ alle "FOR" Befehle durchsuchen. Damit wird der Basic Code um mindestens zwei Blöcke kürzer.:)




    10195 nn=co

    10197 for nn=co to cu step2


    10306 jj=0

    10308 for jj=0 to tc-1


    Anhang: Der Crack auf D64 und die dazugehörige Basic-Datei.



    Achja, fürs bessere Arbeiten mit Notepad++ habe ich mir die ASM- und BASIC Darstellungen angepasst.

  • Und wie bist Du denn darauf gekommen, dass Du Zeile 22808

    Code
    1. 22808 iflen(df$)<8ordf$(1)=chr$(10)+chr$(5)orleft$(df$,1)="("thendt=0:gosub16368

    so anpassen musst:

    Code
    1. 22808 iflen(df$)<8ordf$(1)=(chr$(10)+chr$(5))orleft$(df$,1)="("thendt=0:gosub16368

    Gab's da einen Syntax-Fehler beim kompilieren?

  • Wie ich darauf gekommen bin, das so zu ändern. Erfahrungswerte sind das. Ich habe mitlerweile soviel (de)compiliert und teilweise echt exotische Bugs gehabt, die vergesse ich nicht.


    der Bug war ein "type mismatch error"


    Ja, den Bug, wenn es überhaupt einer ist, kenne ich. Das passiert öfters mal. Wenn man nicht genau Bescheid weiß, was da zu machen ist, einfach einen anderen Decompiler testen.

    Ich code ja schon seit etwa einem Jahr, mit Unterbrechungen an einem Decompiler, der etwa 98% bis 99% fehlerfreien BasicCode erstellt. Dieser ist zu etwa 90% fertig.


    Austrospeed E1 mag das, siehe unten, nicht. Wobei nur das "-1e" den CompileError verursacht. Damit das nicht passiert, müssen alle "-e1" in Kammern gesetzt werden. :)


    8864 js=-1e+09+peek(ob+10)+256*peek(ob+11)+256^2*peek(ob+12)+256^3*peek(ob+13)

    8864 js=(-1e)+09+peek(ob+10)+256*peek(ob+11)+256^2*peek(ob+12)+256^3*peek(ob+13)

  • Der "wilde Klammernsetzer" Decompiler hat das fehlerfrei decompiliert. Kein Wunder, wenn um jeden Ausdruck oder Vorzeichen oder was weiß ich nicht, der BasicCode mit Klammern zugemüllt wird.:)


    22808 if(((len(df$)<8)or(df$(1)=(chr$(10)+chr$(5))))or(left$(df$,1)="("))then:dt=0:gosub16368



    Du wolltest auch was über Extension wissen.


    Im Bild unten, siehst du die Datei "Start" vom Spiel Demon's Winter. Was hier auffällig ist, ist die "2082". Davor steht ein #$9e, der Basic-Token für SYS. Also "SYS 2082"

    Damit wird das Runtime-Unterprogramm gestartet, um Extensions abzuarbeiten. Die Extensionkennung ist #$47 und die Art der Extension ist #$21.


    Simon's Basic hat z.B. die Kennung #$47,#$64

  • Der "wilde Klammernsetzer" Decompiler hat das fehlerfrei decompiliert. Kein Wunder, wenn um jeden Ausdruck oder Vorzeichen oder was weiß ich nicht, der BasicCode mit Klammern zugemüllt wird.:)


    22808 if(((len(df$)<8)or(df$(1)=(chr$(10)+chr$(5))))or(left$(df$,1)="("))then:dt=0:gosub16368

    Ich selbst setze gernal mal eine Klammer zu viel, als eine zu wenig. Das verstehen dann auch Leute wie ich, die die ganzen Operatoren-Präzedenzregeln (jede Programmiersprache kocht hier zwar ein ähnliches, aber eigen gesalzenes Süppchen) gerade nicht parat im Kopf haben. Hat auf das Kompilat jedoch keinen Einfluss, solange kein Optimizer seine Finger im Spiel hat.

    Dieser Thread ist für mich ab sofort der heilige Decompilier-Nachschlage-Thread!

  • Gut, lieber eine Klammer zu viel, als nachher einen Compile error. Das Decompilat ohne Klammern ist 132 Blocks lang und das mit Klammern ist 144 Blocks lang. Der Größenunterschied,

    das sind nur die Klammern. Das Compilat wäre damit auch zu lang, und würde bei "Let's Go 5" andere Daten überschreiben. Klammern setzen ja, aber das ist zuviel das Guten.:)



    PS: Wovon ich immer träume, wäre ein P-Code Compiler mit 24Bit Adressierung. Dann könnte man den P-Code in der SCPU, ab Bank $02 also $020000 ablegen.

    z.B. 19,02,de,32 -> GOTO $02DE32