Zoom Icon

Norpius Crackme

From UIC

Reversing Norpius Crackme v1.0 & v2.0

Contents


Norpius Crackme
Author: anonymous
Email: .
Website: .
Date: 31/12/2003 (dd/mm/yyyy)
Level: Working brain required
Language: Italian Flag Italian.gif
Comments: Commenti, se volete



Tools

Cmq ho usato IDA...


URL o FTP del programma

Allegato


Notizie sul programma

Due semplice crackme da registrare.


Essay

Iniziamo disassemblando il primo l'eseguibile. Non vi allarmate... non serve nemmeno il softice. Cerchiamo una GetDlgItemTextA nel codice... la prima che ci capita sotto le mani è quella giusta. Vediamo un po' di cosa si tratta:

push 200h
push offset username
push 6
push [ebp+hWnd]
call GetDlgItemTextA ;Ritira l'username

push 0
push 0
push 7
push [ebp+hWnd]
call GetDlgItemInt   ; Ritira il serial da noi inserito

mov ebx, eax         ; Il serial da noi inserito viene salvato in EBX
xor eax, eax
lea esi, username    ; ESI punta al nome

Fin qua niente di particolare... Procediamo per vedere che cosa viene fatto a questo nome:

_loop1:
    mov al, [esi]        ; AL = username[ESI]
    test al, al          ; Il nome è finito?
    jz short _end_loop1  ; SI: finisce il loop
    add ecx, eax         ; NO: ECX = ECX + username[ESI]
    inc esi              <; Incrementa il contatore
    jmp short _loop1     ; Passa al char successivo

_end_loop1:
    call proc1           ; Chiamata a una procedura
    cmp eax, ebx         ; Alla fine in EAX abbiamo il serial corretto.

Anche fin qua è facile. Adesso analizziamo che cosa succede dentro a "proc1":

proc1 proc near
    mov eax, ecx         ; EAX = somma dei caratteri
    add eax, 1Bh         ; EAX = EAX + 0x1B
    call proc2           ; Chiamata a Proc2
    retn                 ; Fine di tutto; EAX = serial corretto
proc1 endp

proc2 proc near
    mov ecx, 4Eh         ; ECX = 0x4E
    mul ecx              ; EAX = EAX * 0x4E;
    xor eax, 4D2h        ; EAX = EAX ^ 0x4D2
    retn                 ; Fine</comment>
proc2 endp

Benissimo... abbiamo finito. In poche parole prima viene presa la somma dei caratteri del nome... viene fatta un'addizione, una moltiplicazione e uno xoring per ottenere il seriale. Vediamo di fare lo stesso in C:

int keygen(const char *username)
{
    int c = 0;

    int l = strlen(username);
    for(int i=0; i < l; i++)
    {
        c += username[i];
    }

    ((c += 0x1B) *= 0x4E) ^= 0x4D2;
    return c;
}

Ed ecco fatto il nostro generatore di chiavi. Possiamo visualizzare il risultato della procedura con una SetDlgItemInt, e siamo appost! :-)

Adesso passiamo al secondo eseguibile. Mi limito ad inserire il codice asm commentando le differenze che ci sono tra i due:

push 200h
    push offset username
    push 6
    push [ebp+hWnd]
    call GetDlgItemTextA

    xor ebx, ebx
    push 0
    push 0
    push 7
    push [ebp+hWnd]
    call GetDlgItemInt

    mov ebx, eax
    xor eax, eax      
    xor ecx, ecx      ; Prima differenza... stavolta viene azzerato qualche registro in +
    lea esi, username

    _loop2:
        mov al, [esi]
        test al, al
        jz short _end_loop2
        add ecx, eax   ; Somma username[ESI] con ECX
        sub ecx, 30h   ; Sottrae 0x30 da ECX
        xor ecx, 11D7h ; Lo xora con 0x11D7
        add ecx, 20h   ; Gli riaggiunge 0x20
        inc esi
        jmp short _loop2

    _end_loop2:
        call proc1    ; Chiamata a proc1
        cmp eax, ebx  ; EAX contiene il serial corretto

Anche stavolta guardiamo dentro a proc1:

proc1 proc near  
    mov eax, ecx
    add eax, 1Bh
    call proc2  
    retn        
proc1 endp       ; Questa è identica a quella del primo crackme

proc2 proc near
    mov ecx, 4Eh
    mul ecx
    xor eax, 4D2h
    sub eax, 17h  ; L'unica differenza è che sottrae 0x17 al serial.
    retn
proc2 endp

Morale della favola:

int Keygen2(const char *username)
{
    int c = 0;

    int l = strlen(username);
    for(int i=0; i < l; i++)
    {
        (((c += username[i]) -= 0x30) ^= 0x11D7) += 0x20;
    }

    (((c += 0x1B) *= 0x4E) ^= 0x4D2) -= 0x17;
    return c;
}

Ci vediamo alla prossima! :D


Note Finali

Ringraziamenti


Disclaimer

I documenti qui pubblicati sono da considerarsi pubblici e liberamente distribuibili, a patto che se ne citi la fonte di provenienza. Tutti i documenti presenti su queste pagine sono stati scritti esclusivamente a scopo di ricerca, nessuna di queste analisi è stata fatta per fini commerciali, o dietro alcun tipo di compenso. I documenti pubblicati presentano delle analisi puramente teoriche della struttura di un programma, in nessun caso il software è stato realmente disassemblato o modificato; ogni corrispondenza presente tra i documenti pubblicati e le istruzioni del software oggetto dell'analisi, è da ritenersi puramente casuale. Tutti i documenti vengono inviati in forma anonima ed automaticamente pubblicati, i diritti di tali opere appartengono esclusivamente al firmatario del documento (se presente), in nessun caso il gestore di questo sito, o del server su cui risiede, può essere ritenuto responsabile dei contenuti qui presenti, oltretutto il gestore del sito non è in grado di risalire all'identità del mittente dei documenti. Tutti i documenti ed i file di questo sito non presentano alcun tipo di garanzia, pertanto ne è sconsigliata a tutti la lettura o l'esecuzione, lo staff non si assume alcuna responsabilità per quanto riguarda l'uso improprio di tali documenti e/o file, è doveroso aggiungere che ogni riferimento a fatti cose o persone è da considerarsi PURAMENTE casuale. Tutti coloro che potrebbero ritenersi moralmente offesi dai contenuti di queste pagine, sono tenuti ad uscire immediatamente da questo sito.

Vogliamo inoltre ricordare che il Reverse Engineering è uno strumento tecnologico di grande potenza ed importanza, senza di esso non sarebbe possibile creare antivirus, scoprire funzioni malevole e non dichiarate all'interno di un programma di pubblico utilizzo. Non sarebbe possibile scoprire, in assenza di un sistema sicuro per il controllo dell'integrità, se il "tal" programma è realmente quello che l'utente ha scelto di installare ed eseguire, né sarebbe possibile continuare lo sviluppo di quei programmi (o l'utilizzo di quelle periferiche) ritenuti obsoleti e non più supportati dalle fonti ufficiali.