IL BUCO DELLA CHIAVE

Data

by " STHAKO "

 

10/08/2003

UIC's Home Page

Published by Quequero



Grazie tante sthako, questo tutorial risponde alla domanda: "posso crackare una dongle senza la dongle?" E la risposta e': Si se la dongle non va a leggere nella chiave dati che servono a decrittare/eseguire il programma, in tal caso... Devi avere almeno una dongle "buona", in caso contrario sthako vi ha mostrato come si fa :)


Ho due passioni nella vita ...

...

... la seconda e' il computer

Difficolta'

(x)NewBies ( )Intermedio ( )Avanzato ( )Master

 


il buco della chiave
trombare una hasp senza cercare i codici
Written by Sthako

Introduzione

Dopo un anno e mezzo di studio del linguaggio assembler mi propongo di affrontare la protezione hasp, lo so sarebbe un po' presto (sono partito da zero) ma provare non e' sbagliato anzi, puo' solo aiutare a capire il comportamento dell'assembly . Vorrei incitare i newbies come me a fare tutorial , non potete credere quanto si impara a farne uno. Per motivi personali ho modificato leggermente il nome del programma con le sue dll ed ho rinominato tutte le label,in fin dei conti lo scopo e' quello di far capire come si puo' sviare questo tipo di protezione.

Tools usati


Softice 4.05
HexWorkshop v2.54

URL o FTP del programma


Il programma in causa e' PC_MISW e non si trova in rete

Notizie sul programma


Questo programma e' un softwere di misurazione tridimensionale , misura entita' geometriche tramite un apparecchio di misurazione , viene venduta la licenza con la chiave hasp ed un CD (io sono venuto in possesso solo di una copia del cd).
La chiave viene messa tra la macchina ed il pc attraverso porta LPT.
 

Essay

Partenza!
Facciamo girare il prog, dopo un po' esce fuori la classica messagebox che ci dice che la chiave non c'e' (key missing error -4).
Settiamo un breakpoint (naturalmente con sice) sulla porta parallela BPIO -h 378 RW e rimandiamo in esecuzione il prog. Poco dopo sice poppa e vediamo che e' breccato in HASP9_DL.vxd togliamo il breakpoint e F12 finche' non compare M_HASP.dll.Attenzione perche' il tut si basera' quasi tutto su questa dll .In genere (ho letto in giro) ogni chiave hasp ha una dll che si interpone tra il programma principale e drivers di periferica della chiave hardwere :

M_HASP.dll

       push       dword ptr [esi]
       call         [kernel32!DeviceIoControl]      ;leggi la chiave
       cmp        eax,  0                                ;<- ritorno dalla lettura (EAX=1)
       jz           10014E16                             ;salto non interessante

Settando EAX a 0 va a leggere procedure di errore oppure i codici della chiave,non ho ben capito, d'altronte sono solo un newbie, piu' avanti con un po' di piu'esperienza, faro' il resto, ora pero' volevo far vedere come qualche programmatore possa chiudere una procedura con una porta blindata a doppia serratura (chiave hasp) e magari lasciarne un'altra socchiusa , ed e' li che mi propongo di entrare, anche perche', credo che la cosa piu' difficile sia rendere le modifiche effettive, e non entrare in un prog con l'ausilio di sice !

Ora continuiamo a premere F12 finche' atterriamo qui:

M_HASP.dll

       jnz         10012943
       push       ebx
       call        100126A4
       cmp        eax, ebx               ;<-ritorno dalla call (metto un breakpoint)
       jnz         10012948              ;calcio in culo

Al ritorno dalla call 100126A4 compara EAX con EBX dove EAX e' FFFFFFFC (-4) ed EBX e' 0 .
La cosa migliore, secondo me, sarebbe quella di modificare EAX, quindi R EAX 0, e premo F5 (giusto per vedere cosa succede).
Per un po' di volte il prog brecca dopo la call 100126A4 ed in eax c'e' sempre quel -4 ed ad ogni breack modifico sempre EAX a 0 affinche' non provochi il salto ed alla fine esce lo stesso messagebox che dice sempre key missing ma con l'errore -3 ! Bene (o quasi)!Ricominciamo daccapo,in fin dei conti la pazienza e' la virtu' dei forti. Startiamo di nuovo il prog finche' poppa al primo breakpoint.Quindi premo F12 (p ret) per 2 volte e...

M_HASP.dll

         call        10012F5D
         cmp       eax, edi                          ;<-ritorno dalla call (metto secondo breakpoint)
         jnz       1001265A                         ; altro calcio in culo

E che troviamo in EAX?Ma naturalmente FFFFFFFD (-3) ed EDI e' a 0.Quindi editiamo r EAX 0 per non far saltare ed F12 finche' non trovo il programma principale!

         call          [00D4C14C]                             ;chiama la dll hasp
         cmp          eax,ebx                                  ;<- compara nuovamente eax con ebx
         mov         [edi+00000CC0],eax                  ;lo salva
         jnz           00808BCC                               ;calcio in culo definitivo

Ora, se non avessi azzerato EAX ,ci sarebbe il codice di errore nella procedura di lettura della chiave,jnz indica che se la chiave e' ok il risultato deve essere 0,ecco perche' azzero EAX nei due breakpoints.Il salto condizionato poi porta alla messagebox che indica l' errore nella lettura della chiave (-3 o -4).
Continuo a ridare il controllo al prog con F5, questo pero' poppa piu' volte sui due break creati(probabilmente ci sono verifiche in varie porzioni del caricamento del prog) ed ogni volta modifico EAX 0 (r EAX 0) e ad un certo punto,compare l'interfaccia utente del prog, (segno che qualcosa e' andato a buon fine ovvero qualcosa e' stato sprotetto ) continuo a dare F5 e ad azzerare EAX ma alla fine mi ritrovo una nag screen in cui devo immettere i codici della chiave espirata (4 password)l'ID key, causa di tutto:data scaduta (expiration date).
Altra grana da risolvere! Aggiungo un'altro breakpoint, POSTQUITMESSAGE , questa api di solito chiude un programma, (o qualcosa del genere).Chiudo col bottone quit il nag screen, e ... mi ritrovo nel programma principale:

                 call         [00D3F119]                           ;call che richiama la dll hasp
                 add         esp,0C                                 ;<-ritorno dalla dll
                 mov        [ebp-10],eax                         ;mette EAX (0) in ebp-10
                 cmp         dword ptr [ebp-10],00            ;lo confronta con 0
                 jnz          0079505A                             ;(salto buono)
                 ...
                 ...
                 ...                                                      
                 ...
                 call         [USER32!PostQuitMessage]       ;fino a qui ***<- si atterra qui
0079505A    cmp       dword ptr [ebp-10],FFFFFFFF     ;lo riconfronta con -1
                 jnz          00795100                              ;(salto buono)
                 ...
                 ...
                 call         [USER32!PostQuitMessage]
00795100    mov        dword ptr [ebp-04],FFFFFFFF
                 ...

Al ritorno della call [00D3F119] EAX e' uguale a 0 il salto jnz 79505A se non avviene comporta la lettura della call PostQuitMessage.Anche nel secondo salto (jnz 795100) succede la stessa cosa e mi sembra che ,se invece EAX fosse 1 tutto andrebbe a buon fine , quindi a quel punto basterebbe cambiarla (r eax 1) e....
...Incredibile!Il prog si apre e funziona!

Potrei essere soddisfatto ma sai che palle andare a cambiare EAX ongi volta per aprirlo? Punto della situazione:
Il prog puo' essere aperto modificando solo la dll,basterebbe cambiare il valore di EAX nei due breakpoints con 0 (probabilmente 0 indica che la chiave fisicamente c'e').Poi modificare sempre EAX con 1 (credo che 1 indichi la verifica finale ,e cioe' i codici chiave hardwere sono OK ,praticamente dovrebbe saltare la lettura dei codici). Ma come andarla a modificare? Cerco a questo punto dove EAX diventa -3;-4,0 e vedo quel che si puo' fare.
Metto un breakpoint nella call 100126A4 faccio ripartire il prog.Quando poppa entro nella call con F8 e proseguo finche' non vedo in EAX FFFFFFFC e... ecco cosa compare verso la fine della call:

M_HASP.dll

                 cmp     eax,FFFFFF87     ;confronta EAX con vari codici di errore (?)
                 jz        10001651           ;e li manda in quel posto
                 cmp     eax,FFFFFF8D     ; se non e' nessuno
                 jz        10001651           ; di questi
                 push     FC                    ;salva nello stak FC(-4)
                 pop      eax                   ;e lo poppa in EAX
                 jmp      100029A6          ;facendolo rimanere fino all'uscita
                 ...                               ;della call
                 ...
                 ret

A sinistra del codice si vede il rispettivo esadecimale

   100018A        6AFC        push        FC
   100018B        58            pop        eax

Sempre con sice provo a modificare quel FC: all'indirizzo 100018A push 00(a 100018A push 00). Ora la dll e' modificata per questa sessione,naturalmente prendo nota del codice esadecimale in sequenza per andarlo a modificare poi in maniera definitiva con un editor esadecimale, cambiando 6AFC in 6A00,quindi andra' a salvare nello stak 00 per popparlo in EAX. Procedo nella stessa maniera per individuare l'FD (l'errore -3) trovando questo:

M_HASP.dll

                push      FC
                pop       eax
                jmp
                ...
                ret

Stessa minestra!..E fin qui mi sembra abbastanza facile.Ora non rimane che trovare la procedura del nag screen (e' un programmetto exe che sta dentro alla dir del prog, avviabile anche separatamente).
Metto un breakpoint nella call [00D3F119] e proseguo con F8 finche' trovo questo:

M_HASP.dll

                call      PRENDI_DATA_HASP ;il flag Z non e' attivo
                add     esp, 0Ch
                cmp    eax, 01
                jnz      10001CC7                ;quindi salta
                push    dword ptr [ebp-24h] ;anno
                push    dword ptr [ebp-28h] ;giorno
                push    dword ptr [ebp-2Ch] ;mese installazione hasp
                ...
                ...
                jmp      10001CED              ;salto che puo' andar gia' bene
10001CC7   cmp     [ebp+8], ebx          ;EBP+8=0 EBX=0
                 jz       10001CEB              ;salto non buono
                ...
                ...
                ...
                push     01                       ;perche' salva 01 nello stak
                pop      eax                      ;per popparlo in EAX
                jmp      10001DB2              ;per mantenerlo fino alla ret
10001CEB   xor       esi, esi
10001CED   cmp     esi, ebx                 ;data valida?
                jnz      10001D99               ;salto buono
                push     ebx
                push     offset data ;         ;data
                ...
                ...
                call      CUSTODEHASP        ;<--il programillo del nag screen
                ...
                jz        10001DC1
10001D99   ...
                ...
10001DB2   ...
                ...
                ret                                   ;ritorna al prog principale
                ...
                ...
10001DC1   ...                                   ;fa ritornare al prog princ
                ...                                   ;con EAX=1 (questa e'la strada
                ...                                   ;percorsa originariamente)
                ret




Il percorso originale prevede,uscendo dalla call PRENDI_DATA_HASP di saltare allindirizzo 10001CC7 non andando a leggere la data installazione hasp.Se non saltava sarebbe andato tutto a buon fine lo stesso, ma solo per una serie di coincidenze fortuite (non lo spiego perche' sarebbe troppo lunga la storia ).
All'indirizzo 10001CC7 compara [EBP+8] con EBX dove [ebp+8]=0 (in sice d ebp+8 e nel data window compare l'indirizzo chiamato,alla sua destra il suo valore)ed in EBX 0.Il flag di Z e' attivo in origine, quindi il salto ( JZ 10001CEB ) lo va a fare. Proseguiamo e vediamo che xora esi,quindi ESI = 0,comparandolo di nuovo con EBX (!!!) che e' sempre rimasto a 0.
Il flag di Z si attiva proseguendo (JNZ 10001D99 non esegue il salto) andando a leggere la CALL CUSTODEHASP ovvero il nagscreen sopra citato.
Torniamo all'indirizzo 10001CC7 , se il salto (JZ 10001CEB) non dovesse avvenire, andrebbe a salvare 01 nello stak per popparlo poi in EAX , subito dopo c'e' il salto incondizionato (JMP 10001DB2) e quindi RET ,che porta al prog principale con EAX = 1, condizione che mi ero preposto di ottenere in modo da ottenere i due salti per evitare le chiamate PostQuitMessage sopra citate.
Credo che la cosa piu' giusta da fare sia noppare CMP [EBP+8], EBX e JZ 10001CEB (dannazione alla mia lameraggine, quel EBX=0 (!!!) avrei dovuto seguirlo di piu').
Quindi:


          395D08         cmp      [ebp+8], ebx
          741F             jz         10001651

Sostituisco 395D08 con tre nop che diventano 909090 e 741F con altri due nop (9090), il tutto con un editor esadecimale.
Il programma a questo punto e' craccato definitivamente!
Se qualche malpensante pensava che da " il buco della chiave " si potesse vedere qualche donna ignuda beh... mi dispiace , vi rimando al sito del Quequero sezione XXX.

                                                                Sthako

Note finali

Lanciando il prog,nella fase di caricamento,si nota un forte rallentamento, ma quando l'interfaccia utente e' aperta gira regolarmente. Probabilmente il primo check della chiave, se fosse andato a buon fine leggendo anche i codici,avrebbe memorizzato da qualche parte quest'ultimi e letti nei check sucessivi,senza aprire di nuovo la chiave con hasp95dl.vxd e quindi in maniera hardwere. Altro piccolo rallentamento si vede all'apertura di un file ed in ? about program dove compare il numero di serie (al posto del numero ci sono dei puntini) e la versione del prodotto.Tutto sommato tutti i comandi sono abilitati e posso dire con grande soddisfazione di essere riuscito a craccare la protezione , vabbe' c'era un buco grande ed io ci sono finito dentro ma d'altronte un po' di fortuna non guasta!.

Ringraziamenti

Vorrei infine ringraziare tutto il fantastico gruppo della UIC ,che mi sta insegnando ad essere padrone del mio pc , a darmi la possibilita' di capire come funziona a livello di zeri e uni, e a tutto quello che mi insegnera' in futuro.
Grazie di cuore!

Disclaimer

Vorrei ricordare che il software va comprato e  non rubato, dovete registrare il vostro prodotto dopo il periodo di valutazione. Non mi ritengo responsabile per eventuali danni causati al vostro computer determinati dall'uso improprio di questo tutorial. Questo documento e' stato scritto per invogliare il consumatore a registrare legalmente i propri programmi, e non a fargli fare uso dei tantissimi file crack presenti in rete, infatti tale documento aiuta a comprendere lo sforzo immane che ogni singolo programmatore ha dovuto portare avanti per fornire ai rispettivi consumatori i migliori prodotti possibili.

Noi reversiamo al solo scopo informativo e di miglioramento del linguaggio Assembly.