Copy Link
Add to Bookmark
Report

Win32asm KEYGEN

DrWatson's profile picture
Published in 
guide hacker
 · 6 years ago

tools necessari:
WDASM32
SOFTICE
MASM

programma target:
Programmer's IDE for Win95/NT (software by design)

Questo programma e' facilmente crackabile forzando il jump in determinati punti, ma anche una protezione poco efficente puo' essere un valido esercizio per le nostre menti bacate! Alla fine la filosofia del cracker non e' solo quella di riuscire, a tutti i costi, a violare un programma, ma soprattutto quella di CAPIRE cosa fa una sequenza di codice per il PURO e SEMPLICE PIACERE di SAPERLO e per ACQUISIRE CONOSCENZE che NON A TUTTI APPARTENGONO (soprattutto a certi programmatori). Proprio per questi motivi, A PURO SCOPO DIDATTICO, proveremo a fare un keygen:


Lanciamo il programma ed entriamo nella maschera di registrazione: viene richiesto il nome dell'utente, il nome della societa' ed un codice di registrazione.

inseriamo dei valori a caso e prima di dare "ok" entriamo in SoftIce (ctrl-D) e settiamo un bel : BPX GetDlgItemTextA. Appena dato l'OK al programma ci si presentera' subito la finestra del SoftIce, con F12 usciamo dalla API su cui abbiamo settato il break e torniamo nel nostro progz. Noteremo che la api viene chiamata da "call ebp" .

 
:0040F939 57 push edi
:0040F93A FFD5 call ebp < ---------- getdlgitemtexta
:0040F93C 6A32 push 00000032


Andando avanti con F10 il debugger si blocchera' alle chiamate ad ebp:

 
:0040F93E 53 push ebx
:0040F93F 6A66 push 00000066
:0040F941 57 push edi
:0040F942 FFD5 call ebp < ---------- getdlgitemtexta
:0040F944 8D442410 lea eax, dword ptr [esp+10]
:0040F948 6800010000 push 00000100
:0040F94D 50 push eax
:0040F94E 6A67 push 00000067
:0040F950 57 push edi
:0040F951 FFD5 call ebp < ---------- getdlgitemtexta
:0040F953 8D442410 lea eax, dword ptr [esp+10]
:0040F957 50 push eax
:0040F958 E8F3930000 call 00418D50
:0040F95D 83C404 add esp, 00000004
:0040F960 8BE8 mov ebp, eax
:0040F962 56 push esi


Usciti da questa sequenza troviamo la prima cosa interessante: dopo la call a 00417260 viene confrontato il contenuto di EAX con un certo valore, il fatto che ci siano dei riferimenti alle stringhe "Gregory Braun" e "Software Design" mi ha incuriosito molto quando ho disassemblato il programma e ho forzato il programma a non eseguire il salto alla riga 0040f970. Come risultato ho ottenuto una registrazione con quei dati! ...megalomania del programmatore?

Comunque il punto che ci interessa ancora non e' arrivato, io voglio registrare il programma con un qualsiasi nome, non con il nome di chi lo ha fatto! Quindi eseguiamo il salto ed andiamo avanti:

 
:0040F963 E8F8780000 call 00417260
:0040F968 83C404 add esp, 00000004
:0040F96B 3D92A71901 cmp eax, 0119A792
:0040F970 7518 jne 0040F98A ----------|
|
* Possible StringData Ref from Data Obj ->"Gregory Braun" |
| |
:0040F972 684C734200 push 0042734C |
|
* Reference To: KERNEL32.lstrcpyA, Ord:0296h |
| |
:0040F977 8B2DECB44300 mov ebp, dword ptr [0043B4EC] |
:0040F97D 56 push esi |
:0040F97E FFD5 call ebp |
|
* Possible StringData Ref from Data Obj ->"Software Design" |
| |
:0040F980 683C734200 push 0042733C |
:0040F985 53 push ebx |
:0040F986 FFD5 call ebp |
:0040F988 EB07 jmp 0040F991 |
|
* Referenced by a (U)nconditional or (C)onditional Jump at Address: |
|:0040F970(C) |
| |
:0040F98A 3D3CCE5F0D cmp eax, 0D5FCE3C < --------------|
:0040F98F 750C jne 0040F99D


Incredibile, un'altra comparazione di eax con un valore strano! Ma stavolta non ho indagato e sono andato avanti. Comunque si e' capito che il prog x verificare l'autenticita' della chiave confronta EAX con qualcosaltro ;)

Siamo arrivati alla parte di codice che ci interessa: vengono fatte due call a 00416d90 e il valore di EAX viene confrontato con EBP (indir. 0040f9a7) :

 
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040F988(U)
|
:0040F991 53 push ebx
:0040F992 56 push esi
:0040F993 E8F8730000 call 00416D90 < ------
:0040F998 83C408 add esp, 00000008
:0040F99B 8BE8 mov ebp, eax

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040F98F(C)
|
:0040F99D 53 push ebx
:0040F99E 56 push esi
:0040F99F E8EC730000 call 00416D90 < ------
:0040F9A4 83C408 add esp, 00000008
:0040F9A7 3BC5 cmp eax, ebp < ------ controllo codice
:0040F9A9 741E je 0040F9C9 < ------ se giusto registra il prog
:0040F9AB 68CFEA0000 push 0000EACF altrimenti viene mostrata
una message box di errore


Ecco la parte di codice che esegue il calcolo della chiave di registrazione: all'indirizzo 00416d90 viene caricato in EAX l'indirizzo del "nome dell'utente" all'indirizzo 00416d95 viene caricato in ESI l'indirizzo di una costante corrispondente al valore "CC0DEFED". Dopo la prima call a 00417260 vengono eseguite alcune operazioni sui registri, dopodiche' alla riga 00416dac viene caricato in EAX l'offset che punta al "nome dell'organizzazione" e viene eseguita nuovamente la call a 00417260. Tutti i valori puntati dai registri o presenti ad un certo indirizzo, sono facilmente ispezionabili con il comado "d" (display) del softice.

 
|:0040C722 , :0040F7D9 , :0040F993 , :0040F99F
|
:00416D90 8B442404 mov eax, dword ptr [esp+04] ; EAX < --- nome utente
:00416D94 56 push esi
:00416D95 8B35705D4200 mov esi, dword ptr [00425D70] ; ESI < --- CC0DEFED
:00416D9B 50 push eax
:00416D9C 81CE78030000 or esi, 00000378
:00416DA2 E8B9040000 call 00417260 < -------- 1^ call
:00416DA7 83C404 add esp, 00000004
:00416DAA 03F0 add esi, eax
:00416DAC 8B44240C mov eax, dword ptr [esp+0C] ; EAX < --- nome societa'
:00416DB0 50 push eax
:00416DB1 E8AA040000 call 00417260 < -------- 2^ call
:00416DB6 83C404 add esp, 00000004
:00416DB9 03C6 add eax, esi < - in EAX c'e' il codice ESATTO
per sbloccare il programma
:00416DBB 5E pop esi
:00416DBC C3 ret


Ora non rimane che vedere cosa succede quando viene eseguita la call a 00417260, quindi disabilitiamo il bpx GetDlgItemTexta e settiamo un bpx 00416da2 e bpx 00416db1, ridiamo l'OK sulla maschera di registrazione. Ci troveremo in questa parte di codice che processera' prima il nome dell'utente e poi, alla seconda call, il nome della societa':

 
:00417260 53 push ebx
:00417261 56 push esi
:00417262 8B74240C mov esi, dword ptr [esp+0C] < ----- ESI addr "nome utente"
:00417266 57 push edi
:00417267 55 push ebp
:00417268 33FF xor edi, edi
:0041726A 56 push esi

* Reference To: KERNEL32.lstrlenA, Ord:029Ch
|
:0041726B FF15F8B44300 Call dword ptr [0043B4F8] < ------ EAX lungh. "nome utente"
:00417271 85F6 test esi, esi < - controlla che ESI non sia 0
:00417273 7432 je 004172A7
:00417275 85C0 test eax, eax < - contolla che EAX non sia 0
:00417277 742E je 004172A7
:00417279 B900000000 mov ecx, 00000000 < - inizializza ECX a 0 x usarlo come contatore
:0041727E 7E27 jle 004172A7

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004172A5(C)
|
:00417280 0FBE9C08B89B4200 movsx ebx, byte ptr [eax+ecx+00429BB8] < - muove in EBX il contenuto di una particolare locazione di memoria *
:00417288 0FBE2C0E movsx ebp, byte ptr [esi+ecx] < - usa ECX come puntatore x processare tutti i bytes del "nome Utente"
:0041728C 8D5101 lea edx, dword ptr [ecx+01]
:0041728F 0FAFDD imul ebx, ebp
:00417292 0FBE89F09B4200 movsx ecx, byte ptr [ecx+00429BF0] < - muove in ECX il contenuto di una particolare locazione di memoria *
:00417299 0FAFD9 imul ebx, ecx
:0041729C 0FAFDA imul ebx, edx
:0041729F 03FB add edi, ebx
:004172A1 8BCA mov ecx, edx
:004172A3 3BC2 cmp eax, edx
:004172A5 7FD9 jg 00417280 < - esegue il ciclo fino a che non ha processato tutta la stringa

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00417273(C), :00417277(C), :0041727E(C)
|
:004172A7 8BC7 mov eax, edi
:004172A9 5D pop ebp
:004172AA 5F pop edi
:004172AB 5E pop esi
:004172AC 5B pop ebx
:004172AD C3 ret


* Questa routine esegue dei calcoli sulle stringhe inserite sulla maschera di registrazione, ma usa anche dei valori particolari presenti agli indirizzi 00429BB8 e 00429BF0, non ci resta che andare a vedere cosa contengono queste locazioni:

 
:00429BB8 23 73 65 72 42 26 6E 7A #serB&nz < -------
:00429BC0 7C 6D 66 4D 31 2F 35 28 |mfM1/5(
:00429BC8 21 73 64 24 4D 71 2E 7B !sd$Mq.{
:00429BD0 73 5D 2B 73 46 6A 74 4B s]+sFjtK
:00429BD8 70 7A 53 64 74 7A 6F 58 pzSdtzoX
:00429BE0 71 6D 62 5E 41 6C 40 64 qmb^Al@d
:00429BE8 76 3A 73 3F 78 2F 00 00 v:s?x/..
:00429BF0 7C 62 21 70 7A 2A 6C 73 |b!pz*ls < -------
:00429BF8 3B 72 6E 7C 6C 66 24 76 ;rn|lf$v
:00429C00 69 5E 41 78 70 65 29 72 i^Axpe)r
:00429C08 78 35 61 69 63 26 39 2F x5aic&9/
:00429C10 32 6D 35 6C 73 69 34 40 2m5lsi4@
:00429C18 30 64 6D 5A 77 39 34 63 0dmZw94c
:00429C20 6D 71 70 66 68 77 00 00 mqpfhw..
:00429C28 6D 41 50 49 20 66 75 6E mAPI fun
:00429C30 63 74 69 6F 6E 20 4E 4F ction NO
:00429C38 54 20 73 75 70 70 6F 72 T suppor


A questo punto siamo a conoscenza di tutti i dati che ci occorrono x fare la nostra keygen. Ho scelto di farla in Win32asm perche' con un semplice copia ed incolla, ed alcune piccole modifiche, della routine di calcolo del codice di registrazione e' possibile raggiungere lo scopo, senza neanche curarsi troppo di tutti calcoli che vengono eseguiti. Se avete gia letto il mio tute su come fare una patch noterete che lo scheletro e' del tutto analogo per entrambi i programmi, le cose cambiano quando viene premuto il tasto OK e la dialogbox e' diversa perche' questa volta dobbiamo inserire dei valori:

 
.386
.MODEL FLAT, STDCALL
include winicz.inc
includelib user32.lib
includelib kernel32.lib
includelib gdi32.lib

calcolo PROTO: DWORD

.data
DlgName db "MYDIALOG",0

dati1 db "#serB&nz|mfM1/5(!sd$Mq.{s]+sFjtKpzSdtzoXqmb^Al@dv:s?x/",0,0 ; dati estratti dalla locazione 00429BB8
dati2 db "|b!pz*ls;rn|lf$vi^Axpe)rx5aic&9/2m5lsi4@0dmZw94cmqpfhw",0,0 ; dati estratti dalla locazione 00429BF0

formato db "%lu",0
.data?
nome db 40 dup(?),0
societa db 40 dup(?),0
codice db 40 dup(0),0

hInstance HINSTANCE ?
hInstance1 HINSTANCE ?


.const
IDC_EDIT2 equ 3003
IDC_EDIT1 equ 3004
IDC_EDIT3 equ 3005
IDC_BUTTON2 equ 3007
IDC_EXIT equ 3000

.code

start:

invoke GetModuleHandle, NULL
mov hInstance,eax
invoke WinMain, hInstance,NULL,NULL, SW_SHOWDEFAULT
invoke ExitProcess,eax
WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:SDWORD
mov eax, OFFSET DlgProc
invoke DialogBoxParam, hInst, ADDR DlgName,NULL,eax,NULL
ret
WinMain endp
DlgProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
mov eax,hWnd
mov hInstance1,eax
mov eax,uMsg
.IF eax==WM_INITDIALOG
invoke SetFocus,eax
.ELSEIF eax==WM_CLOSE
invoke EndDialog, hWnd,NULL
.ELSEIF eax==WM_COMMAND
mov eax,wParam
.IF ax==IDC_BUTTON2
shr eax,16
.IF ax == BN_CLICKED

invoke GetDlgItemTextA,hInstance1,IDC_EDIT1,addr nome,40
invoke GetDlgItemTextA,hInstance1,IDC_EDIT2,addr societa,40

mov esi, 0cc0defedh ; valore estratto dalla loc. 00425D70
or esi, 00000378h
invoke calcolo, addr nome ; prima chiamata calcolo sul "nome utente"
add esi, eax
invoke calcolo, addr societa ; seconda chiamata calcolo sul "nome societa"
add eax, esi
invoke wsprintfA,addr codice, addr formato,eax ; il valore HEX viene convertito in decimale
invoke SetDlgItemText,hInstance1,IDC_EDIT3,addr codice ; visualizzazione del codice
invoke UpdateWindow, hInstance1
.ENDIF
.ELSEIF ax == IDC_EXIT
shr eax,16
.IF ax==BN_CLICKED
invoke EndDialog, hWnd,NULL
.ENDIF
.ENDIF
.ELSE
mov eax,FALSE
ret
.ENDIF
mov eax,TRUE
ret
DlgProc endp





calcolo proc aVariabile:dword

push ebx
push esi
mov esi, aVariabile
push edi
push ebp
xor edi, edi
invoke lstrlen, aVariabile
test esi, esi
je @@salto1
test eax, eax
je @@salto1
mov ecx, 00000000
jle @@salto1
@@salto2:
movsx ebx, byte ptr [eax+ecx+dati1]
movsx ebp, byte ptr [esi+ecx]
lea edx, dword ptr [ecx+01]
imul ebx, ebp
movsx ecx, byte ptr [ecx+dati2]
imul ebx, ecx
imul ebx, edx
add edi, ebx
mov ecx, edx
cmp eax, edx
jg @@salto2
@@salto1:
mov eax, edi
pop ebp
pop edi
pop esi
pop ebx

ret
calcolo endp

end start

Non credo che il keygen abbia bisogno di particolari spiegazioni bastera' confrontare la parte di codice che esegue le call a "calcolo" con qella del programma preso in esame alla locazione 00416D90 e la routine "calcolo" con la parte di programma che parte dall'indirizzo 00417260.


Un ringraziamento ad Iczelion x i suoi tutes sul win32asm e a tutti i membri di RingZero!!

Pusillus.

← previous
next →
loading
sending ...
New to Neperos ? Sign Up for free
download Neperos App from Google Play
install Neperos as PWA

Let's discover also

Recent Articles

Recent Comments

Neperos cookies
This website uses cookies to store your preferences and improve the service. Cookies authorization will allow me and / or my partners to process personal data such as browsing behaviour.

By pressing OK you agree to the Terms of Service and acknowledge the Privacy Policy

By pressing REJECT you will be able to continue to use Neperos (like read articles or write comments) but some important cookies will not be set. This may affect certain features and functions of the platform.
OK
REJECT