MJ-Studio 1.05
Ci vuole un seriale per trovare il seriale!


30/04/2000

by "AndreaGeddon"

 

 

UIC's Home Page

Published by Quequero

Nella mia pistola trover� l'obilo che � il solo rifugio...
Bravissimo Andrea (che mi fa sempre la cracka sul letto) hai fatto un tute davvero bello e soprattutto completissimo, mi complimento con te e non so come hai fatto a non uscirne pazzo, i calcoli erano quasi peggiori di quelli che Opera fa al serial, unica nota: ma le parentesi quadre le sai chiudere?? Perch� al posto di ] ci mettevi un |?? Sei un alternativo??? :)))
ps
Ho appena scoperto una cosa, vedete il pipe ( "|" ) sull'ultima riga? Vedete i due punti interrogativi ("??")? Beh, per una qualche illusione ottica (derivante dal fatto che l'occhio tende a vedere cose errate) il pipe sembra storto mentre � drittissimo, se vi interessa sapere il perch�...Beh, il cervello guarda il punto interrogativo che � storto e sono inclinate anche tutte le altre lettere, quindi per un principio di esclusione inclina anche il pipe.
... da quelle cose che non hanno nome e che non devono averne
UIC's form
Home page:  www.andreageddon.8m.com
E-mail: [email protected]
IRC chan:   #crack-it  /  #crack-it2
UIC's form

Difficolt�

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

 

Trovare il seriale di questo programma non � per niente facile: la routine assembler in realt� � di media difficolt�, ma il procedimento matematico per ricavarsi un serial esatto � praticamente irreversibile se non si conoscono a priori alcuni parametri. E' per questo che per risucrie a risolvere questo serial fishing mi sono dovuto appoggiare ad un serial giusto: ho dovuto vedere il comportamento dell'algoritmo e trovare l'ultimo parametro che mi mancava. Sono riuscito a spiegare matematicamente quasi tutto, a parte appunto l'ultimissimo passo. Credo comunque che con una buona conoscenza di matematica (e con una calcolatrice che sia capace di effettuare operazioni con numeri HEX con virgola) si possa spiegare anche l'ultimissimo passo.


MJ-Studio 1.05
Ci vuole un seriale per trovare il seriale!
Written by AndreaGeddon

Introduzione

Un programma per mixare gli mp3. Molto bello, non c'� che dire. Parte in "Restricted demo mode", ma noi vogliamo renderla full.

Tools usati

SoftIce

-  Fogli di carta

-  Molto tempo...

URL o FTP del programma

www.d-lusion.com/products/mj

Notizie sul programma 

Nome e serial number.

Essay

PARTE PRIMA:  LIBERIAMOCI DAI FASTIDI

Doh! Ogni volta che si esce dal prog viene caricato un file html con le istruzioni per registrarsi. Se chiudete e avviate continuamente il programma, la cosa � molto fastidiosa. Quindi basta cancellare (o rinominare) i file html nella directory del programma. Fuori un inconveniente. L'altro, � che mentre il programma � attivo ma non viene utilizzato, ad intervalli regolari manda un wave che dice "yo, gimme some to dance with" o qualcosa del genere. Registrate un wave vuoto, aprite il programma con Exescope, e andate a sostituire al wave "yo, gimme..." il vostro wave vuoto. Cos� non vi scoccer� pi�. Bene, ora basta con le scemenze ed iniziamo sul serio.

 

PARTE SECONDA: TROVIAMO LA ROUTINE

Oki, andate nella finestra di registrazione, ed avrete i due edit box "Nome" e "Codice". Innanzitutto controlliamo se il box del codice ha qualche limitazione: accetta tutti i tipi di caratteri, ma ha un numero massimo di caratteri inseribili, cio� 48. Cazzarola! Un seriale di 48 char?? La cosa gi� si prospetta dura... comunque tanto per tranquillizzarvi vi dico subito che il seriale � di "soli" 40 char! Vabb�, poi vedremo anche la forma che deve avere. Allora, inseriamo un nome (io AndreaGeddon) ed un numero a caso. Inizio inserendo il numero 111222333444555 come mio solito. Infatti all'inizio non sappiamo se il serial deve effettivamente essere di 40 char. Pu� darsi anche che la lunghezza sia determinata dal Nome, e che 40 � la lunghezza massima che un serial pu� raggiungere. Settiamo ora il solito bpx getwindowtexta, e iniziamo. Steppiamo fuori da User e da Mfc42, ed arriviamo alla linea 0040D216. Iniziamo a steppare. Arrivati alla linea 0040D248 c'� un piccolo ciclo che cambia leggermente il seriale immesso: infatti il seriale che ho immesso io diventa 1112233344555. Provate a mettere un seriale pi� lungo, e dopo un minimo di osservazione � facile capire che il programma prende il serial, e ne scarta un char ogni 5. Solitamente lo scarto di un char � dovuto al fatto che il serial dovrebbe essere inserito con i - in mezzo. Quindi il serial sar� del tipo: 12345-67890-12345, cio� un trattino ogni 5 char. Ora continuate a steppare, e quando uscite dal ciclo vi ritroverete nel processo di mfc42.dll. Se provate a premere F12 pare non esserci via di uscita! Siamo intrappolati in una dll! Invece no! Dovrete premere F12 parecchie volte (circa una trentina!) per riuscire a tornare al processo di MJ-Studio. In compenso, appena tornate in MJ-Studio vi ritroverete dritti dritti nella routine del controllo del seriale, che inizia alla linea 00403DE9.

 

PARTE TERZA: L'ANALISI

Ricapitoliamo: finora sappiamo solo che il seriale � composto a gruppi di 5 char e che la sua lunghezza massima � di 48 char. Come sappiamo che da 00403DE9 inizia la routine di calcolo? Semplice, ci sono molte operazioni sul Nome e sul Seriale, ed inoltre non appena qualcosa non va, venite sparati alla linea 00404050, dove vi verr� poppato il messagebox di errore. Oki. Vi posto lo routine. La ho commentata a blocchi (separati da una linea di trattini), cos� risulta di pi� facile lettura. Questa volta come serial inserisco 12345-12345-12345

 

---------------------------- 1 ---------------------------------------

00403DE9   cmp   eax, 01     la routine parte da qui

00403DEC    jz   00403E07    avviene sempre

...

00403E07   add   edi, 00041B1C  |  tutta questa routine

00403E0D   mov   ebp, 704B8A19  |  � solo una serie di controlli

00403E12   mov   [esp+1C], edi  |  con la blacklist, cio�

00403E16   mov   edx, 0042D5C4  |   controlla che il nostro nome

00403E1B   mov   eax, [edx]     |  non sia tra quelli non validi

00403E1D   mov   esi, edi       |  infatti tra i nomi non validi

00403E1F   mov   bl, [eax]      |  vedrete Bill Gates e altri

00403E21   mov   cl, bl         |  nomi giapponesi

00403E23   cmp   bl, [esi]      |  ai nostri fini questo pezzo

...                             |  non interessa

00403E59    jl   00403E1B       |

--------------------------------2 -----------------------------------

00403E5B   mov   ecx, [esp+10]  mette in ecx un puntatore, che punta "nei pressi" del seriale

00403E5F   xor   eax, eax       | un modo stupido

00403E61   mov   [esp+18], eax  | di azzerare   la locazione esp+18

00403E65    mov   dl,[ecx+00041B44] metti in dl il primo char

00403E6B    test  dl, dl        controlla che non sia zero

00403E6D    mov   [esp+17], dl  salvalo in esp+17

00403E71     jz   00403E83      se il char era zero salta

allora, come avete notato non viene usato un puntatore diretto al seriale, ma un puntatore composto. Abituatevici, perch� questa routine utilizza spesso puntatori composti. In questo caso il puntatore al seriale era [ecx+00041B44|. Questo blocco prende il primo char del serial e lo salva in una locazione.

--------------------------- 3 -------------------------------

00403E73    mov   bl, [ecx+eax+00041B45] prende uno alla volta tutti i char del seriale

00403E7A    inc   eax                     incrementa il contatore

00403E7B    test  bl, bl                  se questo char era zero...

00403E7D    jnz   00403E73                ... non loopare pi�

00403E7F    mov   [esp+18], eax    salva in esp+18 il numero di char del seriale

questo blocco conta il numero di char del seriale

--------------------------- 4 -------------------------------

00403E83    mov   al, [edi]         edi contiene il puntatore al nome

00403E85    xor   esi, esi          azzera esi

00403E87    test  al, al            controlla il primo char del nome

00403E89     jz   00404050          se � zero salta a ERRORE

00403E8F    mov   al, [edi+esi+1]prende uno a uno i char del Nome

00403E93    inc   esi               incrementa il contatore

00403E94    test  al, al            controlla l'n-esimo char

00403E96    jnz   00403E8F          se � zero non loopare pi�

00403E98    cmp   esi, 08           controlla il numero di char...

00403E9B    mov   [esp+20|, esi     salva il numero di char del nome in esp+20

00403E9F     jl   00404050          ...salta a errore se il numero di char � minore di 8

Questo blocco conta i char del nome. Buono il JL, cos� sappiamo che il nome deve essere di almento 8 char.

-------------------------- 5 --------------------------------

00403EA5    xor   ecx, ecx         azzera ecx

00403EA7    mov   ebx, 00014CBB    carica il valore 14CBB, valore di partenza per i prossimi calcoli

00403EAC    test  esi, esi         controlla il numero di char del nome

00403EAE    jle   00403ED2         se � zero abbiamo finito

00403EB0    mov   eax, ecx         metti in eax il contatore

00403EB2    cdq                    azzera edx

00403EB3    idiv  esi              dividi eax per il numero di char del nome

00403EB5    movsx edx, byte ptr [edi+edx]  carica il char n-esimo del nome

00403EB9    lea   ebx, [edx+ebx+0A] ebx = (ebx*2) +10

00403EBD    mov   eax, ebx         metti in eax il valore ottenuto da ebx

00403EBF    shr   eax, 1F          divide eax per 80000000

00403EC2    lea   edx, [ebx+ebx]   mette in edx il doppio di ebx

00403EC5    or    eax, edx         eax era maggiore di 80000000, allora somma 1 a edx, altrimenti gli                                                                                       somma 0

00403EC7    inc   ecx              incrementa il contatore

00403EC8    cmp   ecx, esi         controlla se il contatore � minore del numero di char del nome...

00403ECA    mov   ebx, eax         metti in ebx il valore aggiornato, che verr� usato nel prossimo ciclo

00403ECC     jl   00403EB0         ... se lo �, continua a calcolare

questo blocco calcola un valore in base al nome inserito. Il valore di partenza per i calcoli � 14CBB. Non perdete tempo su questo blocco: infatti da qui uscir� un numero che sar� il parametro di partenza per altri calcoli, quindi segnatevi il valore ottenuto in base al vostro nome e non pensateci pi�. Nel mio caso ottengo 14D773C4.

--------------------------- 6 -----------------------------------

00403ECE    mov   dl, [esp+17]   metti in dl il primo char del seriale (salvato nel blocco 2)

00403ED2    mov   esi, [esp+10]  esi = puntatore al seriale - 41B47

00403ED6    movsx eax, byte ptr [esi+00041B47]  prendi il 4� char del seriale

00403EDD    cmp   eax, 61        controlla il char

00403EE0     ja   00403EE7       salta se � maggiore di "a"

00403EE2    add   eax, -30       se non sei saltato allora il char immesso deve essere un numero, ergo sottraigli 30

00403EE5     jmp   00403EEA

00403EE7     add   eax, -57      se il char � una lettera minuscola sottraigli 57

00403EEA     cmp   eax, 0F       adesso controlla il risultato...

00403EED      ja   00404050      ... e salta a errore se ottengo un numero maggiore di 0F

altra indicazione sul seriale: se contiene numeri, okay. Se contiene lettere maiuscole, sottraendogli 30 ottiene un valore maggiore di 0F e salta a errore. Quindi escludiamo le maiuscole. Se contiene lettere minuscole, okay, ma solo se sono comprese tra "a" ed "f", altrimenti la sottrazione di 57 mi d� un valore maggiore di 0F. Altri caratteri sono quindi esclusi: l'alfabeto del seriale sar� 0123456789abcdef.

--------------------------7----------------------------------------

00403EF3     movsx ecx, byte ptr [esi+00041B46] prendi il 3� char

00403EFA     cmp   ecx, 61    controlli sul char...

00403EFD     jae   00403F04

00403EFF     sub   ecx, 30

00403F02     jmp   00403F07

00403F04     sub   ecx, 57

00403F07     cmp   ecx, 0F

00403F0A      ja   00404050

00403F10     shl   eax, 04

00403F13     add   eax, ecx   forma 43

00403F15     movsx ecx, byte ptr [esi+00041B45] prendi il 2� char

00403F1C     cmp   ecx, 61    controlli sul char...

00403F1F     jae   00403F26

00403F21     sub   ecx, 30

00403F24     jmp   00403F29

00403F26     sub   ecx, 57

00403F29     cmp   ecx, 0F

00403F2C      ja   00404050

00403F32     shl   eax, 04

00403F35     add   eax, ecx   forma 432

00403F37     movsx ecx, dl    prendi il 1� char

00403F3A     cmp   ecx, 61    controlli sul char

00403F3D      ja   00403F44

00403F3F     sub   ecx, 30

00403F42     jmp   00403F47

00403F44     sub   ecx, 57

00403F47     cmp   ecx, 0F

00403F4A      ja   00404050

00403F50     shl   eax, 04

00403F53     add   eax, ecx   forma 4321, cio� l'inverso dei primi 4 char che avevo inserito.

--------------------------- 8 ----------------------------------

00403F55     xor   eax, ebx   xor 4321 con il valore 14D773C4, ottenuto nel blocco 5

00403F57     mov   ecx, eax   lo copia in ecx

00403F59     and   ecx, 0000FFFF  tieni solo la parte relativa a cx

00403F5F     xor   ebx, ecx   ri-xor con 4321

00403F61     test  ax, ax     controlla ax...

00403F64      jz   00403F73   ... e salta se � zero

00403F66     cmp   ax, [004713A0] [004713A0] = 0000

00403F6D      jb   0040409E       salta se ax � minore di zero

00403F73     mov   eax, [esp+18]  carica il  numero di char del seriale in eax

00403F77     mov   edi, 02        mette 2 in edi

00403F7C     cdq                  azzera edx

00403F7D     sub   eax, edx       sottrai edx a eax

00403F7F     sar   eax, 01        divide il numero di char del seriale a met� (questo perch� lavorer� solo sulle coppie, quindi il numero di iterazioni dovr� essere pari alla met� del numero di char del seriale)

00403F81     cmp   eax, edi       controlla se il contatore ha raggiunto il valore di eax

00403F83     mov   [esp+18], eax  salva il numero di coppie di char da elaborare

00403F87     jle   00404050       salta se il numero di coppie da elaborare � minore di edi (2)

00403F8D     mov   edx, [esp+10]  mette in edx una parte che comporra il puntatore al seriale

00403F91     lea   ecx, [edx+00041B48] mette in ecx il puntatore composto

00403F97     mov   [esp+10], ecx  salva il puntatore composto in esp+10 per i prossimi calcoli

00403F9B     jmp   00403FA1

------------------------- 9 -------------------------------

qui inizia la routine vera e propria

00403F9D     mov   ecx, [esp+10]  prendi il puntatore alla coppia n-esima

00403FA1     xor   eax, eax       azzera eax

00403FA3     mov   al, [ecx+01]   metti in al il secondo char della coppia

00403FA6     cmp   eax, 61        controlla che sia nel giusto range

00403FA9     jae   00403FB0

00403FAB     add   eax, -30

00403FAE     jmp   00403FB3

00403FB0     add   eax, -57

00403FB3     cmp   eax, 0F

00403FB6      ja   00404050       salta a errore se non lo �

00403FBC     movsx ecx, byte ptr [ecx] metti in ecx il primo char della coppia
00403FBF     cmp   ecx, 61       
controlla che sia del giusto range

00403FC2     jae   00403FC9

00403FC4     sub   ecx, 30

00403FC7     jmp   00403FCC

00403FC9     sub   ecx, 57

00403FCC     cmp   ecx, 0F

00403FCF      ja   00404050       salta a errore se non lo �

00403FD1     shl   eax, 04

00403FD4     add   eax, ecx       forma la coppia inversa, cio� se nel serial c'era 56 qui ottengo 65

00403FD6     mov   esi, eax       copi la coppia inversa in esi

00403FD8     mov   ecx, esi       ed in ecx

00403FDA     xor   ecx, ebx       xor della coppia inversa con il valore in ebx, quello proveniente dal 5� e poi 8� blocco (nel mio caso 14D74321)

00403FDC     mov   ebx, [esp+1C]  metti in ebx il puntatore al nome

00403FE0     mov   eax, ecx       metti in eax il valore xorato prima

00403FE2     and   eax, 000000FF  tieni solo la parte bassa, cio� al

00403FE7     lea   edx, [eax*8+00000000]  |

00403FEE     sub   edx, eax              | moltiplica la parte bassa per 7

00403FF0     add   ebp, edx              aggiungi il risultato a EBP

attenzione, ebp contiene all'inizio il valore di partenza = 704B8A19

00403FF2     mov   eax, ebp           copia in eax il valore ottenuto

00403FF4     sar   eax, 1F            |controlla che tale valore sia maggiore di 80000000

00403FF7     and   eax, 01            |se lo �, conserva il valore 1, altrimenti il valore 0

00403FFA     lea   edx, [ebp+ebp+00] metti in edx il doppio di ebp

00403FFE      or   eax, edx           |somma l'eventuale 1 o 0 a edx, e metti il tutto in eax

00404000     mov   ebp, eax           rimetti eax in ebp, che sar� usato nella prossima iterazione

00404002     lea   eax, [edi-02]     metti in eax il valore del contatore - 2

il contatore - 2 deriva dal fatto che le prime due coppie del serial sono gi� state lavorate fuori da questo ciclo per formare il numero 4321

00404005     cdq                      azzera edx

00404006     idiv  dword ptr [esp+20]   dividi eax per il numero di char del nome

0040400A     xor   eax, eax              azzera eax

0040400C     mov   al, byte ptr [ebx+edx] metti in al il char n-esimo del nome

0040400F     add   eax, 05               sommagli 5

00404012     xor   eax, ecx              e xoralo con il solito valore di ebx (14D7...)

00404014     add   eax, esi              aggiungili pure la coppia inversa

00404016     mov   ecx, eax              copia in ecx il risultato di tutto sto casino

00404018     shr   ecx, 1C               |  praticamente prende il primo numero del valore di ecx

0040401B     shl   eax, 04               |  e lo mette in coda

0040401E      or   ecx, eax              |  (es. 12345678 -> 23456781)

00404020     mov   eax, [esp+18]         metti in eax il numero di char del seriale

00404024     mov   ebx, ecx              ebx ora contiene il nuovo numero da usare per la prossima iterazione

00404026     mov   ecx, [esp+10]         mette in ecx il puntatore al seriale

0040402A     inc   edi                   incrementa il contatore

0040402B     add   ecx, 02               aggiunge 2 al puntatore, cos� punter� alla prossima coppia

0040402E     cmp   edi, eax              confronta il contatore con il numero di char del serial.....

00404030     mov   [esp+10|, ecx         salva in esp+10 il puntatore aggiornato

00404034      jl   00403F9D              ... e se � pi� piccolo continua a iterare

0040403A     cmp   ebp, -03              alla fine � ebp il valore chiave!

0040403D      jz   004040C5               se ebp � -3, salta a "thanx for nothing" (?)

00404043     cmp   ebp, -02              se � -02

00404046      jz   0040409E              salta a "License Code Expired"

00404048     cmp   ebp, 375B5EE6         eccolo! Il valore da ottenere in ebp � 375B5EE6

0040404E      jz   00404077              se lo �, salta a registrazione avvenuta

00404050     push  FF                    se continuate da qui, finirete in "code not valid"

...

nota che il quando il seriale viene esaminato, se � minore di 40 char gli verranno messi in coda dei valori, che quando verranno controllati per vedere se siamo nel range "01...ef" ci daranno errore e ci spareranno direttamente fuori dalla routine senza passare dal via. Per ovviare a ci�, basta fare qualche prova per arrivare a vedere che per non generare errori di range dobbiamo inserire PER FORZA i 40 char.

Sappiamo adesso quindi che il serial giusto deve essere nella forma:

12345-67890-abcde-f1234-56789-0abcd-ef123-45678-

totale? i 48 char!

 

chiaro, no? Per semplicit� di lettura e per ricapitolare le idee ci scriviamo una sintesi dell'algoritmo in alto livello:

 

- Prende la coppia n-esima del serial e la inverte, formando una coppia inversa

- XOR ebx con la coppia inversa

- prendi la parte bassa del precedente xor

- (parte bassa * 8) - parte bassa =   parte bassa * 7    la chiameremo PB7

- aggiungi PB7 a ebp

- ebp = ebp *2   e sommagli anche 1 se prima del raddoppio ebp era maggiore di 80000000. Quindi ora ebp contiene il nuovo valore per il prossimo ciclo.

- xor  ebx  con il (char n-esimo)+5   (es. A=41, +5 = 46)

- somma la coppia inversa al valore ottenuto in ebx

- mette in coda la prima cifra di ebx (es. 12345678 -> 23456781)

 

E adesso facciamo il punto della situazione; le variabili usate sono:

- ebx      il valore ottenuto all'inizio mediante calcoli sul nome

- ebp      il valore di partenza, 704B8A19

- coppia/coppia inversa      la coppia di char del serial

- il char del nome

 

In pratica conosciamo solo il char del nome. Le altre variabili sono parametri, e teoricamente dovremmo riuscire a calcolarceli.L'incognita in definitiva deve essere solo la coppia/coppia inversa del seriale. Tutto il procedimento consiste di 20 iterazioni. Sappiamo che il valore che dobbiamo riuscrie ad avere alla fine in EBP deve essere 375B5EE6. Se proviamo a partire da questo valore per ricalcolarci all'indietro i. seriale, ecco quello che dobbiamo fare per ogni iterazione:

- dividere ebp (375B5EE6) per 2

- adesso il risultato � un (numero+PB7).

e qui ci fermiamo. Come facciamo a sapere qual'� PB7? e questo � il primo problema. Infatti per come � fatto l'algoritmo noi dobbiamo riuscire a calcolarci una catena di valori (che saranno contenuti in ebp), che partendo da 704B8A19 attraverso ogni iterazione ci portano a 375B5EE6. Se avessimo questi valori, allora potremmo conoscere anche PB7, e cos� potremmo determinarci infine la coppia inversa giusta. Affrontiamo matematicamente questo pezzo di algoritmo, e otteniamo un sistema cos�:

((((((((((((((((((((((((((((((((((((704B8A19 + 7x) *2) +7x) *2) +7x) *2) +7x) *2) +7x) *2) +7x) *2) +7x) *2) +7x) *2) +7x) *2) +7x) *2) +7x) *2) +7x) *2) +7x) *2) +7x) *2) +7x) *2) +7x) *2) +7x) *2) +7x) *2) = 375B5EE6

oki, spero di non aver dimenticato qualche parentesi, comunque questa � la formula.Che cosa abbiamo fatto? Semplice, partiamo da 704B8A19 e ogni volta gli sommiamo 7x (dove x � il valore "parte bassa") e poi moltiplichiamo per due il tutto. NOTA che l'algoritmo in realt� somma 1 ad alcune iterazioni, ma l'ho omesso nella formula. Poi nei calcoli lo metteremo. Cosa speriamo di ottenere? Spero di ottenere un valore "medio" da inserire di volta in volta nell'algoritmo per arrivare al risultato di 375B5EE6. RI-NOTA: io suppongo che ci sia un valore medio, ma non ne sono certo! Se non ci fosse un valore medio, la formula in realt� avrebbe non una sola incognita (7x), ma UNA INCOGNITA DIVERSA PER OGNI ITERAZIONE, e sarebbero cazzi! Vabb�, procediamo col nostro intento. Eccovi tutti i calcoli che dovrete fare per arrivare al valore medio:

 

(704B8A19 + 7x) * 2 = E0971432 + Ex

((E0971432 + Ex) + 7x) *2 = C12E2864 + 2Ax + 1

PICCOLA PARENTESI

Come vi ho detto avevamo trascurato +1 nella formula generale. Questo +1 deriva dal fatto che se all'inizio dell'iterazione il valore in ebp (0E971432) � maggiore di 80000000. In realt� il codice fa un

SAR  eax, 1F

che sarebbe uno shift aritmetico a destra di 1F del registro eax, praticamente effettua divisione di eax per 2^1F, cio� 80000000. Se eax � maggiore di 80000000 il risultato sar� 1 con il resto, altrimenti sar� zero. E sono appunto i risultati della divisione a determinare la somma di +1 o +0. Che differenza c'� tra SAR e IDIV? SAR tronca tutti i numeri verso l'intero pi� piccolo, IDIV tronca tutti i numeri verso lo zero.

FINE PARENTESI

((C12E2865 + 2Ax) +7x) *2 = 825C50CA +1 +62x

((825C50CB + 62x) +7x) *2 = 04B8A196 +1 +D2x

((04B8A197 + D2x) +7x) *2 = 0971432E + 1B2x

((0971432E + 1B2x) +7x) *2 = 12E2865C + 372x

((12E2865C + 372x) +7x) *2 = 25C50CBB + 6F2x

((25C50CBB + 6F2x) +7x) *2 = 4B8A1970 + DF2x

((4B8A1970 + DF2x) +7x) *2 = 971432E0 + 1BF2x

((971432E0 + 1BF2x) +7x) *2 = 2E2865C0 +1 +37F2x

((2E2865C1 +37F2x) +7x) *2 = 5C50CB82 + 6FF2x

((5C50CB82 + 6FF2x) +7x) *2 = B8A19704 + DFF2x

((B8A19704 + DFF2x) +7x) *2 = 71432E08 +1 + 1BFF2x

((71432E09 + 1BFF2x) +7x) *2 = E2865C12 + 37FF2x

((E2865C12 + 37FF2x) +7x) *2 = C50CB824 + 1 +6FFF2x

((C50CB825 +6FFF2x) +7x) *2 = 8A19704A +1 +DFFF2x

((8A19704B +DFFF2x) +7x) *2 = 1432E096 +1 +1BFFF2x

((1432E097 +1BFFF2x) +7x) *2 = 2865C12E +37FFF2x

quindi adesso

2865C12E +37FFF2x = 375B5EE6

ed esplicitando abbiamo

x = (0EF59DB8 / 37FFF2) = 44

Abbiamo trovato il nostro valore medio! 44! E mo che ci facciamo? Ci possiamo calcolare la scala di valori che dovr� assumere ebp ad ogni iterazione, cos� poi potremo esplicitare tutto l'algoritmo in funzioe delle coppie di char del seriale. Iiziamo a calcolare:

(704B8A19 +7(44))*2 = E09717EA       - primo passaggio

....                                                            - si procede analogamente a tutte le iterazioni....

(1BA2DBFE +7(44))*2 = 3745BBB4     - ultimo passaggio

come 3745BBB4? Dovevamo ottenere 375B5EE6! Che succede? Vi ricordate la divisione x = (0EF59DB8 / 37FFF2) = 44? Bene, facciamola in decimale:

x = (250977720 / 3670002) = 68,386262...

Minchia! Il valore medio era supposto funzionare a patto che la divisione fosse INTERA, invece abbiamo un bel RESTO! Allora come facciamo a calcolarci questa stramaledetta scala di valori???? La mia ipotesti � che oltre a 44 dovremmo inserire nell'algoritmo di volta in volta anche il resto. Per� non possiamo inserire una frazione, quindi dovremo considerare il resto, aspettare che si accumuli, e poi aggiungerlo al 44 a determinati intervalli. E qui � la parte dove entra in gioco il seriale per calcolare il seriale :-) Infatti ho provato a calcolare gli eventuali accumuli di tale resto, ma non sono riuscito a determinare un valore utile. Allora ho preso un seriale giusto, l'ho inserito ed ho controllato che succedeva: ho visto cos� che veniva usato anche l� ogni volta il valore 44 (ci avevo azzeccato :-)), solo che in corrispondenza della 9� e 13� iterazione venivano usati FE invece di 44. L'ultima iterazione, poi, usava 8C. FE - 44 = BA, che � lo scarto dovuto ai resti che di volta in volta aumentano. Anche adesso, conoscendo il valore di scarto non riesco a determinare una qualche formula matematica che mi permette di capire dove e come inserire lo scarto... boh... forse avrei dovuto studiarmi meglio l'algebra. Comunque, quello che importa � che adesso possiamo calcolarci la scala di valori. Inserendo ai giusti posti FE e 8C. I calcoli sono i soliti, quindi non li riscrivo tutti:

(704B8A19 +7(44)) *2 = E09717EA

(E09717EA +7(44)) *2 = C12E338D

C12E338D  ....

825C6AD3

04B8D95F

0971B676

12E370A4

25C6E500 ...

(4B8DCDB8 +7(FE)) *2 = 9714BA954

9714BA954  ...

2E375661

5C6EB07A  ...

(B8DD64AC +7(FE)) *2 = 71BAD73C +1

71BAD73D  ...

E375B232

C6EB681D

8DD6D3F3  ...

(1BADAB9F +7(8C)) *2 = 375B5EE6

375B5EE6

Ecco la nostra bella scaletta! Adesso ci rimane l'ultimo passo, finalmente.

 

PARTE QUARTA: INFINE CALCOLIAMOCI IL SERIAL

Adesso che abbiamo la nostra scala di parametri possiamo calcolarci il seriale. C'� anche la scala di parametri conetnuta in EBX, ma quelli ce li possiamo calcolare di volta in volta procedendo "in avanti" nell'algoritmo. In pratica questi valori ebx ci bloccavano la strada quando ci volevamo calcolare il serial "all'indietro". Ora per� non abbiamo pi� problemi. Ricontrolliamo i nostri parametri:

- ebx      il valore ottenuto all'inizio mediante calcoli sul nome/// questi ce li calcoliamo ad ogni iterazione

- ebp      il valore di partenza, 704B8A19///  ci siamo appena calcolati la scaletta per ebp

- coppia/coppia inversa      la coppia di char del serial///  questa ce la dobbiamo calcolare

- il char del nome///  ad ogni iterazione si prende il char n-esimo del nome. Se il nome � pi� corto del  numero di iterazioni, ricomincia dal primo char.

Da notare che le prime due coppie del seriale vengono elaborate e riscritte per formare i 4 numeri all'inverso. Nel mio caso da 1234 forma 4321. Queste cifre verranno messe in ebx, che sar� usato come base per i successivi calcoli. La cosa strana � che  non sembrano esserci controlli su queste prime 4 cifre, quindi possono assumere uno qualsiasi dei 16^4 possibili! Se vi calcolate vari serial a partire da varie basi di partenza, scoprirete che sono tutti validi. Quindi per ogni nome avremo un totale di 65536 seriali validi! E' un algoritmo veramente molto versatile! Oki, ora mi calcolo il mio seriale.

Come si fa? Devo trovare quel valore che xorato con ebx mi dia 44: essendo lo xor reversibile io xoro ebx con 44 e trovo il valore che xorato con ebx mi d� 44! Tale valore corrisponde ovviamente all'inverso della coppia giusta di char del seriale! Se seguite questi ragionamenti con la scaletta di passi in alto livello vi sar� pi� facile! Ecco tutti i passi. Ricordatevi gli FE e 8C da mettere al punto giusto!!

 

------A-------

14D74321 xor 44 = 14D74365  -->   56 = 3� coppia del seriale esatto

14D74344 xor (char+5) = 14D74344 xor 46 = 14D74302

14D74302 + coppia inversa = 14D74302 + 65 = 14D74367

14D74367  -->  4D743671     prossimo valore per ebx

------n--------

4D743671 xor 44 = 4D743635  -->   53 = 4� coppia

4D743644 xor 73 = 4D743637

4D743637 + 35 = 4D74366C

4D74366C  -->  D74366C4

------d--------

D74366C4 xor 44 = D7436C80    -->  08 = 5� coppia

D7436644 xor 69 = D743662D

D743662D + 80 = D74366AD

D74366C4 --> 74366ADD

------r---------

74366ADD xor 44 = 74366A99    --> 99 = 6� coppia

74366A44 xor 77 = 74366A33

74366A33 + 99 = 74366ACC

74366ACC --> 4366ACC7

------e---------

4366ACC7 xor 44 = 4366AC83    --> 38 = 7� coppia

4366AC44 xor 6A = 4366AC2E

4366AC2E + 83 = 4366ACB1

4366ACB1 --> 366ACB14

------a---------

366ACB14 xor 44 = 366ACB50  --> 05 = 8� coppia

366ACB44 xor 66 = 366ACB22

366ACB22 + 50 = 366ACB72

366ACB72 --> 66ACB723

------G---------

66ACB723 xor 44 = 66ACB767  --> 76 = 9� coppia

66ACB744 xor 4C = 66ACB708

66ACB708 + 67 = 66ACB76F

66ACB76F --> 6ACB76F6

------e----------

6ACB76F6 xor 44 = 6ACB762B  --> b2 = 10� coppia

6ACB7644 xor 6A = 6ACB762E

6ACB762E + B2 = 6ACB76E0

6ACB76E0 --> ACB76E06

------d----------

ACB76E06 xor FE = ACB76EF8 ---> 8f = 11� coppia

ACB76EFE xor 69 = ACB76E97

ACB76E97 + F8 = ACB76F8F

ACB76F8F --> CB76F8FA

------d----------

CB76F8FA xor 44 = CB76F8BE  --> eb = 12� coppia

CB76F844 xor 69 = CB76F82D

CB76F82D + BE = CB76F8EB

CB76F8EB -> B76F8EBC

------o----------

B76F8EBC xor 44 = B76F8EF8  --> 8f = 13� coppia

B76F8E44 xor 74 = B76F8E30

B76F8E30 + F8 = B76F8F28

B76F8F28 --> 76F8F28B

------n----------

76F8F28B xor 44 = 76F8F2CF  --> fc = 14� coppia

76F8F244 xor 73 = 76F8F237

76F8F237 + CF = 76F8F306

76F8F306 --> 6F8F3067

------A----------

6F8F3067 xor FE = 6F8F3099  --> 99 = 15� coppia

6F8F3044 xor 46 = 6F8F30B8

6F8F30B8 + 99 = 6F8F3151

6F8F3151 --> F8F31516

------n----------

F8F31516 xor 44 = F8F31552  --> 25 = 16� Coppia

F8F31544 xor 73 = F8F31537

F8F31537 + 52 = F8F31589

F8F31589 --> 8F31589F

------d----------

8F31589F xor 44 = 8F3158DB  --> bd = 17� coppia

8F315844 xor 69 = 8F31582D

8F31582D + DB = 8F315908

8F315908 --> F3159088

------r----------

F3159088 xor 44 = F31590CC  --> cc = 18� coppia

F3159044 xor 77 = F3159033

F3159033 + CC = F31590FF

F31590FF --> 31590FFF

------e----------

31590FFF xor 44 = 31590FBB  --> bb = 19� coppia

31590F44 xor 6A = 31590F2E

31590F2E + BB = 31590FE9

31590FE9 --> 1590FE93

------a----------

1590FE93 xor 8C = 1590FE1F  --> f1 = 20� coppia

 

pant! Finito.Adesso ho finalmente calcolato il mio seriale esatto:

AndreaGeddon

12345-65308-99380-5762b-8feb8-ffc99-25bdc-cbbf1

Come dite? "Ma non era pi� semplice crakkarlo"? Si ma non avreste imparato un bel niente! Il cracking qui si riduce alla modifica di 3 o 4 byte se ben ricordo.

Finalmente � finita! Spero di essere stato abbastanza chiaro e di non aver sbagliato a ricopiare i calcoli dai miei appunti cartacei!

AndreaGeddon

 

                                                                                         Note finali

Hack-it 2000 si avvicina! Spero di esserci, ma credo che sar� molto difficile, visto che sono bombardato dagli esami. Saluto tutta la mailing list. Saluto Cek che ho risentito dopo taaanto tempo. Ciauuuuz a tutti!

Disclaimer

Queste informazioni sono solo a scopo puramente didattico.

                                                       
UIC's page of reverse engineering, scegli dove andare:
Home   Anonimato   Assembly    CrackMe   ContactMe   Forum   Iscrizione
Lezioni    Links   Linux   NewBies   News   Playstation
Tools   Tutorial   Search   UIC Faq
UIC