Software Cracking (Example 1)

0. Building
The following crackme sourcecode got build with the C compiler from MinGW as PE x86.

#include <stdio.h>
#include <string.h>

int main()
{
    char strLicense[] = "l_i_c_e_n_s_e";
    int intLenLicense = sizeof(strLicense)/sizeof(strLicense[0]);

    char strInput[intLenLicense];
    fputs("Enter the license:", stdout);
    fgets(strInput, intLenLicense, stdin);

    if(strncmp(strInput, strLicense, intLenLicense) != 0) {
        fputs("Trial version", stdout);
        return 1;
    }
    else
        fputs("Full version", stdout);

    return 0;
}

 

1. Reverse Engineering
For the reverse engineering of the build program is OllyDbg used. The interesting section is shown in the following assembler code.

0040166E  MOV DWORD PTR SS:[ESP],a.00404044      ; ||||ASCII "License:"
00401675  CALL <JMP.&msvcrt.fwrite>              ; |||\fwrite
0040167A  MOV EAX,DWORD PTR DS:[<&msvcrt._iob>]  ; |||
0040167F  MOV EDX,EAX                            ; |||
00401681  MOV EAX,DWORD PTR SS:[EBP-14]          ; |||
00401684  MOV DWORD PTR SS:[ESP+8],EDX           ; |||
00401688  MOV EDX,DWORD PTR SS:[EBP-C]           ; |||
0040168B  MOV DWORD PTR SS:[ESP+4],EDX           ; |||
0040168F  MOV DWORD PTR SS:[ESP],EAX             ; |||
00401692  CALL <JMP.&msvcrt.fgets>               ; ||\fgets
00401697  MOV EDX,DWORD PTR SS:[EBP-C]           ; ||
0040169A  MOV EAX,DWORD PTR SS:[EBP-14]          ; ||
0040169D  MOV DWORD PTR SS:[ESP+8],EDX           ; ||
004016A1  LEA EDX,DWORD PTR SS:[EBP-22]          ; ||
004016A4  MOV DWORD PTR SS:[ESP+4],EDX           ; ||
004016A8  MOV DWORD PTR SS:[ESP],EAX             ; ||
004016AB  CALL <JMP.&msvcrt.strncmp>             ; |\strncmp
004016B0  TEST EAX,EAX                           ; |
004016B2  JE SHORT a.004016E3                    ; |
004016B4  MOV EAX,DWORD PTR DS:[<&msvcrt._iob>]  ; |
004016B9  ADD EAX,20                             ; |
004016BC  MOV DWORD PTR SS:[ESP+C],EAX           ; |
004016C0  MOV DWORD PTR SS:[ESP+8],0D            ; |
004016C8  MOV DWORD PTR SS:[ESP+4],1             ; |
004016D0  MOV DWORD PTR SS:[ESP],a.0040404D      ; |ASCII "Trial version"
004016D7  CALL <JMP.&msvcrt.fwrite>              ; \fwrite
004016DC  MOV EAX,1
004016E1  JMP SHORT a.00401710
004016E3  MOV EAX,DWORD PTR DS:[<&msvcrt._iob>]  ; |
004016E8  ADD EAX,20                             ; |
004016EB  MOV DWORD PTR SS:[ESP+C],EAX           ; |
004016EF  MOV DWORD PTR SS:[ESP+8],0C            ; |
004016F7  MOV DWORD PTR SS:[ESP+4],1             ; |
004016FF  MOV DWORD PTR SS:[ESP],a.0040405B      ; |ASCII "Full version"
00401706  CALL <JMP.&msvcrt.fwrite>              ; \fwrite

 

2. Solution
Patch
The easiest solution is to patch the program. The conditional jump for that is at 004016B2 below the important string comparison. Replace this conditional jump with an unconditional jump, cause a jump there leads to the “Full version”.

Serial
Another solution is to find out the requested license key. Set a breakpoint, above the important string comparison, at 004016A8 and start the debugger. The ASCII value in EDX is the license key and the ASCII value in EAX is the entered string.