



          1999 
               
                  
   

Cracking Tutorial #2
SmartCheck

(c) seaw0lf99-08
moral rights reserved.


Bentigte Software


   CoverPro v7.0.7 (beigelegt)
    http://www.directlogic.com

   VisualBasic6-Runtime fr CoverPro
    (siehe Schlusswort)

   Numega SmartCheck v6.01
    http://www.numega.com/products/aed/sc.shtml

   Beliebiger HEX-Editor
    z.B. Hacker's View / HIEW v6.xx

   DOS-Betrachter fr binre Dateien
    z.B. NC-Viewer oder FAR-Viewer

   Hirn v2.4 (wre zumindest recht praktisch)

   Assemblerwissen v1.0 (Build 25)



Einfhrung


Ich   hab   mich   endlich  mal  aufgerafft,  ein  Tutorial  fr  SmartCheck
zu  schreiben.  Fr  alle,  die  nicht wissen, was SC ist: Ein Debugger, der
speziell fr Visual Basic-Programme ausgelegt wurde.

`Geknackt  wird  heute  ein  rmliches  Shareware-Programm  namens CoverPro
v7.0.7  (ist  beigelegt;  COVER.EXE),  mit  dem  man  sich hbsche CD-Covers
ausdrucken  knnen  soll.   Naja,  unser  Ziel  ist  es,  das Programm so zu
patchen,  dass es sich auf unseren Namen registriert. Der Schwierigkeitsgrad
hierfr bewegt sich irgendwo zwischen sehr sehr einfach und witzlos einfach.
Gut, beginnen wir:



Schritt 1: Untersuchen der EXE-Datei


Es ist zunchst wichtig zu erkennen, womit ein Programm erzeugt wurde, ob es
verschlsselt  ist,  etc.  Zum Betrachten der Datei benutze ich den internen
Viewer  von  FAR.  Nehmt ihr vielleicht den Norton Commander-Betrachter oder
so,  was  eben da ist. Betrachtet die Datei aber nicht(!) unter Windows, und
unter  keinen Umstnden mit Word oder so. Es handelt sich hierbei ja um eine
Binrdatei.

Ein  kurzer Blick in COVER.EXE: Tja, da wre mal der Header. Win32-EXE-Files
erkennt  man erstens am Text "This program cannot be run in..." oder hnlich
Ausserdem sieht man immer Zeug, das in etwa so aussieht: .text, .data, .rsrc,
etc.  (oder hnlich).  Dies sind verschiedene Sektionen - fr uns jedoch un-
wichtig.  Manche Packer oder Encrypter (verschlsseln EXE-Files) ndern auch
die  Sektionsnamen.  Die eindeutig seltsamsten Sektionsnamen, die ich je ge-
sehen  habe,  werden  von  PE-Crypt  (by Random & Killa) erzeugt. Dort kommt
relativ oft ".ficken" vor. Naja ;-) Auch gut, oder? :))

Gleich darunter gibts oft einen etwas greren Abstand, nicht immer.

Nach dieser "Lcke" beginnt meistens schon der Code. Kleben hier die Zeichen
sehr  stark  aneinander  und kommen eher wenig einzelne Spaces vor,  so kann
man  davon  ausgehen,  dass  die  Datei  verschlsselt ist. Mit ein bisschen
bung erkennt man das aber sofort.

Unsere COVER.EXE ist also nicht verschlsselt. Gut, mehr wollen wir garnicht
wissen. D.h., wir knnen sie patchen.



Schritt 2: SmartCheck anwenden


Wir  starten  SmartCheck,  ffnen COVER.EXE und drcken [F5] um das Programm
zu  starten.  CoverPro  arbeitet  nun wie gewohnt, mit dem Unterschied, dass
Smart Check im Hintergrund alle Aktionen mitloggt.

Beim  Start von CoverPro kann es vorkommen, dass ein kleines Shareware-Fens-
terchen  anzeigt  wird.  Das  kommt  zufllig  vor,  und auch nur,  wenn das
Programm  nicht registriert ist. Jetzt solltest du ein Fenster mit dem Titel
"CoverPro  v7.0.7" vorfinden, mit hsslichem grnen Hintergrund. Ist das so,
ging  bis  hierher  alles  glatt. Schau dir jetzt mal "Registered to:" unter
"Help  | About" an. Eeeek: "Unregistered". Das geht aber wirklich nicht. Das
muss  weg.  Bedenke,  dass  SmartCheck  alles  mitloggt,  was  du tust.  Uns
interessiert  jedoch  "Help  | Register". Das probieren wir auch gleich aus.
Jetzt werden wir nach einem Namen gefragt. Tippe hier "seaw0lf" ein. Weiters
werden  wir  nach  dem  Key  gefragt.  Hier  tippst  du "1234" ein. So, neue
Message: "Invalid Name Or Key.". Klicke auf "OK" und schliesse CoverPro. Wir
haben jetzt alle bentig- ten Informationen im Kasten.

Zurck  in  SmartCheck  siehst du das Log, sofern du "View | Show Errors and
Specific  Events" gewhlt hast. Wenn du alles brav befolgt hast, sehen deine
"Program Results" folgend aus:

 1   [-] Thread 0 [thread id:xxxxxxxxxx (0xxxxxxx)]
 2       [] Event reporting started: xx/xx/xx xx:xx:xx
 3       [] frm_Main (Form) created
 4   [+] frm_Main_load
 5   [+] mnu_About_Click
 6       [] cmdOK_Click
 7   [+] mn_reg_Click
 8   [+] frm_Main_Unload

Gehen wir nun diese Resultate schrittweise durch:

 1   unwichtig (wirklich sehr unwichtig ;)
 2   unwichtig (das Datum und die Uhrzeit des Programmstarts)
 3   unwichtig (hier wurde das Hauptfenster `frm_Main erzeugt)
 4   unwichtig (hier wurde `frm_Main in den Speicher geladen)
 5   unwichtig (hier klickten wir den Menpunkt "Help | About" an)
 6   unwichtig (hier klickten wir in der Aboutbox auf "OK")
 7   Ahaaa, das der zweite Menpunkt, den wir anklickten. Logischer-
     weise handelt es sich hier um "Help | Register".
 8   unwichtig (Hauptfenster wird geschlossen & aus Speicher entfernt)

Punkt 7 interessiert uns also. Klick jetzt auf das [+] neben "mn_reg_Click",
um  das  Log  fr  dieses  Ereignis  einzusehen.  Gleich zu Beginn sehen wir
zweimal  "InputBox".  Hierbei  handelt  es  sich  um  die  zwei  VisualBasic
Eingabefenster, in denen wir um Name und Key gefragt wurden. Klicke zum Test
den ersten "InputBox"-Eintrag an und schau in die rechte Fensterhlfte. Dort
sollte jetzt erstens ganz oben "COVER.EXE!000xxxxx (no debug info)" zu sehen
sein.  Die  "xxxxx"  sind  die  Position  des InputBox-Aufrufes in der Datei
COVER.EXE.  Zweitens,  gleich darunter sehen wir den String "Enter your...".
Hier wurden wir also nach unserem Namen gefragt - interessant. Gut. In einem
anderen  Tutorial  knnte  man  erklren,  wie man aus dem Log mit ein wenig
Zauberei  einen  Keygen  schreibt.  Naja, schau dir weiters den Eintrag "Len
returns  LONG:xxx"  an. Rechts siehst du den String "seaw0lf". War das nicht
unsere   Eingabe,  hmm?  ;)  Jetzt  springen  wir  im  Log  runter  zu  "Val
returns...".  Der  Part dazwischen ist nur fr KeyGen-Schreiber interessant.
Rechts  sehen  wir nun den String "1234". Fruchtig! :) Das war unsere zweite
Eingabe. Und jetzt zum wichtigsten Teil:

Der  nchste  Eintrag  im  Log  lautet  "MsgBox  returns Integer:1". Blickst
du  wieder in die rechte Fensterhlte, so siehst du dort den String "Invalid
Name  or  Key". Dies ist der Text, welcher in der MessageBox angezeigt wird.
Wir  bentigen  jetzt  das  Dateioffset.  Dazu siehst du gleich darber, wie
bereits  vorhin  erklrt,  "COVER!0004D6AF (no debug info)". Tja, das ist so
quasi unser Startpunkt :)



Schritt 3: Das Problemkind suchen


Nachdem du dir das Offset notiert hast, kannst du SmartCheck beenden, da das
Log nicht mehr bentigt wird. Unseren Startpunkt haben wir ja.

Erstelle jetzt eine Sicherheitskopie von COVER.EXE. Am besten COVER.EXE-OLD.
Mit  HIEW  ffnest du nun COVER.EXE. Nachdem die Datei geladen wurde drckst
du [F4] und whlst den Modus "Decode".

Jetzt  springst du an das oben notierte Offset, indem du [F5] drckst, 4D6AF
eintippst  und [ENTER] drckst. Was erwarten wir? Einen CALL-Befehl, der die
MessageBox  ffnet? Genau! Mist, was soll jetzt dieser ADC-Befehl? Da stimmt
doch  was  nicht.  Anscheinend  stimmt das Offset nicht exakt und wir hngen
irgendwo  im  aktuellen  Befehl. Drcke jetzt die [UP]-Taste und schau dabei
links  auf  das Offset. Na sowas, jetzt steht da 4446AE statt 4D6AF. Das mit
der  seltsamen  neuen Addresse mchte ich jetzt nicht erklren. Ich sag nur,
so  neu  ist  sie  gar  nicht.  Wichtig  ist nur, dass das Offset nicht ganz
stimmte  und  wir  uns  nun  ein  Byte  vor der von uns gewnschten Addresse
befinden. Das Allerwichtigste ist jetzt aber, dass du folgendes siehst:

    .0044D6A5: 8D8D74FFFFFF         lea       ecx,[ebp][0FFFFFF74]
    .0044D6AB: 6A40                 push      040
    .0044D6AD: 51                   push      ecx
 -> .0044D6AE: FF1574104000         call      MSVBVM60.595
    .0044D6B4: 8D95B4FEFFFF         lea       edx,[ebp][0FFFFFEB4]
    .0044D6BA: 8D4DDC               lea       ecx,[ebp][-0024]
    .0044D6BD: 8985BCFEFFFF         mov       [ebp][0FFFFFEBC],eax

Der  CALL  greift sichtlich auf eine Funktion der VisualBasic-Runtime zu. In
unserem Fall MUSS ES die Funktion sein, welche die MessageBox anzeigt.

Aber  wonach  suchen wir jetzt eigentlich?  Was liegt am nhesten,  hmm? Ge-
genau.  Ein bedingter Jump, der darber entscheidet, ob der eingegebene Code
gltig  oder  ungltig  ist.  Kurz gesagt: wir suchen nach einem JE/JZ- oder
JNE/JNZ-Befehl.

Nachdem  dieser Jump sicher VOR der MessageBox zu finden sein muss, scrollen
wir  mal  schn langsam nach oben, wobei wir uns immer brav alle Befehle an-
sehen. Und nicht zu schnell scrollen, denn wir wollen ja nichts BERsehen.

    .0044D65E: 689C7E4200           push      000427E9C ;" B~"
    .0044D663: FFD6                 call      esi
 -> .0044D665: E98C000000           jmp      .00044D6F6   -- (1)
    .0044D66A: 8D95F4FEFFFF         lea       edx,[ebp][0FFFFFEF4]
    .0044D670: 8D8D74FFFFFF         lea       ecx,[ebp][0FFFFFF74]

Aha,  siehe da: ein Jump. Kann das unser gesuchter Sprung sein? Nein. Er ist
ja  nicht bedingt. Wir brauchen einen Jump, der, wie schon oben gesagt, ent-
sprechend  der  Gltigkeit  der Eingabe der Registrierinformationen zu einem
bestimmten Platz springt. Naja, scrollen wir eben weiter...

    .0044D574: 898544FFFFFF         mov       [ebp][0FFFFFF44],eax
    .0044D57A: 898D5CFFFFFF         mov       [ebp][0FFFFFF5C],ecx
    .0044D580: 898554FFFFFF         mov       [ebp][0FFFFFF54],eax
    .0044D586: 898D6CFFFFFF         mov       [ebp][0FFFFFF6C],ecx
    .0044D58C: 898564FFFFFF         mov       [ebp][0FFFFFF64],eax
 -> .0044D592: 0F84D2000000         je       .00044D66A   -- (1)
    .0044D598: 8D95F4FEFFFF         lea       edx,[ebp][0FFFFFEF4]
    .0044D59E: 8D8D74FFFFFF         lea       ecx,[ebp][0FFFFFF74]

Tja,  wie  es  aussieht,  haben wir das Problemkind gefunden ;) Das Programm
springt  hier  nur  weg,  wenn die Registrierinformationen falsch sind. Btw,
JE/JZ  bedeutet  so  viel  wie  (j)ump  if (e)qual bzw. (j)ump if (z)ero (in
beiden  Fllen  muss  das  Zero-Flag  gesetzt  sein). Daraus solltst du auch
gleich auf die Bedeutung von JNE/JNZ schliessen knnen.



Schritt 4: Datei patchen


Wir  wollen  also,  dass  unser Programm genau das Gegenteil macht: es fhlt
sich  registriert,  wenn  ein  falscher Code eingegeben wird. Logischerweise
wird  dann  einfach  aus  JE/JZ ein JNE/JNZ. Also gut, das machen wird jetzt
auch gleich.

In  HIEW  bewegst  du  den Cursor an den Anfang des zum JE-Befehl gehrenden
Opcodes, unten als  hervorgehoben.

    .0044D58C: 898564FFFFFF         mov       [ebp][0FFFFFF64],eax
 -> .0044D592: 84D2000000         je       .00044D66A   -- (1)
    .0044D598: 8D95F4FEFFFF         lea       edx,[ebp][0FFFFFEF4]

Hier drckst du nun [F3], um in den Editiermodus zu schalten, und anschlies-
send  [TAB],  um  den  Befehl zu ndern. Schliesslich ersetzt du im Eingabe-
fenster  JE  durch  JNE. Danach drckst du [ESC] und [F9], um die nderungen
zu  speichern.  Zauberei  beendet?  Nicht  ganz.  So sieht der Code nach dem
Patchen aus:

    .0044D58C: 898564FFFFFF         mov       [ebp][0FFFFFF64],eax
 -> .0044D592: 0F85D2000000         jne      .00044D66A   -- (1)
    .0044D598: 8D95F4FEFFFF         lea       edx,[ebp][0FFFFFEF4]

Was  macht  der JNE-Befehl jetzt eigentlich? Das Programm fhlt sich nun bei
falschen  Registrierinformationen  registriert.  Wenn  wir  nun aber gltige
Informationen eingeben? berleg mal.

Deswegen  folgendes: wir entfernen einfach den gesamten(!) bedingten Sprung,
berschreiben  ihn  also  mit  NOP-Befehlen.  NOP bedeutet (N)o (OP)eration.
In  HIEW  siehst du genau, dass der Befehl aus 6 Bytes besteht, indem du den
Cursor  nach rechts bewegst und dabei die Kstchen zhlst. Im Folgenden sind
diese 6 Bytes durch  markiert.

    .0044D58C: 898564FFFFFF         mov       [ebp][0FFFFFF64],eax
 -> .0044D592:          jne      .00044D66A   -- (1)
    .0044D598: 8D95F4FEFFFF         lea       edx,[ebp][0FFFFFEF4]

Mit  [F3]  schaltest  du  also nochmals in den Editiermodus. Diesmal drckst
du  jedoch  nicht  [TAB], sondern berschreibst die 6 Bytes hndisch mit dem
Opcode   des  NOP-Befehls,  also  mit  90.  Mit  [F9]  speicherst  du  deine
nderungen.

Das  Ergebnis:  Das  Programm  erkennt  nun ALLE Eingaben als gltig, sowohl
Falsche als auch Richtige. Nach diesem Patch sollte der Code so aussehen:

    .0044D586: 898D6CFFFFFF         mov       [ebp][0FFFFFF6C],ecx
    .0044D58C: 898564FFFFFF         mov       [ebp][0FFFFFF64],eax
 -> .0044D592: 90                   nop
 -> .0044D593: 90                   nop
 -> .0044D594: 90                   nop
 -> .0044D595: 90                   nop
 -> .0044D596: 90                   nop
 -> .0044D597: 90                   nop
    .0044D598: 8D95F4FEFFFF         lea       edx,[ebp][0FFFFFEF4]
    .0044D59E: 8D8D74FFFFFF         lea       ecx,[ebp][0FFFFFF74]

Das war auch schon alles! Das VB-Programm ist geknackt ;)



Schlusswort


Ich  muss  sagen,  solche  Programme  sind  es  bei Gott nicht wert, bezahlt
zu  werden.  Aber  dazu  sind ja wir Cracker da ;) Obwohl, ausser einem Nag,
gibts ja eh nichts zu entfernen. Ich habe dieses Tutorial absichtlich in die
Lnge  gezogen,  es  ist  ja  auch  fr  Newbies, die sich bereits ein wenig
Assemblerwissen  angeeignet  haben,  gedacht.  CoverPro habe ich in sage und
schreibe 30 Sekunden gepatcht (Start der Programme exklusive ;)

Das  Programm  ist  wirklich  ntzlich, um schnell CD-Covers zu drucken. Man
saugt  sich  einfach  aus dem Web von irgendwelchen Cover Sites irgendwelche
Covers  runter,  ldt das Front- und Backbildchen in CoverPro und schon kann
gedruckt werden. Echt klasse ;)

Es kann sein, das COVER.EXE nicht funktioniert. In diesem Fall fehlt dir die
VisualBasic6-Runtime.  Die  gibts  bei  Micro$hit  oder  sonst  wo. Folgende
Dateien werden bentigt:

 -> msvbvm60.dll
 -> oleaut32.dll
 -> olepro32.dll

Ich  wrde  mich auf Feedback freuen. Schickt einfach alles, was ihr auf dem
Herzen habt an seaw0lf@gmx.net (das ist eine Null, kein O :).



Viel Spass beim Tfteln,
seaw0lf.
