MJ-Studio 1.05 |
|
|
30/04/2000 |
by "AndreaGeddon" |
|
|
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??? :)))
|
... da quelle cose che non hanno nome e che non devono averne |
UIC's form |
|
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.
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]
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
|
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 |
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 |