--==>> [Lesson Information] <<==--

 >DudeZ Cracking TUTORiAL  >Lesson #2

-==[What]==-

 > Roland Garros '98
 > Published by Microfolie's

-==[Type of Protection]==-

 > SecuROM v3b1 (Sony DADC)

-==[Toolz]==-

 > SoftIze v4.00 - THE debugger (SI!!! E' uscito... correte!)
 > WinDasm32 v8.93
 > Roland Garros '98 - L'originale o la copia
 > ...a brain ;-D
 > a box of Marlboro cigaretts...;-D

 N.B. : Il CD di cui sono in possesso Φ la versione
        in iTALiANO e RG983DFX.EXE Φ lungo 1.204.224 bytez.
  

for more information: Dudez@freemail.it


In Aprile (mamma mia come passa il tempo...per≥ potrei crackarlo, chi mi da una
mano?!) avevo promesso il tut per Need For Speed ][ SE, ma a pensarci bene, credo 
che per quello basti un piccolo schemetto...per i keygen...eheh... avevo promesso
anche quelli, in effetti io ho tutti gli appunti per≥ il tempo per scrivere
keygen-tutz non Φ molto... comunque sia ho trovato uno po' di tempo per scrivere
questo, a mio avviso qualcosa di molto pi∙ particolare ed impegnativo...giα giα...
si tratta di *SecuROM v3b1*! 
Molti di voi non sanno che per vedere se un CD Φ protetto da SecuROM, molto
spesso basta prendere il CD originale, rovesciarlo, leggere quello che sta scritto 
sotto... se vedete anche un logo tipo "DADC" o "Sony DADC" o ancora "Sony DADC Austria"
state tranquilli che quel CD Φ maledettamente protetto da una firma digitale stampata 
con processi particolari nel CD.


** Facciamo un po' di storia **

La Sony scrisse il suo SecuROM per abbattere la pirateria in maniera definitiva,
ma se fosse realmente riuscita nel suo intento, IO non starei qui a scrivere 'sto 
TUT... quindi... 
Brevemente... so perfettamente che questa versione di SecuROM Φ mooolto vecchia
(v3b1) pero' vale comunque la pena di sapere come funzioni, no?! In questo modo 
apprezzerete MOOOLTO di pi∙ il loader dei Laxity per SecuROM v4 et simili.

  **   **   **   **   **   **
 
PerchΦ quando, inserita la COPIA del CD nel lettore, lanciando il gioco non
parte?! PerchΦ mi da un messaggio che non trovo nelle STRF con WinDASM?! 
(Tengo a precisare che nelle ultime versioni di SecuROM, la Sony Φ cos∞
gentile che nemmeno vi da un messaggino...carino, no?! TANTO NON VI SERVONO!).
Durante la copia "fatta in casa" del CD originale, vengono copiati tutti i dati
e tecnicamente il CD funziona:
il vero problema Φ che non viene copiata la firma digitale impressa nel CD (si
narra alla Sony che l'impronta digitale Φ REALMENTE l'impronta del dito pollice 
di uno degli autori della protezione...) cosa che viene automaticamente rilevata
all'avvio del gioco/applicazione (v. OMNIA'99 e compagnia bella ;-DD). L'eseguibile
Φ criptato e si decripta durante l'esecuzione, ecco spiegato perchΦ aprendolo in
WinDASM, non sempre il codice corrisponde a quello visto in SoftICE. Generalmente 
(almeno nelle versioni pi∙ recenti) SecuROM decripta 3 VOLTE dei pezzi di codice 
anche se il CD non Φ inserito oppure se nel lettore c'Φ quello copiato, quindi la
prima parte della decriptazione Φ indipendente dalla firma. La cosa carina Φ che
se inseriamo il CD originale viene decriptata un'altra porzione di codice 
(che fanno 4) mentre col copiato restiamo a 3 ed il gioco non ne vuole sapere di 
funzionare. Ora ci sarebbero due modi di procedere: il 1░ consiste nel metodo 
illustrato in questo tut, il 2░ sarebbe quello di procedere essenzialmente in 
questo modo:

  - Recuperare il codice decriptato dal CD originale;
  - Inserirlo nell .EXE del CD copiato;
  - Fixare la routine di decrypt nell .EXE copiato altrimenti 'hangherebbe'
subito;

Vi chiederete: come facciamo noi a scovare il codice decryptato, ma sai kuante
kakkio di righe di codice ci dobbiamo scialaquare?!
NO! Sappiamo benissimo che il programma scrive in memoria parti di se stesso e
le modifica (decrypt) e sappiamo che il caro Bill Gates ha implementato nelle APi 
la funzione "WriteProcessMemory", e allora, perchΦ non la usiamo?! Sulla mia 
"APi Huge Guide" dicono che quando sulla funzione Φ attivo un breakpoint, ci≥ che 
succede Φ questo:

  - ESP+08: indirizzo di destinazione;
  - ESP+0c: indirizzo sorgente;
  - ESP+10: lunghezza dell'area da copiare;

Bene direi! Abbiamo tutto...tranne un DUMP per Soft-iCE v4.00 ma credo che se
andate nella meravigliosa pagina dei Toolz dei RingZ3r0, troverete iCEDUMP5 che fa
al caso vostro (un po' di pubblicitα, dai....). Termino qui la spiegazione del 2░ 
metodo perchΦ non appena avr≥ fra le mie mani un CD originale protetto da SecuROM
credo che scriver≥ un TUT su questo metodo, molto pi∙ fine...

Credo di poter cominciare ora.
Prendete la copia di Roland Garros '98 ed installatelo. Fatto?! Bene,
procediamo. Fatevi una copia del file RG983DFX.EXE (io ho usato questo, ma il 
procedimento vale anche per RG98.EXE).
Avviatelo e noterete un temporaneo caricamento dal CD seguito dal messaggio
"Disc verification error (3)".
WOW! Carini alla Sony... non ci mettono nemmeno la caption alla finestrella...fα
lo stesso...
Bene... ora apritelo con il Symbol Loader e caricatelo...
ci sarα del codice invalid ma andate avanti tranquilli fino alla CALL 47DC9E:
qui premete F8, ancora INVALID,
ma avanti comunque con F10 fino a 47CC71 (non riporto qui il listato perchΦ
WinDASM fa casino in questo punto).
Okkey.. giunti a 47CC71, possiamo proseguire prestando attenzione al pezzo di
codice che ci si pone davanti fra poche righe, esattamente a 47CCD0:


:0047CCD0 FF154CC54800            call [0048C54C]
:0047CCD6 85C0                    test eax, eax
:0047CCD8 7517                    jne 0047CCF1
:0047CCDA FF1570A34800            call [0048A370]        <--- questa CALL viene
eseguita raramente;
                                                                presumo (1) per
decriptare il codice iniziale
                                                                e (2) per
decriptare il codice finale, per
                                                                la comparazione.
E' alquanto complicato capire la CALL [0048A370], ma proseguiamo, ricordando che
la abbiamo saltata!
Dopo un po di stepping, arriveremo al seguente codice, MOOLLTOO importante,
anche se non lo modificheremo...
Fermatevi di steppare giunti a 47CEBA e guardate:

:0047CDCB FF15F0C44800            call [0048C4F0]         |
:0047CDD1 8B0DF0BA4800            mov ecx, [0048BAF0]     | Questo pezzo di
codice non serve, ma lo
:0047CDD7 81E100080000            and ecx, 00000800       | ho riportato
volutamente per la somiglianza
:0047CDDD 85C9                    test ecx, ecx           | con gli
altri...vedete come ci si puo'
:0047CDDF 0F85BA000000            jne 0047CE9F            | confondere
facilmente in questi casi?!
[...]
:0047CEBA A1B89D4800              mov eax, [00489DB8]
:0047CEBF 2500020000              and eax, 00000200
:0047CEC4 85C0                    test eax, eax
:0047CEC6 7517                    jne 0047CEDF
:0047CEC8 FF1570A34800            call [0048A370]        <--- ve la ricordate
questa?! Ebbene, la salta ancora!
[...]
:0047CEDF 8B0DB89D4800            mov ecx, [00489DB8]

^^^^^^^^^^^^^^
e giungiamo qui!

Come abbiamo constato, Φ una CALL che si ripete sempre, e se abbiamo visto bene,
finora la salta sempre!
Mmmm...Φ strano.. perchΦ mai la salterα sempre?!
Steppiamo ancora, non per molto perchΦ ci fermeremo alla riga 47CEDF dove
potremo notare:

:0047CEDF 8B0DB89D4800            mov ecx, [00489DB8]
:0047CEE5 81E100200000            and ecx, 00002000
:0047CEEB 85C9                    test ecx, ecx
:0047CEED 7517                    jne 0047CF06
:0047CEEF FF1570A34800            call [0048A370]        <--- e come poteva
mancare?! Ovviamente verrα saltata!

Steppiam, steppiam che bello debuggar la-la-la-la-la-la-la-la, la-la, la-la (da
'+ORC ed i 7 newbies' ;-D)
Fermiamoci 47CF92 e vediamo che c'Φ di carino...uhmmm ancora coding
'apparentemente' assurdo...

:0047CF92 8B0DB89D4800            mov ecx, dword ptr [00489DB8]
:0047CF98 81E1FFFFFBFF            and ecx, FFFBFFFF
:0047CF9E 890DB89D4800            mov [00489DB8], ecx
:0047CFA4 EB12                    jmp 0047CFB8

....ma aspetta...EHI!! Guardate quel JMP... ora guardate ECX: viene modificato
con un AND ECX,FFFBFFFF e poi passato alla routine sotto... e scommettiamo che a 47CFB8
ci sarα anche la CALL che viene sempre saltata?!
Vediamo... steppate fino a 47CFB8, osservate:

:0047CFB8 A1B89D4800              mov eax, [00489DB8]   <-- ricordate ECX di
prima!?
:0047CFBD 2500000400              and eax, 00040000     <-- ecco cosa se ne fa!
:0047CFC2 85C0                    test eax, eax
:0047CFC4 7517                    jne 0047CFDD
:0047CFC6 FF1570A34800            call [0048A370]       <-- non poteva mancare!
ma questa volta...
:0047CFCC 6A07                    push 00000007
:0047CFCE E8DDD8FFFF              call 0047A8B0                
:0047CFD3 B807000000              mov eax, 00000007     <-- ehi!! Ma che fa! Ma
cos∞ esce con EAX #7!!!!
:0047CFD8 E9D9010000              jmp 0047D1B6          <-- Esce dalla routine


WOW!! Che bello! Adesso abbiamo da lavorare NOI!! Allora allora... abbiamo visto
che questa volta la CALL viene eseguita ed immediatamente dopo, c'Φ un passaggio 
di valori nello stack con PUSH 00000007, una CALL che provvederα ad informarci 
dell'errore ("Disc verification error (3)") ed un MOV EAX,00000007 seguito da un 
bel JMP lontano lontano... che sarα mai?!
Bene... questa parte controlla il CD con la firma e decripta di conseguenza,
altrimenti esce con EAX=7, cioΦ "Disc verification error (3)". Mmmm... rifacciamo
tutto da capo, ma questa volta fate in modo che il salto "jne 0047CFDD" alla 
riga 47CFC4 venga effettuato, ci siamo?! Pronti di nuovo?! VIA!
Per ora siamo riusciti a passare, ma attenzione, steppate con gli occhi ben
aperti, il pericolo Φ sempre in agguato! Dai scherzo.. ora potete steppare 
tranquillamente fino a 47D05B dove noterete le seguenti righe:

:0047D05B 8B0DB89D4800            mov ecx, [00489DB8]
:0047D061 81E1FFFFFFFE            and ecx, FEFFFFFF
:0047D067 890DB89D4800            mov [00489DB8], ecx
:0047D06D EB12                    jmp 0047D081

Come prima...WOW!! solo che cambia un "addendo" dell'operatore logico, FEFFFFFF
anzichΦ FFFBFFFF...bhe..
cavoli loro. A noi invece, interessa di pi∙ quel bel JUMP 47D081 che Φ mooolltoo
simpatico...vediamo un po' dove ci porta...

:0047D081 A1B89D4800              mov eax, [00489DB8]   <-- passa in EAX ci≥ che
ha fatto con ECX
:0047D086 2500000001              and eax, 01000000     <-- anche lui se lo
gioca per benino...
:0047D08B 85C0                    test eax, eax
:0047D08D 7517                    jne 0047D0A6          <-- ehi... non salta
neanche ora...BAD GUY!
:0047D08F FF1570A34800            call [0048A370]       <-- e di conseguenza la
esegue...BAD GUY!
:0047D095 6A08                    push 00000008
:0047D097 E814D8FFFF              call 0047A8B0
:0047D09C B808000000              mov eax, 00000008     <-- Esce con EAX #8!
:0047D0A1 E910010000              jmp 0047D1B6          <-- Esce dalla routine

[...]
[...]


:0047D1B6 5F                      pop edi
:0047D1B7 5E                      pop esi
:0047D1B8 5B                      pop ebx
:0047D1B9 8BE5                    mov esp, ebp
:0047D1BB 5D                      pop ebp
:0047D1BC C3                      ret


Bene... ora anche il JNE 47D0A6 ci mette il bastone fra le ruote, ma noi
possiamo modificare a piacere, cos∞ da bypassare anche questa pezzetto...;-))
Una volta giunti a 47D08D (vale anche per 47CFC4) scrivete "r fl z" e passerete
lisci come l'olio...
Se volete potete anche scrivere "a" e poi "JMP 47D08D", oppure sovrascrivere la
riga

:0047D081 A1B89D4800              mov eax, [00489DB8]

con la riga

:0047D081 A1B89D4800              mov eax, 01000000

....come vedete le vie sono molte...a voi la scelta. Ci siete fin qui?! Dai
forza...
Riguardate il codice in 47D095, qui ci farebbe uscire con EAX #8...ma ora siamo
passati...

Ora ci addentreremo nella seconda parte della sprotezione, quindi vedete di
effettuare le modifiche fin qui descritte... se non avete voglia di cercarvi 
gli offset...

  -  7BFC4h    un bel JUMP...
  -  7C08Dh    anche qui un bel JUMP...
 
Fatto?! Bene...
Se tutto Φ corretto... quando lanciate l'eseguibile opportunamente modificato,
il messaggio d'errore che
vi appare dovrebbe essere "Disc verification error (2)".

* NON ALLARMATEVI * Questo Φ dovuto al fatto che abbiamo crackato soltanto una
parte... per la veritα la pi∙ facile...

Okkey... sono andato a mangiare qualcosina... cicca... e via!
Ora dovrete ri-steppare tutto perchΦ i breakpoint qui non funzioneranno, quindi
arrivate fino a 47D134, quindi entrateci premendo F8...WOW! Quanta schifezza!
Bene... ora dovrete steppare, eccome! Io vi consiglio di fare una cosa: quando
vedete che si sono dei loop molto grossi, cercate il punto in cui il codice vi
rimanda a capo, al di sotto del JMP che vi rispedisce in cima solitamente potete
mettere un breakpoint e proseguite con F5 molto cautamente per non perdervi la
parte pi∙ bella, ma MOOOLLTTTOOOO pallosa...Sicuramente arriverete in un punto
come questo:

:0047B43A A340C54800              mov dword ptr [0048C540], eax
:0047B43F C78504FFFFFF00000000    mov dword ptr [ebp+FFFFFF04], 00000000
:0047B449 EB0F                    jmp 0047B45A
[...]
:0047B45A 83BD04FFFFFF0A          cmp dword ptr [ebp+FFFFFF04], 0000000A
:0047B461 0F8DD9020000            jge 0047B740
:0047B467 C7856CFEFFFF00000000    mov dword ptr [ebp+FFFFFE6C], 00000000
:0047B471 EB0F                    jmp 0047B482


Perfetto! Se siete riusciti ad arrivare fin qui, il gioco Φ fatto!
E' indispensabile guardare il vostro codice in Soft-iZE e non il mio.. 
io lo ho preso da WinDASM, ma Φ diverso, e potreste confondervi; guardate quindi 
gli indirizzi... con quelli non vi sbagliate di sicuro!
Arrivate fino a 47B461 e noterete che non salta affatto...BENE!!
Questa Φ l'ultima modifica da fare... cambiate in un JUMP 47B740 quel JGE e
vedrete che tutto andrα liscio come l'olio...in kulo a SecuROM!!!!!!!

Riporto gli offset dove apportare le modifiche:

 - 7BFC4h - piazzate un bel JMP;
 - 7C08Dh - anche qui piazzateci un bel JMP;
 - 7A461h - JUMP anche qui;

Quando modificherete all'ultimo offset (7A461h per intenderci) noterete che il
codice cambierα notevolmente al di sotto del nostro JMP; non preoccupatevi, 
funziona anche cos∞, ma fareste meglio ad aggiungere un NOP.

Il gioco Φ fatto ragazzi... ora possiamo creare il nostro PATCH personale.
Qui di seguito riporto il mio, non prendetelo assolutamente come esempio di
coding perchΦ lo ho fatto in fretta prima di andare via (Φ tardi!!!), ma rende 
molto felici i possessori di una copia del gioco non funzionante per lo 
stramaledetto SecuROM!

{ Non ho commentato praticamente nulla nel sorgente, ma mi sembra dirvi troppo,
non vi pare?!}

===========================================================================CUT HERE


; Model ASM-PATCHER
; Patching byte of your appZ!
;               DudeZ [NRG]

..MODEL TINY
..386
..DATA

;*************************************
;TExT Z0N3!!

INTRO   DB      0AH, 0DH, '+---------------------------------+'
        DB      0AH, 0DH, 'ª     Roland Garros ''98 -iT-      ª'
        DB      0AH, 0DH, 'ª             DudeZ/NRG ''99       ª'
        DB      0AH, 0DH, 'ª---------------------------------ª'
        DB      0AH, 0DH, 'ª  This crack remove the SecuROM  ª'
        DB      0AH, 0DH, 'ª   protection from RG983DFX.EXE  ª'
        DB      0AH, 0DH, 'ª       long 1.204.224 bytes      ª'
        DB      0AH, 0DH, '+---------------------------------+', 0AH, 0DH
        DB      0AH, 0DH, ' _-Opening RG983DFX.EXE','$'
FILE    DB      'RG983DFX.EXE', 0
HANDLE  DW      0

;PATcH RESOURcE!

Patch1  DB      0EBh,0
Patch2  DB      0E9h,0DAh,02h,00h, 00h,90h

;END PATcH RESOURcEí
;iNiT MESSAGEz & GREETiNGz!

NotFound DB     0Ah,0Dh,' File RG983DFX.EXE not found. Shutting Down Crack...',
0AH, 0DH, '$'
Cracked DB      0Ah,0Dh,' Roland Garros ''98 -iT- 3DFX Succesfully Cracked!'
        DB      0Ah,0Dh,' Enjoy another [NRG] Crack!'
        DB      0Ah,0Dh,' by DudeZ [NRG]'
        DB      0Ah,0Dh,24h
       
;MESSAGEz & GREETiNGz! TERMiNATEí

;**Cominciamo a scrivere...vα!**

..CODE

        ORG     100H

;Parte - 1 -

START:
        LEA     EDX, [INTRO]
        CALL    PRINT
        LEA     DX, [FILE]
        MOV     AX, 3D02H
        INT     21H
        MOV     [HANDLE], AX
        CMP     AX, 02H
        JNE     WRITE
        LEA     DX, [NOTFOUND]
        CALL    PRINT
        JMP     EXIT

;1░ modifica

WRITE:
        MOV     BX, HANDLE              ;  -> BX <- HANDLE of the FiLE!
        MOV     CX, 0007h                 ; <-- 0007:BFC4h
        MOV     DX, 0BFC4h             ; <-- Offset to modify to...
        MOV     AX, 4200h
        INT     21H
        MOV     CX, 01h                 ; <-- What can i write?!
        LEA     DX, [PATCH1]            ; <-- Maybe...PATCH1?!?
        MOV     AH, 40H
        INT     21h

;2░ modifica

        mov     bx,handle
        mov     cx,0007h
        MOV     DX, 0C08Dh
        mov     ax, 4200h
        int     21h
        MOV     CX, 01h
        lea     dx,[patch1]
        mov     ah,40h
        int     21h

;3░ modifica

        mov     bx,handle
        mov     cx,0007h
        MOV     DX, 0A461h
        mov     ax, 4200h
        int     21h
        MOV     CX, 06h
        lea     dx,[patch2]
        mov     ah,40h
        int     21h
               
;Chiudi File! WOW!

        MOV     AX,3E00h
        int     21h
        LEA     edx,Cracked
        CALL    PRINT

;FiNE CRACKiNG!

EXIT:
        MOV     AX, 4C00H
        INT     21H

PRINT   PROC
        MOV     AH, 09H
        INT     21H
        RET
PRINT   ENDP

GET     PROC
        MOV     AH, 0AH
        INT     21H
        RET
GET     ENDP

END START




========================================================================== CUT HERE


Ringraziamenti:

 - Kill3xx - per la meravigliosa idea di costruire una pagina simile e di permettere
             il 'postaggio' dei vari TUTz...
         
 - Siccome non conosco praticamente nessun'altro di voi... fatevi sentire in e-mailz!

 DudeZ@Freemail.it