Crackiamo Enalotto 3.1 con il RegOpenKeyA attack

 

Salve gente, qualche tempo fa qualcuno, non ricordo con esattezza chi, mi chiese di crackare Enalotto 3.1 (http://www.daniele.net) perchè si era incartato nel codice della generazione del seriale, la sera stessa scaricai il programma e gli detti uno sguardo ma poi lo lasciai stare per molto tempo fino a che non venne ieri che avevo 10 minuti liberi.....e finalmente ecco il crack.
Il programma una volta installato ci presenta un noioso nag che ci dice quanti giorni possiamo ancora usare il programma e quante volte, la cosa è in effetti un po' frustrante specie per i giocatori di Super-Enalotto che giocano 2 volte a settimana, ma ecco la storia di questo crack minuto per minuto:
ore 17:49 -- Chiama la mia ragazza e mi dice di andarla a prendere alle 18:30
ore 17:51 -- Entro nella doccia
ore 18:14 -- Esco dalla doccia
ore 18:15 -- Accendo il computer e do uno sguardo al programma, ho solo 10 minuti
ore 18:16 -- Provo un metodo
ore 18:18 -- Ne provo un altro
ore 18:19 -- Provo il terzo
ore 18:24 -- Crack pronto
 
Allora allorino, la prima volta che ho aperto il programma ho messo un bp su GetWindowTextA ed ho tracciato per un po', dopo poco noto delle cose nel debugger, esco e metto un bp su GetDlgItemTextA, premo ok....d'ho! Mi traccia anche così, nulla da fare, provo allora a mettere un bp su MessageBoxA, traccio ancora un po' ma vedo che c'è una vera e propria giungla di jump.......Si accende la lampadina e mi vien voglia di mettere un bp su RegOpenKeyA, trovo i punti e li patcho con Sice...... Ottimo tutto funziona ed esco.
Giorno Seguente:
Disassemblo il file col WDASM, trovo i rispettivi virtual address, ci clicco sopra, prendo nota dell'offset, apro il file con l'Hex-Workshop, vado a quell'offset ma...Porko *** non trovo i jump, i byte sono diversi dal disassemblato, chiudo tutto, apro lo stesso file con IDA Pro, patcho il prog, provo ad usare l'opzione "generate exe file" ma IDA dice che non può generare eseguibili per winzoz...Ariporko ***, allora prendo nota dei byte prossimi ai due jump e li cerco con l'Hex WorkShop, li trovo e noto anche una cosa, cioè: il W32dasm quando cliccavo sul primo jump mi dava l'offset dell'altro jump ed il secondo quando ci cliccavo sopra mi dava l'offset del primo.....Ecco perchè non li trovavo hehehe ;)) 
Aspettate un secondo che vado a vedere Heidi....Rieccomi, allora iniziamo a crackare il programma, installatelo, andate sulla barra di applicazione, programmi, enalotto e mettete il cursore su "ENALOTTO", ^D per aprire il debugger, piazzate un bel bp su RegOpenKeyA e uscite, immediatamente cliccate sul nome del prog, premete una volta F11 e poi F12 per 27 volte finchè sarete qui:
 
_20_20tea:0053B39C      push offset str->Systemappids
_20_20tea:0053B3A1      push 80000000h
_20_20tea:0053B3A6      call ds:RegOpenKeyA_0 
<--- Arriviamo da qui
_20_20tea:0053B3AC      test eax, eax
_20_20tea:0053B3AE      jz short _20_20tea_53B3BC 
<---- Dobbiamo noppare questo
_20_20tea:0053B3B0      mov ax, 2
_20_20tea:0053B3B4      pop ebp
_20_20tea:0053B3B5      pop edi
_20_20tea:0053B3B6      pop esi
EAX nel nostro caso conterrà 0, clicchiamo sulla finestra dei registri proprio su EAX e sostituiamo l'ultimo numero con 1, facciamo questo per non cambiare per il momento il codice, fatto ciò premete F12 per 10 volte ed approderete qui:
 
_20_20tea:00538BF7     mov [ebp+var_48], 1
_20_20tea:00538BFE     mov eax, [ebp+arg_8]
_20_20tea:00538C01     mov ds:_data_53F984, eax
_20_20tea:00538C06     mov edx, offset _data_53FA00
_20_20tea:00538C0B     lea ecx, _data_53F961
_20_20tea:00538C11     call _20_20tea_53BCD0
_20_20tea:00538C16     call _20_20tea_53BD00
<--- Controlla se il prg è registrato ;)
_20_20tea:00538C1B     test eax, eax 
<--- EAX = 0 ? Programma non registrato  
_20_20tea:00538C1D     jz _20_20tea_538C3B
<--- Salta se EAX=0, noppiamo questo ;)
_20_20tea:00538C23     mov ds:_data_53D348, 1
_20_20tea:00538C2C     mov ds:_data_53D2FC, 1
_20_20tea:00538C36     jmp _20_20tea_538EC0
 
Occhei, abbiamo trovato i jumperilli e li abbiamo patchati dal debugger, adesso dobbiamo farlo fisicamente, apriamo wdasm cerchiamo 0053B3AE e 00538C1D, doppioclicchiamoci sopra e vediamo l'offset che ci restituisce in basso a destra, prendiamone nota, apriamo il file con l'Hex-Workshop, clicchiamo su "Go to Offset" e inseriamo il nostro offset, premiamo invio e come vi accennavo prima ecco che non troviamo corrispondenza tra i byte del disasm e quelli dell'hex editor, però notiamo che l'offset del primo jmp ci riporta al codice del secondo e quello del secondo al primo, quindi non dovremo fare altro che scambiare i byte da patchare, ecco una tabella nella quale vi riporto tutti i dati reali (offset compresi).
 
Virtual Address Istruzione del prog.

Cambiare in...

Offset "falso"

Offset "reale"

00538C1D

JZ (Jump if Zero)

NOP (90h)

1343AEh

131C1Dh

0053B3AE

JZ (Jump if Zero)

NOP (90h)

131C1Dh

1343AEh

 
Così tutto dovrebbe essere chiaro. +ORC docet et dicit: "Niente è incraccabile ed  ogni programmma può essere SEMPRE attaccato in più modi" con questo tutorial spero di avervi fatto capire che tutto ciò è vero, infatti considerato il tempo che avevo non avrei potuto cimentarmi nella routine di generazione del numero, allora ho cercato una strada più breve e l'ho trovata, vorrei precisare che questo metodo è pressocchè universale in quanto tutti i programmi che vogliono essere registrati tramite seriale, salvano il numero nel registro oppure in un .ini ed ogni volta che vengono avviati lo controllano, quindi possiamo mettere due rispettivi breakpoint cioè: bpx RegOpenKeyA oppure RegQueryValueA per i file che mettono il serial nel registro e: bpx GetPrivateProfileStringA per quelli che lo salvano in un file ini, le soluzioni che poi ci si presentano innanzi sono due cioè: eliminare la routine di check (e noi potevamo noppare tranquillamente la chiamata a 00538C16) così il programma diventa anche più veloce ;)))) oppure noppare i jump che la seguono, capitooooo!!!!!
Bene bene, con questo tute spero di aver spiegato questo tipo di attacco che, a dire il vero, non ho trovato documentato da nessuna parte ma sembra comunque promettente, cercherò di scrivere altri tutorial in merito, ho infatti notato in praticamente tutti i programmi che ho esaminato, che è messa molta più accuratezza nel nascondere la routine che genera il numero piuttosto che quella che lo controlla al riavvio del programma, questo tutorial sarà letto da poca gente e quindi potremmo fare affidamento su questo tipo di attacco ancora per molto ;))
 
Quequero