** Warme Worte im Vorraus **

  Hallo und Herzlich Willkommen zum ersten Crack Tutor von xCrk'98.

  Dies ist hoffentlich mal ein Tutor, der sich sehen lassen kann, und 
  ganz besonders den Neuanfaengern in Deutschland weiter helfen wird.

  Ich hoffe es stoert nicht wenn zum Ende zu immer groesser Spruenge
  in den Erklaerungen sind. Auch "Aber", "Also", "Jetzt" und "Nun" am
  Satzanfang sollten Euch nicht stoeren.



** Grundlegendes zum Tutor **

  Gibt es nicht viel, einfach immer weiter diesen Text nach unten 
  scrollen, die zum Text passenden Bilder werden automatisch ange-
  zeigt.



** Was zum Anfangen benoetigt wird **

  Als erstes sollte Ihr mal die Seite von Lord Caligo besuchen.  
  
    http://www.nettaxi.com/citizens/caligo/cracking.htm

  
  Dort muesst ihr folgende Programme herunterladen:
  
    * W32DSM v8.9
    * Hiew 5.84

              
  Dann wird noch der DCC (Dos Command Center) benoetigt, der Norton
  Commander oder aehnliches geht auch, aber der DCC ist perfekt.
  Den DCC gibts unter:
  
    http://www.emerge.de

        
  Jetzt werden noch zwei kleine ganz wichtige Programme benoetigt,
  zum einen einen Registry Monitor, zum anderen ein Datei Monitor
  (die brauchen wir heute zwar nicht, aber haben ist alles).
  Diese beiden Tools gibts bei Sys-Internals:
  
    http://www.sysinternals.com
    

  Programme die zum releasen des Cracks noch ganz nuetzlich sein
  koennen sind:
  
    * Visual C++ (oder irgend ein anderer C++ Compiler)
    * ZipMagic '98 (http://www.mijenix.com)
    * AcidDraw (damit kann man nette NFO's malen)
    * eine (meine) Crackengine (xCrk@Bigfoot.com)
      oder eine von Lord Caligo... oder selber eine schreiben
      

      
** Welches Shareware Programm soll dran glauben? **

  Entweder eines, welches Euch gefaellt, oder eines welches gerne
  jemand gecrackt haben moechte, oder eines von diesen tollen
  Sharewareseiten hier:
  
     http://top-download.de
     http://www.sharepaper.com
     

  Aber ich habe mich heute mal fuer Second Copy 97 entschieden.
  Wo ihr das findet?
  
     http://www.centered.com
     

  Wie ich ausgerechnet darauf gekommen bin? Wei ich auch nicht,
  lag halt auf Sharepaper rum...
  
  Jetzt meckert nicht gleich rum wie: das braucht doch keiner,
  dafuer gibts ja einen Regkey, warum Cracken und nicht gleich
  ein Regkey hacken?
  
  Weil: Diese Crackmethode bei >50% der Shareware Programme geht.
  


** Fangen wir mal an! **  

  Als erstes sollte man immer mal abchecken wie das Programm
  eigentlich geschuetzt ist. Was immer gut ist, ist ein Programm,
  wo man einen Regkey eingeben kann. Ein Programm wo man keinen
  Key eingeben kann, und welches zusaetzlich noch eingeschraenkte
  Funktion hat, sollte man lieber nicht ansehen - weil man an die
  fehlenden Funktionen eh nicht ran kommt (aber versuchen schadet
  nicht!).
  Es ist auch immer hilfreich zu wissen in welcher Programmier-
  sprache ein Programm geschrieben ist.
  Hier ist mal meine persoenliche Crackbarkeits-Hitparade nach
  Programmiersprachen:
  
                  1. Visual C++ (32-Bit)        ~95%
                  2. Delphi (32-Bit)            ~60%
                  3. Borland C++ (32-Bit)       ~50%
                  4. Visual Basic 5++           ~0%
                  
  Diese Hitparade gilt fuers Cracken mit W32DSM, 16-Bit geht da von
  vorherein nicht, Visual Basic erzeugt Laufzeitfehler. Mit SoftIce
  kommt man da natuerlich viel weiter, vielleicht erzaehle ich im
  Tutor 5 mal was dazu.
  
  Wie man rausbekommt welche Sprache? Mit einem DLL-Checker kann man
  schauen welche DLL's genutzt werden. VC++ nutzt die Standard 
  Windows Bibliotheken (SHELL32.DLL KERNEL32.DLL MFCxx.DLL...).
  Visual Basic die VB*.DLL's. Und Delphi erkennt man am "besonderen" 
  (bescheuerten) Assembler Code.
  
  Das alles fuer unser Second Copy '97 v5.30 build 85 ergibt:
  
    * Keyeingabe moeglich
    * wahrscheinlich VC++ geschrieben (na das wird einfach!)

    
  Sieht also alles ganz gut aus.

  

** Schritt 1: Vorbereiten **

  Geht ganz schnell:
  
    * Second Copy 97 installieren (in temporaeres Verzeichnis)
    * Copy zum Cracken anlegen (am besten CRK.EXE)
    

    
** Schritt 2: Disassemblieren **

  Das bedeutet: Wir wollen das sehen was der Rechner versteht.
  Achtung: Wer keine ASM-Kenntnisse hat sollte sich vielleicht
  doch erst man welche aneignen.
  
  Wenn Ihr wisst was PUSH, POP, CALL, RET, MOV, LEA, TEST, CMP,
  alle arten von Jumps (zumindest die top 4: JMP, JMPS, JE, JNE)
  ist duerft ihr weiterlesen.
  
  Jetzt aber mal los: Disassemblieren, geht mit dem W32DSM.
    
  folgende Menuschritte:

    -> W32DSM89 -> Disassembler -> Open File to Disassemble..
    -> SC97.EXE oeffnen -> ... warten ...
    -> Disassembler -> Save Disassembly Text File..


  und das Projekt wieder laden (so merkt er sich die Breakpoints
  nach einen Neustart des Programmes)...

    -> Project -> Open Project File...
    


** Schritt 3: Die richtige Stelle finden! **

  Das soll heissen die Stelle wo entschieden wird ob registriert
  oder nicht. Diese muss es geben - weil irgendwo muss ja festgelegt
  werden ob Vollversion oder Shareware. Hier gibt es zwei Wege
  diese Stelle zu finden (es gibt natuerlich noch mehr, aber diese
  zwei nehme ich fuer gewoehnlich).

    
  Vorher noch etwas Theorie zur richtigen Stelle!
  
  Also, die richtige Stelle ist nicht immer dort wo der Vergleich 
  einer Variablen (eines Registers, Speicherstelle) mit einem Wert,
  und dem daraus resultierende Sprung (zur Shareware-
  Version oder zur Vollversion) stattfindet, sondern dort wo
  die Variable gesetzt wird. Und das sind "immer" Funktionen die
  aufgerufen werden, und einen Entscheidenden! Wert zurueck liefern,
  oder setzen. (Heute dreht es sich ums zurueckliefern, Programme
  die einen Wert setzten sind eher selten!)
  
  Erklaerung (in C++):
    Routine zum Checken des Key sieht oft so aus:
    
             bool IsValidRegKey(char *name, int key) {
                if (key == ok)
                    return (true);
                else
                    return (false);
             }

             
    Und ein Hauptprogramm koennte so aussehen:

             int main(void) {
                 LeseConfig();
                 if (IsValidRegKey(cfg.name, cfg.key) == false) {
                     ... Nags ... Blub ... Blah ...
                 }
                 
                 // das ist natuerlich nicht so in C++
                 // aber nur der Erklaerung wegen!
                 if (MenuPunkt_RegKeyEingeben == ausgewaehlt) {
                     -> name einlesen
                     -> key einlesen
                     
                     if (IsValidRegKey(name, key) == true) {
                        ... irgendwo in Registry speichern,
                            oder in der .INI
                        ... eine kleine Erfolgsmeldung
                     } else {
                        ... Meldung das Key falsch war
                     }
                 }
             }

    
    Das ganze sieht in Assembler natuerlich etwas anders aus,
    die Check-Routine "IsValidRegKey":
    
    
             push        ecx           ; sieht besser aus ;-)
             push        edx

             .
             .
             .
                          
             ; wuester asm code zum checken ob code richtig
             ; diesen  erkennt man oft an: einfachen befehlen
             ; wie addieren, rollen, schieben oder Gleitkomma-
             ; operationen (die sind aber schwer ;-)
             
             .
             .
             .
             
             ; und meistens hat diese ASM-Routine zwei (oder
             ; mehr) ausgaenge
             
             cmp        ecx, 12345678h  ; z.b. key zu gro
             jle        [falsch]
             
             cmp        edx, 12345678h  ; z.b. Key-Quersumme falsch
             jne        [falsch]
             
             ; hier waere man gelandet wenn key richtig ist
             ; und da bei richtig ein true zurueckgegeben werden
             ; soll, und rueckgabewerte immer in eax (16Bit: ax)
             ; (na gut auch al) sind, und da true in C++ <>0 be-
             ; deutet geben wir eine "1" zurueck
             mov        eax, 1
             
             ;und eben zurueck
             pop        edx             ; sieht besser aus ;-)
             pop        ecx
             ret
             
             [falsch]
             ;hier landet man bei falschem key!
             xor        eax, eax        ; kuerzer als mov   eax, 0!
                                        ; bewirkt aber das gleiche!
             ;und auch zurueck
             pop        edx             ; sieht besser aus ;-)
             pop        ecx
             ret
    
                                   
    Und die Aufrufe im Hauptprogramm aeussern sich so in ASM:
     
             push       [etwas]         ; jeder push vor dem Call
             push       [etwas]         ; ist ein uebergebener
                                        ; parameter, und wir haben
                                        ; halt zwei
             call       [IsValidRegKey]
             test       eax, eax        ; cmp eax, 0 ist das gleiche!
             jne        [falscherKey]   ; auswerten was rueckgabewert
                                        ; beinhaltete und jenachdem
                                        ; springen
             

             
             
                          
  *#+?\*#+?\*#+?\ so das muss erst mal verdaut werden! *#+?\*#+?\*#+?\

  
  
  
    
  Und jetzt die beiden Wege:
    
  Weg 1:  Key-Check nach Versuch einer Keyeingabe (welche zu 100%
    schief geht), oder bei Nag-Message (Wie: "Das geht nur in der
    Vollversion")
    
  Weg 2:  Key-Check bei Programm-Start

    
  Hier kurz ein paar +/- fuer die einzelnen Wege:
    
  Weg 1:
    + leicht zu finden, da oft eine Meldung (Falscher Key) kommt
    - schwer zufinden, weil der eingegeben Key gar nicht nach der
      Eingabe geprueft wurde, sondern erst nach dem Neustart
      des Programmes (also Weg 2)
    - manche Shareware Programme sagen nicht das Key falsch, oder
      lassen nur drei Eingaben zu
    - was manchne Programmierer auch machen: Key-Testen, und viele
      unwichtige Vergleiche machen um den Cracker zu aergern (weil
      er erst rausfinden muss wo ist der "wichtige" Vergleich ist)
      (ich glaube aber nicht das irgendein Shareprogrammierer so
      schlau ist und das ausnutzt!)
    + viele Programmierer sind bloed, die nutzen zwar die letzten
      beiden Nachteile aus, aber vergessen Ihre Nags (die bloeden
      "Du darfst das nicht in der Testversion" Sprueche) auch dem 
      entsprechend zu schuetzen
    + manche sind ganz bloed und schreiben in einer DLL eine 
      exportierte Funktion mit dem Namen CheckeObKeyRichtig, solchen
      Leuten kann ich dann wirklich nicht mehr helfen!
      
  Weg 2:
    - man muss lange den Source-Code durchtracen bis man so was
      findet
    + der KeyCheck ist garantiert irgendwo am Angang
    
    
  Da wir Second Copy 97 mit Weg 1 cracken werden ist Weg 2 fuer einen
  folgenden Tutor aufgehoben.

    
  Also fangen wir an die Stelle zu suchen.
    * Programm im W32DSM starten, mit Strg+L
    * Kommandozeilenargumente... Enter

    
  Jetzt ist der Debugger scharf und das Sharewareprg so gut wie Tot!

    
  Beim abchecken des Programmes wird Euch bestimmt die Meldung
  
      "Invalid Registration Key..."
      
  aufgefallen sein, wenn Ihr versucht habt einen falsche Key einzu-
  geben. Dieser Spruch hilft uns schon maechtig weiter, weil der
  W32DSM faehig ist uns zu sagen wo dieser String verwendet wird.
  Das geht so:
  
    -> Menu:Refs -> String Data References
    
  Es oeffnet sich ein Fenster mit allen Strings die irgendwo im
  Programm verwendet werden.
  Uns interessiert ja nun der "Invalid Registration Key..."-String,
  den suchen wir in der List, und machen einen Doppelklick mit der
  Maus drauf. Daraufhin springt der Cursor im W32DSM Hauptfenster
  zur ersten Stelle wie eine MOEGLICHE!! Referenz mit dem String ist.
  In unserem Fall ist das die Adresse [004618AF], durch nochmaliges
  Doppelklicken wuerde die naechste String-Refernz gesucht. In diesem
  Fall gibt es (zu unserer Freude) nur eine. So, jetzt muessen wir
  ASM lesen, und zwar von unten nach oben.
                          ~~~~~~~~~~~~~~~~
    -> mov    dl, 01            ... unwichtig
    -> mov    cx, word prt []   ... unwichtig
    -> push   00000000          ... unwichtig
    
    -> ein bedingter Sprung kommt von irgendwo, das ist doch ein
       gutes Zeichen!
       
  Schaune wir nach von wo, aha von [00461883]
    
  gehen wir mal dahin...
    
  da lesen wir das da:
    
       call  00403F24     ... eine Funktion wird aufgerufen
       test  eax, eax     ... ist der rueckgabe wert 0?
    -> jle   004618A4     ... wenn <=0 dann springe [zu der Fehler-
                              meldung!]
       
  sieht ja ganz gut aus das ganze. Also lassen wir das Programm
  mal bis dahin laufen. Um das Programm dort zum stehen zu bringen
  muessen wir da einen Breakpoint setzen. Das geht mit F2,
  die Zeile wird gelb. Jetzt lassen wir das Programm
  loslaufen (mit F9), und bringen es moeglichst zu unserem Break-
  point -> Falschen Regkey eingeben. Und "Register" druecken.
    
  BAFF BUMM das Programm stoppt! Wie wir es wollten.
    
  So, wir stehen nun bei dem JLE, da wir den Sprung verhindern 
  wollen mssen wir die Bits die den bedingten Sprung leiten,
  so aendern das der Sprung nicht ausgefuehrt wird.
   
  JLE ... JUMP IF LESS OR EQUAL (zu 0 weil vorher TEST EAX, EAX)
            |                 
          springt wenn ((SF XOR OF) OR ZF) = 1
          d.h.
          
<<<<<<<<<<  BITMAP:CRK_MOD_FLAG  >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

          wenn Vorzeichen-Flag (SF) oder Ueberlauf-Flag (OF), aber
          nur eines der beiden! oder das Null-Flag gesetzt ist
          wird gesprungen.
    
  in unserem Falle stehen die Bits (0 xor 0) or 1 = 1 also springe!
  Das muessen wir jetzt mal schnell verhinden, also auf "Modify Data"
  druecken, das ZF-Flag loeschen (weil die Bedingung ja nur dadurch
  erfuellt wird). Mit "Modify" werden diese Aenderung aktiv. Jetzt
  gehen wir mit F7 mal einen Befehl weiter. Und sehen das der Sprung
  nicht erfolgte. War es das jetzt? Lassen wir uns Ueberraschen!
  Also Programm weiterlaufen lassen (mit F9).
    
  Wie? Was? jetzt oeffnet sich die Hilfe? Das war wohl nicht richtig. 
  (Diese Stelle musste in den Tutor rein - weil in allen Tutorials
  die ich bisher gelesen habe waren nur Erfolgsmeldungen nach dem
  ersten Modify zu verzeichnen, aber so einfach ist Cracken nun
  auch nicht.)

  Also weitergehts. Der bedingte Sprung war es auch noch nicht.
  Nach genauer ASM-Analyse stellen wir fest:

    * vor der "Invalid..."- String Referenz geht es nicht weiter,
      also der Sprung JLE 004618A4 muss ausgefuehrt werden
        
    * gehen wir da weiter hoch...
      
    * bei :00461866 kommt wieder ein bedingter Sprung, und weil 
      eine Zeile vorher auch ein JMP 00461856 steht, muessen wir von
      da (da = :00461756) kommen, also gehen wir dahin...
        
      scrolle, scrolle scrolle
      
<<<<<<<<<<  BITMAP:CRK_ISVAL_CALL  >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

  Dort steht jetzt wieder ein JLE 00461866. Analysieren wir die 
  drei Befehle vorher:
    
      Call  00460B24     ... Call ist immer gut, koennte ja
                             die IsValidRegKey-Funktion sein
      mov   esi, eax     ... aha, den Rueckgabewert sichern
                             (ist auch nicht schlecht!)
      test  esi, esi     ... da esi = eax wird der Rueckgabewert
                             gecheckt
      jle   xxxx         ... springt wenn der rueckgabewert <=0
                             ist, man erinnere sich:
                                  TRUE <> 0 (in C++) und >0
                             waere immernoch TRUE
                               
  Wir setzen uns jetzt wieder einen Breakpoint auf den JLE (mit F2),
  und lassen das Programm weiterlaufen (mit F9). Wieder einen 
  falschen Key eingeben, und "Register" druecken. 
  
  BUMMS * BLAUTZ * BAENG
    
  W32DSM bleibt bei unserem neuen Breakpoint stehen. Schauen wir
  uns mal den Rueckgabewert EAX an, aha, der ist 0. Also springen
  wir ja direkt nach unten zu unserer "Invalid Key..." Meldung.
  Da wollen wir aber nicht hin! Also versuchen wir was neues, mal
  nicht einfach dem JLE so manipulieren das er nicht springt,

<<<<<<<<<<  BITMAP:CRK_MOD_EAX  >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

  sondern einen Breakpoint auf MOV ESI, EAX. (Wir manipulieren
  gleich mal den Rueckgabewert, mal sehen was es bringt). D.h.
  F9 weiterlaufen, falschen Key eingeben. Irgendwann stoppt der
  W32DSM bei MOV ESI, EAX. Jetzt wird der Rueckgabewert EAX mit
  "Modify Data" auf > 0 (da springt er ja nicht) geaendert. Nehmen
  wir 5, das reicht.
    
  So, jetzt ein paar mal F7 - Step Into, und siehe da wir springen
  nicht! Yeah - Erfolgserlebnis. Lassen wir das Programm weiter-
  laufen (mit F9).

<<<<<<<<<<  BITMAP:CRK_SUCCESS  >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

  Na Wahnsinn Leute, seht Euch die MessageBox an! Wir haben so-
  ebend eine 5 (so ein Zufall unsere 5 ist wieder da) User Lizenz
  ermogelt.
    
  Was machen wir jetzt?

            
** Schritt 4: Programm veraendern **

  Wie zum Abschluss bei Schritt 3 festgestellt haben wird an der
  Adresse :0046174D eine Funktion aufgerufen wird, welche irgendetwas
  macht, und die Anzahl der Lizenz-User zurueckliefert.
  Man erkennt weiterhin, das wenn <=0 User zurueckgeliefert werden,
  der Key als falsch gewertet wird!
    
  Was koennen wir damit anfangen?
    
  Einen Crack! Im W32DSM wird nun der Cursor auf den CALL 00460B24
  gebracht, und der "Call" Button gedrueckt. Der W32DSM geht nun
  in die gecallte Funktion rein. Dort sehen wir das sie vier mal
  aufgerufen wird. Seht Ihr Leute, wir haetten den JLE nach dem
  CALL "ausNOPen" koennen, aber was haetten wir davon, wenn an noch
  drei anderen Stellen eine (fuer uns) Fehlentscheidung getroffen
  wird. Was wir daraus lernen -> die CALL Funktion muss so geaendert
  werden das sie den von uns gewuenschten Wert zurueckliefert (z.b.
  eine 5, besser eine 123456789, die Lizenz reicht fuer die halbe
  Welt!)
  
  Und das machen wir mit dem Hiew. Also 
  
    C:\..\..>Hiew crk.exe
    
  eingeben. F4 -> Decode, jetzt sehen wir das ganze Programm in
  Assembler! Schoen. Jetzt schauen wir mal in die Statuszeile des
  W32DSM das steht am Ende "@Offset 0005FF24h in File SC97.exe".
  Das ist dort wo die Call Funktion beginnt. Fuer uns soll sie ja
  dort enden, aber den richtigen Wert zurueckliefern. Sprich da muss
  ein  "MOV EAX, 00BC614E"  und ein  "RET"  hin.
  Das geht im Hiew. Erst mal gehen wir mit F5 zur Funktion, die
  Adresse ist 5ff24. Flott eingegeben und Enter. Der Hiew springt
  dahin, und was sehen wir die gleiche Befehle wie im W32DSM. Aber
  die wollen wir ja eh nicht haben. Also F3 fuer Edit Mode.
  Und F2 fuer ASM-Edit. Jetzt geben wir unsere neuen Befehle ein:
  
       mov eax,075bcd15 (enter) ... Rckgabewert manipulieren
       ret (enter)
       
  einige Zahlen aendern sich, und werden gelb. Jetzt wollen wir das
  Programm so speichern (mit F9). ESC und weg ist der Hiew.
  Was wir jetzt haben ist eine geaenderte EXE. Hoffentlich laeuft sie.
  (Keine Angst, frueher oder spaeter werdet Ihr festellen, das es
  nicht immer so einfach geht wie hier!)
  Starten wir mal die Crk.exe.
  
  Freu, lauuft einwandfrei, ohne Nags. Info/About... wow da steht 
  zwar noch unregistriert, aber eine 123456789 User Lizenz.
  Wem das reicht der kann hier aufhoeren.
  
  Fuer die etwas haerteren Cracker machen wir das natuerlich auch
  noch weg.



** Schritt 5: "Uns" ins Programm einbringen **

  Dafuer brauchen wir jetzt den DCC (der hiew geht auch, aber
  ich erklaere das fuer den HEX-Edit vom DCC).
  
  So, DCC starten, und die CRK.EXE mit Alt+F4 im Hex-Editor oeffnen.
  F7 Suchen -> nach "UnRegistred" suchen, das wird dann auch an Stelle
  0061BB8 gefunden. Das Ueberschrieben wir jetzt mit unserem Namen.
  z.B. "xCrk'98", weil das kuerzer ist als "UnRegistred" fuellen wir 
  die ungenutzen Zeichen mit Blanks, oder auf der HEX-Seite mit 00.
  
  Das gleiche kann man auch noch mit der Homepage-URL und der E-Mail
  Adresse machen.
  

  
** Den Crack releasen **

  um die Unterschiede zwischen Original und Crack zu finden gebt Ihr
  
    FC /b SC97.EXE CRK.EXE
    
  der listet fein saeuberlich die ganzen unterschiede auf.

  
  Jetzt seit Ihr gefragt:
  
    * Crack Engine schreiben, aber bitte mir Pruefsumme und Filesize
      checks.
      
    * NFO basteln! Mit cooler GfX! und etwas Text zum Programm.
      Datum, URL, Cracker, EMail Adresse gehoeren da auch rein!
    
    * eine File_id.diz erstellen
    
    * das ganze ZIPpen und releasen
    
  und wenn Ihr gut wart gibts sogar ein Feedback!
  

    
** Warme Worte zum Schluss **

  So, ich habe jetzt vier Stunden getippt, werde noch weitere zwei
  Bilder rippen und eine Stunde programmieren. Dann sollte der 
  Tutor fertig sein. 
  
  Ich hoffe Ihr habt kapiert!
  
  Jetzt sucht Euch ein Shareprogramm und macht es kapput!
  
  Fuer Anfaenger: (wo der Tutor hilft)
  
     * RecovertNT (www.sunbelt-software.com/recovernt.htm)
     * Anno 1602
     * Quake II <v3.15
     * alles von www.isdn4win.de

       
  Fuer Koenner:
  
     * TypoGraf 4.04 (www.neuber.com)
     * Yats v6.7 (www.dillobits.com)
     
  des waren zwei echt gut geschuetze Programme... aber habe
  ich dann irgendwann auch "gekauft"...

