CrackME 44.8 by Lucifer48
(ExceptionHandler,Trick anti-Wdasm32 e Matematica Cervellotica)


Data

by "GuZuRa"

UIC's Home Page

Published by Quequero

La parte più difficile della stesura di un tutorial ...

Guzu, bravo hai fatto un'ottimo tute e soprattutto ho visto che NON hai messo in pratica quello che ho spiegato sul tute sulle SEH :)) vabbe basta che la prossima volta usi un form AGGIORNATO :)

è cercare una frase ad effetto da inserire qui...
UIC's form
E-mail: [email protected]
#crack-it (da poco)
UIC's form

Difficoltà

()NewBies (X+1/2)Intermedio ( )Avanzato ( )Master

Un CrackMe piuttosto interessante con un trick anti wdasm32 e l'utilizzo di un final handler (Que docet...)


CrackME 44.8 by Lucifer48
(Alla ricerca dei punti deboli di un ALGO)
Written by GuZuRa

Introduzione

CrackMe che ci chiede un keyfile

Tools usati

Sice,IDA,una tabella ASCII tutti reperibili alla UIC e un editor di testo per buttare giù i dati raccolti...

URL o FTP del programma

http://www.multimania.com/lucifer48

Notizie sul programma 

ENJOY...

Essay

Il programmino presenta un tasto di check che verifica la correttezza del keyfile...

Prima di tutto disassembliamo con IDA (anche Wdasm32 che però non potrete usare come debugger) e diamo un'occhiata alle API che gestiscono i file per vedere chi cerca cosa ...
Guardate nella names window (o nella string reference per i WDasm maniaci) e noterete la presenza di CreateFileA e Getfilesize, doppio click andianmo a vedere cosa ci propone il codice (dovreste arrivare qui) :

0040128B push 0 ; si parte da qui belli
0040128D push 80h
00401292 push 3
00401294 push 0
00401296 push 0
00401298 push 0C0000000h
0040129D push offset aClef_l48 ; nome del file che si cerca
004012A2 call j_CreateFileA ; se va bene ho l'handle del file se no esco
004012A7 cmp eax, 0FFFFFFFFh
004012AA jz loc_4014BE
004012B0 push eax
004012B1 push eax
004012B2 push 0
004012B4 push eax         ; handle del file
004012B5 call j_GetFileSize
004012BA cmp eax, 32h ; voglio un file lungo 50 byte (32h)
004012BD jnz loc_4014B6
004012C3 pop eax
004012C4 push 0
004012C6 push offset unk_4023AA
004012CB push 32h
004012CD push offset unk_402377
004012D2 push eax
004012D3 call j_ReadFile ; vado a leggere i 50 byte
004012D8 mov esi, offset unk_402377 ; metto i byte in esi
004012DD mov ecx, 32h ; muovo in ecx 32
004012E2 xor ebx, ebx ; azzero ebx
004012E4 xor eax, eax ; azzero eax

loc_4012E6: ; CODE XREF: sub_4011C6+123j
004012E6 lodsb
004012E7 add ebx, eax
004012E9 loop loc_4012E6 ; con questo loop metto in ebx la somma dei byte del file
004012EB std ; inverto il flag di direzione
004012EC mov edi, offset unk_40235F ; infilo in edi  un puntatore a una tabella di valori
004012F1 dec esi ; FA SI CHE ESI PUNTI ALL?ULTIMO BYTE DEL FILE

loc_4012F2: ; CODE XREF: CODE:00401321j
004012F2 mov eax, ebx ; muovo la somma in ebx
004012F4 xor ecx, ecx ; azzero ecx
004012F6 mov cx, [edi+14h] ; muovo in ecx 141c al primo giro
004012FA cdq ; mi preparo per la divisione
004012FB div ecx
004012FD cmp eax, 1 ; quoziente=1
00401300 jnz Sbattuto_Fuori         ;SCUSATE LE MIE BELLISSIME LABEL
00401306 test edx, edx ; resto=0
00401308 jnz Sbattuto_Fuori ; per non uscire la sooma dei byte deve essere 141c(hex)
0040130E xor eax, eax ; azzera eax
00401310 mov ecx, 5 ; metto in ecx 5

loc_401315: ; CODE XREF: sub_4011C6+152j
00401315 lodsb
00401316 sub ebx, eax
00401318 loop loc_401315 ; sottraggo a 141c la somma degli ultimi 5 byte
00401318 ; ho invertito il direction flag da ricordare
0040131A dec edi ; decresco edi
0040131B dec edi ; decresco edi
0040131C cmp word ptr [esi], 1314h
00401321 jnz short loc_4012F2     ; torno su
00401323 cld ; inverto il direction flag di nuovo
00401324 add esi, 6
00401327 cmp ds:dword_40235B, 1 ; molto ma molto ma molto IMPORTANTE
0040132E jnz Sbattuto_Fuori
Qui finisce la prima parte di controlli che introducono gia un pò di restrizioni sul keyfile però prima precisiamo lo schema di lettura e controllo del file a grandi linee: CreateFileA cerca il file CLEF.L48 nella directory corrente e se lo trova crea un handle per il file, GetFilesize prende l'handle e legge la lunghezza del file (il cmp successivo ci caccia fuori se il file non è lungo 50 byte; loc :4012BA) e alla fine la ReadFile legge il file e lo memorizza a partire da 402377 (poi in esi e da lì in avanti si lavorerà solo su esi come puntatore ai byte del file).

Ora arriva la parte più impegnativa: consideriamo il loop :4012E6 :4012E9 (che non fà altro che la somma dei byte del file) poi muovo in edi l'offset di una tabella di valori su cui faro parecchi controlli nelle istruzzioni successive.  

Vi riport la tabella di valori nel momento in cui viene messa in edi (la tabella è fatta a gruppi di WORD che muovo in CX ):

edi+00:  0000
edi+02:  012D
edi+04:  0468
edi+06:  0568
edi+08:  07B7
edi+0A:  0A32
edi+0C:  0C70
edi+0E:  0CFE
edi+10:  1061
edi+12:  1034
edi+14:  141C


Che cosa succede in pratica la prima volta che arrivo nel ciclo? Verifico che la somma dei byte del keyfile sia uguale  a 141C,infatti la divisione in :4012FB deve dare quoziente (eax) uguale a 1 e resto (edx) uguale a zero (Prima restrizione sul Keyfile è somma dei byte = 141C) poi si prosegue e al valore in ebx che la prima volta è la somma dei byte del file tolgo la somma degli ultimi 5 byte (loop :401315 :401318) che compongono il file stesso e se il risultato è uguale a 1314 allora proseguo altrimenti ritorno su.
Qui abbiamo il primo punto veramente critico, la prima cosa a cui pensiamo è fare in modo che i byte combacino per saltare subito ma questo ci darà un notevole fastidio in seguito. Mi spiego meglio, tutto sta ad avere nella locazione 40235B il valore l (per non essere sbattuti fuori al salto successivo una volta usciti dal ciclo) ma come si fa a mettercelo? Qui stà il bello (vi garantisco che senza IDA capire il trick è veramente dura perchè il disassemblato WDasm32 non vi dice nulla su come si arriva lì e vi spiegherò dopo perchè in queso si ha (secondo me e non so se questo sia vero...) la debolezza del WDasm32 usato come debugger)

L'idea per vedere chi dovrebbe mettere il valore 1 in 40235B è stato cercare nel disassemblato 40235B (con un search normalissimo)e vi riporto cosa dice IDA:

00401168 loc_401168: ; CODE XREF: start+13Bj
00401168 push ds:dword_4023F8
0040116E call j_ExitProcess     ; NON CI INTERESSA MA CI FA CAPIRE FINO A DOVE RISALIRE
00401173
00401173 loc_401173: ; DATA XREF: start+B5^o   SI PARTE DA QUA
00401173 mov edx, [esp+0FFFFFFFCh+arg_4]
00401177 push ebx
00401178 push edi
00401179 push esi
0040117A mov esi, [edx]     ; TUTTO QUESTO LO SPIEGA QUE NEL TUT SUL SEH
0040117C mov edi, [edx+4]
0040117F mov ecx, [esi]
00401181 cmp ecx, 0C0000094h
00401187 jz short loc_40118D    ; DA FARE
00401189 xor eax, eax
0040118B jmp short loc_4011C2   ; SEI FUORI BASTARDO
0040118D ; ---------------------------------------------------------------------------
0040118D
0040118D loc_40118D: ; CODE XREF: start+187j
0040118D add dword ptr [edi+0B8h], 2
00401194 mov dword ptr [edi+0B0h], 1
0040119E mov eax, [edi+0A0h]
004011A4 inc eax
004011A5 mov eax, [eax]
004011A7 ror eax, 17h
004011AA cmp eax, 68AA9870h
004011AF jnz short loc_4011BB
004011B1 mov ds:dword_40235B, 1   ; TROVIAMO QUESTO E RISALIAMO PER VEDERE DA DOVE SI PARTE

Seguendo le mie bellissime label dovreste capire da dove si parte cioè alla locazione :401173 si fanno un po di conti e si arriva all'istruzione che ci interessa ma la routine la vediamo più avanti perchè ora mi interessa farvi capire come si arriva qui a questo punto del codice...O la peppa andate a vedere dove vi riporta il DATA XREF: start+B5 che IDA vi riporta  e arriverete nientepopodimeno che qui:

004010B5 push offset loc_401173
004010BA call j_SetUnhandledExceptionFilter     ; leggetevi il tut di Que (e due)

Queste righe sono all'inizio durante l'inizzializzazione del prog ; vi rendete conto che per mettere il valore 1 in quella locazione devo generare un'eccezzione...
Il bravo reverser dovrebbe intuire subito che l'unica istruzione potenzialmente pericolosa che potrebbe generare un'eccezzione è proprio il DIV ECX che stava alla locazione :4012FB (un DIV 0 genera un INT 0 che è un'eccezzione) ma io non sono un bravo reverser e mi sono affidato ad un'altra strada... e qui ci sono arrivato solo dopo  (Il crackme l'avevo risolto prima del tut di Que sul SEH altrimenti dal codice si sarebbe capito al volo il tipo di eccezzione generata)
Proseguiamo con il ciclo di conti precedenti che ci deve dare ancora molte informazioni, il ragionamento che ho seguito io è stato questo: osservando cosa succede la prima volta che viene eseguito il ciclo di istruzioni :4012F2 :401231 ho osservato dove andava a finire esi ,che all'inizio, puntava un byte sottoall'ultimo byte del file (istruzione :4012F1). Durante il ciclo (notate il direction flag come varia) esi viene abbassato di 5 byte quindi dopo il primo ciclo esi punta 5 byte prima della fine del file (vi potete imaginare che ad ogni ciclo io sposti il puntatore volendomi avvicinare verso il primo byte del file,a questo proposito vi consiglio per chiarirvi le idee di dare un paio di steppatine in questo ciclo e tutto vi sara chiaro); a questo punto la tentazione è quella di far un keyfile la cui somma dei byte è 141C e se gli tolgo la somma degli ultimi 5 byte ho 1314 e salto subito ma questo non va bene e vi spiego a cosa avevo pensato io: osservate il codice sotto ed esattamente l'istruzione :401388 (cmp al,[esi+31h] ),non vi dice nulla, oki vi do una mano, allora io ho pensato se esi puntasse all'inizio del file questo sarebbe l'ultimo byte del file stesso (lunghezza file 32h),dunque dovrei ripetere quel ciclo almeno 50/5=10 volte (almeno perchè non vavevo notato il ADD ESI,6 che arrivava a fine ciclo) per fare in modo che esi puntasse all'inizio del file ma questo avrebbe voluto dire che a un certo punto in edi avrei dovuto avere il valore 1314 per il famoso compare che mi faceva uscire da ciclo,(tutto questo e necessario altrimenti esi+31h non sarebbe stato un byte del keyfile) be è ora di mettersi a fare dei conti mi sono detto e sono andato a rispulciare la tabella di prima e il codice   
Ora vi spiego: l'istruzione :4012F2 non fa altro che mettere in eax ad ogni ciclo il valore ottenuto togliendo dal valore precedente il valore degli ultimi 5 byte risalendo col puntatore (in esi) meglio detto al primo ciclo ho in eax la somma dei byte (141C) al secondo 141C meno la somma degli ultimi 5,al terzo 141C meno la somma degli ultimi 10 (e così via per ogni ciclo portando esi verso il primo byte del file) Questa scelta comporta l'obbligo di dover rispettare la divisione perfetta (:4012FB) con i valori della tabella che avevo in edi (ricordate), questo comporta che la somma degli ultimi 5 byte sia 141C-1314=108 (sarà la somma degli ultimi 5 byte), al secondo giro in eax dovrò avere lo stesso valore che ho in ecx per la divisione perfetta quindi sara 1314-1061=2B3 (sarà la somma dei byte dal 40 al 44 esimo) e così via risalite a quale deve essere la somma dei gruppi da 5 byte (e come al solito per capire bene vi consigli una ciclatina di istruzioni osservando come cambia la tabella)
Vi riporto direttamente quale deve essere la somma dei gruppi da 5 byte

(byte 0 è il primo del file per mantenere la corrispondenza con esi+00, si parte dal fondo per arrivare all'inizio)
Somma Byte da 0 a 4 =  141C- la somma di tutti gli altri =12D
Somma Byte da 5 a 9 =33B
Somma Byte da 10 a 14 =100
Somma Byte da 15 a 19 =24F
Somma Byte da 20 a 24 =27B
Somma Byte da 25 a 29 =23E
Somma Byte da 30 a 34 =8E
Somma Byte da 35 a 39 =1061-0CFE=363
Somma Byte da 40 a 44 =1314-1061=2B3
Somma Byte da  45 a 49 =141C-1314=108

E' ora di costruirsi il primo KeyFile di nome Clef.l48 che deve essere lungo 50 bye dove la somma dei primi 5 byte è 12D queel a dei byte da 5 a 9 è 33B e così via e vediamo che succede (teniamo presente che non abbiamo ancora risolto il problema di avere 1314 in esi necessario per proseguire)
A questo punto sono andato a controllare cosa stava sopra esi (prima di entrare nel ciclo la prima volta) e esattamente in esi-31 che ovviamente se avete capito era il primo byte del file (be ci stava la tabella e naturalmente il 141C e sopra 1314 e 0CFE..., BINGO tirando giu esi con i cicli c'era la concreta probabilita che al momento giusto avrei avuto in esi il valore 1314, che mi avrebbe fatto proseguire) la via era stata individuata un primo keyfile preparato e si va a provare
A questo punto io ho ciclato per tutti i valori della tabella facendo decrescere edi di word in word fino a che l'ultimo valore che ho nella div è proprio 0000 che altro non fa che generare quell'eccezzione a cui tanto agognavo
Ora è necessario usare Sice e vi spiego perchè se avete usato il WDasm32 come debbugger da questo punto in poi siete fottuti

DIGRESSIONE: Ora vi dico quello che penso e non so se corrisponde a verità quindi prendete quello che dico con le pinze: il programma per proseguire genera appositamente un'eccezzione con una DIV 0 che genera un INT 0 il WDasm32 trappa l'eccezzione prima dell'handler installato dal programma stesso e ne impedisce la prosecuzione, morale della favola questo costituisce un trick contro l'uso del WDasm32 come debugger e quindi è necessario usare Sice per proseguire, il trick non è probabilmente voluto (credo) ma sicuramente sarebbe interessante sapere come si comporta il WDasm32 di fronte alle eccezzioni (in realtà il WDasm32 ciaverte dell'eccezzione avvenuta e ci chiede se proseguire ma poi si pianta) ma qui si va in un campo troppo elevato per me quindi se qualche MOSTRO SACRO che si è reversato il WDasm32 ha voglia di darmi delucidazioni lo prego di darmi qualche dritta sull'argomento,cmq il trick, involontario o no, resta ed è utilizzabile a tutti gli effetti (A proposito neanche dal disassemblato riuscite a risalire all'handler dell'eccezzione col WDasm32 ma forse lo avevo già detto)  

Riprendiamo vedendo che prima del div 0 esi punta a un byte sopra il primo byte del file, e eseguendo il div 0 l'handler mi spara dritto a :401773 dove il codice interessante per noi è quello che va da :40119E :4011AA ve lo riporto: (capirete il perchè leggendovi il tut di Que sul SEH)

0040119E mov eax, [edi+0A0h] ; muove in eax lo stesso puntatore di esi prima del div 0
004011A4 inc eax            ; eax puntava a un byte sopra il primo del file dopo inc                           ; punta al primo byte del file
004011A5 mov eax, [eax]
004011A7 ror eax, 17h
004011AA cmp eax, 68AA9870h   ; deve essere uguale
004011AF jnz short loc_4011BB
004011B1 mov ds:dword_40235B, 1 


Vanno notate un paio di cose: il valore che rorrato con 17 da 68AA9870 è 3834554C ma per avere questo valore in eax all'istruzione :4011A7 devo fare in modo che eax punti a 4C 55 34 38 (invertiti) all'istruzione :4011A5 cioè i primi quattro byte del KeyFile devono essere proprio 4C 55 34 38 (cioè la stringa "LU48" che caso)  e l'ultimo byte del primo gruppo di 5 byte sarà 12D-4C-55-34-38=20 (cioè lo spazio).Bene abbiamo i primi 5 byte del keyfile ce ne restano solo 45...

Quando ritorno eseguo il resto del ciclo e abbasso ancora esi di 5 byte e con questo si spiega l'istruzione all'uscita del ciclo add esi,6 che fa si che si esca dal ciclo con esi+00 che punta al primo byte del file, notate che tirando esi giù ancora di 5 prima di sommargli 6 ho proprio il valore 1314 in esi che mi permette di uscire dal ciclo e proseguire e a questo punto l'handler ha gia aggiustato il valore 40235B e finalmente arrivo a :401134 (TUTTO ALLA FINE E' TORNATO)

Ora la parte didattica (calcolando che ho il diploma magistrale mi posso permettere questa affermazione)e forse più interessante èconclusa e il resto è solo una barca di considerazioni matematiche che io ho trovato interessanti perchè sono un maniaco ma voi non so, il resto è solo un bordello di incroci tra i restanti 45 byte de keyfile ma se siete arrivati fin qui vi consiglio di proseguire perchè vi farò vedere come si trovano i buchi in un algoritmo (anche se questo non è un algoritmo ma una serie MOLTO LUNGA di restrizioni da rispettare)

Vi riporto il tutto e vi ricordo che il nostro scopo è arrivare a :40149E senza essere sbattuti fuori.
Allora come potreste rappresentare il codice sotto, vi dico come ho ragionato io.
Possiamo rappresentare il tutto come un "sistema (non proprio) lineare" in 45 incognite (non è propriamente lineare per via di quache ror,shr,ecc) cioè ogni compare può essere visto come la parte finale di un'equazione; per risolvere un sistema in 45 incognite il mio caro professore di MATEMATICA APPLICATA mi diceva che erano necessarie 45 equazioni (linearmente indipendenti) e se ne avevo di meno avrei avuto delle variabili che potevano assumere un valore arbitrario
A questo punto si procede così (prendo la prima parte del codice sotto)

00401334 mov al, [esi+12h]       ; esi+12 lo chiamo A
00401337 add al, [esi+13h]       ; esi+13 lo chiamo B
0040133A cmp al, [esi+15h]       ; esi+15 lo chiamo C e deve essere uguale ad A+B
0040133D jnz Sbattuto_Fuori

Va notata la seguente cosa i nomi A,B,C... servono solo per un fattore di comprensibilità, sotto ad ogni riga faccio corrispondere il numero decimale corrispondente ad ogni byte e la lettera e ripoto tutto in una tabella word che trovate alla fine per avere tutto più chiaro e compatto 

00401334 mov al, [esi+12h] ; 18 A
00401337 add al, [esi+13h] ; 19 B
0040133A cmp al, [esi+15h] ; 21 A+B
0040133D jnz Sbattuto_Fuori
00401343 mov al, [esi+25h] ; 37
00401346 rol al, 4
00401349 cmp al, [esi+2Fh] ; 47
0040134C jnz Sbattuto_Fuori
00401352 mov al, [esi+0Dh] ; 13
00401355 cmp al, [esi+10h] ; 16
00401358 ja Sbattuto_Fuori
0040135E mov al, [esi+0Ah] ; 10 C
00401361 add al, [esi+20h] ; 32 D
00401364 sub al, [esi+22h] ; 34 E
00401367 sub al, [esi+4]   ; 4  20h (valore noto)
0040136A cmp al, [esi+8]   ; C+D-E-20h
0040136D jnz Sbattuto_Fuori
00401373 mov al, [esi+7]   ; 7 C
00401376 cmp al, [esi+0Ah] ; 10 C
00401379 jnz Sbattuto_Fuori
0040137F mov al, [esi+14h] ; 20
00401382 mov ah, al
00401384 shr al, 1
00401386 xor al, ah
00401388 cmp al, [esi+31h] ; 49
0040138B jnz Sbattuto_Fuori
00401391 mov al, [esi+0Eh] ; 14 F
00401394 add al, [esi+19h] ; 25 G
00401397 add al, [esi+22h] ; 34 E
0040139A cmp al, [esi+23h] ; 35 F+G+E
0040139D jnz Sbattuto_Fuori
004013A3 movzx ax, byte ptr [esi+11h] ; 17
004013A8 movzx cx, byte ptr [esi+0Bh] ; 11
004013AD xor dx, dx
004013B0 mul cx
004013B3 sub al, [esi+8]   ; 8
004013B6 cmp al, [esi+13h] ; 19
004013B9 jnz Sbattuto_Fuori
004013BF mov al, [esi+28h] ; 40 I+2
004013C2 sub al, [esi+27h] ; 39 I
004013C5 cmp al, 2
004013C7 jnz Sbattuto_Fuori
004013CD cmp byte ptr [esi+2Ch], 49h ; 44 49h(valore)
004013D1 jnz Sbattuto_Fuori
004013D7 mov al, [esi+4] ; 4 20h(val)
004013DA add al, [esi+0Fh] ; 15 L
004013DD add al, [esi+18h] ; 24 M
004013E0 cmp al, [esi+5]   ; 5 20h+L+M
004013E3 jnz Sbattuto_Fuori
004013E9 mov al, [esi+1Ah] ; 26
004013EC mov cl, [esi+30h] ; 48
004013EF ror al, cl
004013F1 cmp al, [esi+12h] ; 18
004013F4 jnz Sbattuto_Fuori
004013FA mov al, [esi+6]   ; 6 O
004013FD add al, [esi+1Fh] ; 31 P
00401400 cmp al, [esi+1Ch] ; 28 O+P
00401403 jnz Sbattuto_Fuori
00401409 cmp byte ptr [esi+2Dh], 44h ; 45 44h (val)
0040140D jnz Sbattuto_Fuori
00401413 mov al, [esi+2Eh] ; 46
00401416 cmp al, [esi+22h] ; 34
00401419 jnb Sbattuto_Fuori
0040141F mov al, [esi+14h] ; 20 Q
00401422 add al, [esi+19h] ; 25 G
00401425 sub al, [esi+6]   ; 6 O
00401428 cmp al, [esi+0Bh] ; 11 B=Q+G-O
0040142B jnz Sbattuto_Fuori
00401431 mov al, [esi+0Ch] ; 12 S
00401434 add al, [esi+16h] ; 22 T
00401437 add al, [esi+20h] ; 32 D
0040143A add al, [esi+2Ah] ; 42 U
0040143D cmp al, [esi+9]   ; 9 S+T+D+U
00401440 jnz short Sbattuto_Fuori
00401442 mov al, [esi+0Dh] ; 13 K
00401445 add al, [esi+0Fh] ; 15 L
00401448 sub al, [esi+7]   ; 7 C
0040144B cmp al, [esi+1Ah] ; 26 K+L-C
0040144E jnz short Sbattuto_Fuori
00401450 mov al, [esi+29h] ; 41
00401453 xor al, [esi+26h] ; 38
00401456 shr al, 3
00401459 sub al, [esi+21h] ; 33
0040145C cmp al, [esi+1Eh] ; 30
0040145F jnz short Sbattuto_Fuori
00401461 mov al, [esi+2Ah] ; 42 Z
00401464 sub al, [esi+5]   ; 5 20h+L+M
00401467 cmp al, [esi+11h] ; 17 Z-20h-L-M
0040146A jnz short Sbattuto_Fuori
0040146C mov al, [esi+27h] ; 39
0040146F shl al, 2
00401472 cmp al, [esi+17h] ; 23
00401475 jnz short Sbattuto_Fuori
00401477 movzx ax, byte ptr [esi+0Eh] ; 14
0040147C movzx cx, byte ptr [esi+22h] ; 34
00401481 xor dx, dx
00401484 div cx
00401487 cmp al, [esi+1Eh] ; 30
0040148A jnz short Sbattuto_Fuori
0040148C cmp dl, [esi+0Dh] ; 13
0040148F jnz short Sbattuto_Fuori
00401491 mov al, [esi+1Dh] ; 29
00401494 cmp al, [esi+1Bh] ; 27
00401497 jbe short Sbattuto_Fuori
00401499 call j_CloseHandle
0040149E push offset aStatusRegister ; "Status: registered"
004014A3 push 0
004014A5 push 0Ch
004014A7 push 6Eh
004014A9 push ds:Dialog_parameters
004014AF call j_SendDlgItemMessageA
004014B4 jmp short loc_4014FB

Bella stà tabella che dite, io l'ho usata per riordinare tutte le equazioni in funzione delle lettere che avevo assegnato e alla posizione dei byte e mi sembra una cosa abbastanza carina:

 

12D 33B=FF+FF+FF+3E 100=FF+1 24F=FF+FF+51 27B=FF+FF+7D
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
L U 4 8 20 20+L+M O C C+D-E-20 S+T+D+U C Q+G-O S K F L   Z-20-L-M A B Q A+B T   M
G K+L-C   O+P     P D   E F+G+E inc     I I+02   Z inc 49 44        
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
23E=FF+FF+40 8E 363=FF+FF+FF+66 2B3=FF+FF+B5 108=FF+09

Allora questa tabella necessita ancora di un paio di chiarimenti prima di proseguire:

  1. sono state riportate solo le equazioni che contenevano esclusivamente add e sub perchè da un punto di vista algebrico sono le più facili da maneggiare una volta stabiliti dei valori per certi byte, che devo imporre a priori(infatti come accennato sopra ho meno di 45 equazioni tre l'altro molte non lineari)
  2. le caselle vuote sono rappresentative di byte utilizzati in equazioni che comprendono xor,shr,mul,ecc... e vedremo proprio che saranno queste che nonostante la complessità ci permetteranno di bucare il 90% delle restrizioni
  3. terzo e assolutamente da non trascurare è la dimensione dei gruppi da 5 byte che scritta in questa maniera vi da un'informazione fondamentale che ora vi spiego (a parte che vi da subito una maniera veloce per costruirvi un primo keyfile di prova infatti i primi 10 byte saranno LU48 20 FF FF FF 3E 00 dove a posto di LU48 dovrete sostituire gli hex relativi ai char ovvio): l'informazione da non trascurare è questa; considerate il secondo gruppo di 5 byte la cui somma deve essere 33B, è necessario per questo gruppo che almeno 4 byte su 5 siano diversi da 0, e questa cosa dovete tenerla bene a mente perchè dovendo imporre dei valori per alcuni byte per avere un punto di partenza l'ideale sarà azzerare qualche cosa (per semplificare ovvio) ma è logico che non potremo azzerare molto qui dovendo ottenere un somma abbastanza alta
  4. gli inc stanno per incognito cioè sono byte dal valore completamente arbitrario e non rientrano in nessuna equazione che potremo usare alla fine per far tornare la somma dei vari gruppi di byte
  5. è mantenuto anche l'ordine degli operandi nelle equazioni per evitare fonte di errori anche se remoti (esempio FF+FF=1FE ma noi faremo dei compare solo su FE e mantenendo l'ordine degli operandi si mantiene il flusso di esecuzione delle operazioni nei registri inalterarto)   

Dunque ora si tratta di ridurre al minimo le incognite e l'idea più furba che ho trovato è stato proprio usare le equazioni che contenevano xor,shr e compagnia bella a mio favore e vado a farvi vedere cosa intendo punto per punto
Consideriamo questo gruppetto di isruzioni:

004013E9 mov al, [esi+1Ah] ; 26
004013EC mov cl, [esi+30h] ; 48
004013EF ror al, cl
004013F1 cmp al, [esi+12h] ; 18
004013F4 jnz Sbattuto_Fuori

Dovreste notare che il byte 48 non è utilizzato in nesun'altra equazione quindi quindi se il byte 26 avesse valore 0 il byte 48 potrebbe acquistare qualsiasi valore (quindi diventerebbe un'incognita) a patto che anche il byte 18 abbia valore 0; questo ci porta ad attribuire ai byte 26 e 18 il valore 0 e mettere un inc a 48 (abbiamo guadagnato un valore arbitrario mica male ) in più guardando  la tabella ci si accorge che il byte 18 corrisponde all'incognita A quindi in ogni equazione dove compare la A sostituiremo uno 0 e al byte 26 abbiamo K+L-C=0 cioè ad ogni K potremo sostituire C-L (vediamo la nuova tabella)

12D 33B=FF+FF+FF+3E 100=FF+1 24F=FF+FF+51 27B=FF+FF+7D
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
L U 4 8 20 20+L+M O C C+D-E-20 S+T+D+U C Q+G-O S C-L F L   Z-20-L-M 00 B Q B T   M
G 00   O+P     P D   E F+G+E inc     I I+02   Z inc 49 44     inc  
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
23E=FF+FF+40 8E 363=FF+FF+FF+66 2B3=FF+FF+B5 108=FF+09

Secondo pezzo di codice:

0040137F mov al, [esi+14h] ; 20
00401382 mov ah, al
00401384 shr al, 1
00401386 xor al, ah
00401388 cmp al, [esi+31h] ; 49


Senza fare nessun conto, come prima, se il byte 20 è uguale a 0 segue il byte 49 è uguale a 0 e anche l'incognita Q acquista valore 0
Terzo pezzo di codice:

004013A3 movzx ax, byte ptr [esi+11h] ; 17
004013A8 movzx cx, byte ptr [esi+0Bh] ; 11
004013AD xor dx, dx
004013B0 mul cx
004013B3 sub al, [esi+8]   ; 8
004013B6 cmp al, [esi+13h] ; 19
004013B9 jnz Sbattuto_Fuori


Abbiamo una mul quindi l'idea è azzerare uno dei due moltiplicatori ma se guardate la tabella il byte 17 è meglio non toccarlo e mettiamo il byte 11 a zero questo ci permette anche di dire che il valore nel byte 19 è uguale a -valore del byte in 8 cioè B sarà uguale a -valore in 8;  c'è anche il fatto che G=O se il byte in 11 è uguale a 0 (e vi riporto la tabella)

12D 33B=FF+FF+FF+3E 100=FF+1 24F=FF+FF+51 27B=FF+FF+7D
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
L U 4 8 20 20+L+M G C C+D-E-20 S+T+D+U C 00 S C-L F L   Z-20-L-M 00 -C-D+E+20 00 -C-D+E+20 T   M
G 00   G+P     P D   E F+G+E inc     I I+02   Z inc 49 44     inc 00
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
23E=FF+FF+40 8E 363=FF+FF+FF+66 2B3=FF+FF+B5 108=FF+09

Quarto pezzo:

00401477 movzx ax, byte ptr [esi+0Eh] ; 14
0040147C movzx cx, byte ptr [esi+22h] ; 34
00401481 xor dx, dx
00401484 div cx
00401487 cmp al, [esi+1Eh] ; 30
0040148A jnz short Sbattuto_Fuori
0040148C cmp dl, [esi+0Dh] ; 13


Se impongo il byte 14 uguale a 0 (cioè anche F=0) il byte 34 è arbitrario e il byte 30 e il byte 13 (C=L) devono essere uguali a zero
Quinto:

00401450 mov al, [esi+29h] ; 41
00401453 xor al, [esi+26h] ; 38
00401456 shr al, 3
00401459 sub al, [esi+21h] ; 33
0040145C cmp al, [esi+1Eh] ; 30


Se byte 41 è uguale a byte 38 (li chiamo con Y) byte 30 l'ho appena messo a 0 segue byte 33 uguale a 0
NELLA TABELLA C'E' UNA SVISTA E VALE U UGUALE A Z L'HO ASSEGNATO 2 VOLTE (QUINDI IMPONETE QUESTA NUOVA EQUAZIONE U=Z) e vi riporto la tabella  e mi sono di assegnare anche il byte 46 uguale al 34 tanto nel codice c'era un jnb

Vorrei farvi notare che senza far alcun conto sono state eliminati tutti i gruppi di codice più incasinati...(LOGCAMENTE LE STRADE  POSSIBILI SONO INFINITE)

12D 33B=FF+FF+FF+3E 100=FF+1 24F=FF+FF+51 27B=FF+FF+7D
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
L U 4 8 20 20+C+M G C C+D-E-20 S+T+D+Z C 00 S 00 00 C   Z-20-C-M 00 -C-D+E+20 00 -C-D+E+20 T   M
G 00   G+P   00 P D 00 E G+E inc   Y I I+02 Y Z inc 49 44 E   inc 00
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
23E=FF+FF+40 8E 363=FF+FF+FF+66 2B3=FF+FF+B5 108=FF+09

Ora vi riporto la tabella con le altre relazioni per le poche caselle ancora vuote:

12D 33B=FF+FF+FF+3E 100=FF+1 24F=FF+FF+51 27B=FF+FF+7D
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
L U 4 8 20 20+C+M G C C+D-E-20 S+T+D+Z C 00 S 00 00 C >00 Z-20-C-M 00 -C-D+E+20 00 -C-D+E+20 T I shl 02 M
G 00 <W G+P W 00 P D 00 E G+E inc X Y I I+02 Y Z inc 49 44 F inv X inc 00
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
23E=FF+FF+40 8E 363=FF+FF+FF+66 2B3=FF+FF+B5 108=FF+09

Vi spiego cosa intendo per INV X nel byte 23: se guardate il codice vi accorgete che se X ha il valore 34 allora INV X è 43 e se X è D4 allora INV X 4D e così via

Una bella sfoltita è stata data ma il problema diventa questo ora: quanto ancora mi posso spingere con le semplificazioni ? Prendete per esempio i byte da 10 a 14 li non posso più azzerare niente se voglio che la somma dei byte sia uguale 100 quindi se ben guardate, semplificare ulteriormente  diventa troppo restrittivo quindi non ci resta che iniziare a tirar fuori dei valori e provare a far tornare il tutto 
Ci tengo a dire che una strada vera a propria a questo punto non c'è è più che altro si può andare a tentativi il più mirati possibili (ma pur sempre tentativi) quindi non mi resta che darvi il keyfile che ho trovato io darvi un'idea dei valori da cui sono partito
Diciamo che sarebbero da evitare i byte da 5 a 9 e da 15 a 19 (troppe variabili) e anche quelli da 10 a 14 (troppo poche), io sono partito attribuendo i valori alle variabili P,D,E dei byte 30 a 34 anche perchè potendo mettere a posto la somma dei byte anche con un valore solo (uguale a 8E) mi sembrava il punto ideale ma tutte le strade a questo punto suno buone dato che comunque si va per tentativi (HO FATTO PARECCHI TENTATIVI)

Vi riporto ora il keyfile che ho trovato io

12D 33B=FF+FF+FF+3E 100=FF+1 24F=FF+FF+51 27B=FF+FF+7D
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
4C 55 34 38 20 1E E0 FF AB 93 FF 00 01 00 00 FF B3 48 00 55 00 55 FF 28 FF
E0 00 18 E0 66 00 00 2D 00 61 41 69 F0 FF CA CC FF 66 39 49 44 60 0F 55 00
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
23E=FF+FF+40 8E 363=FF+FF+FF+66 2B3=FF+FF+B5 108=FF+09

Ale finalmente ho finito non ne potevo più di scriverema ne è valsa la  pena.

Con questo vi saluto e alla prossima

                                                                                                                           By GuZuRa




Note finali

 
E' il momento dei saluti che questa volta sono indirizzati particolarmente a Ritz al quale rompo sistematicamente le balle su #crack-it con le mie domande molto leim

La seconda riga per salutare tutti gli amici di #crack-it e della ML troppi per nominarli tutti ... Vi lascio dicendovi che ho passato ELETTRONICA 2 quindi sono molto felice. E' tutto by.

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 è 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.
Capitoooooooo????? Bhè credo di si ;))))