crackme 11 keygen crackme 11 ui :
you need input username and password.
decompile code 1 2 3 4 5 6 7 8 9 10 11 0040127D . BF 06214000 mov edi,crcme1.00402106 ; ASCII "testabc" 00401282 . 33DB xor ebx,ebx 00401284 . 33C0 xor eax,eax 00401286 > 8A1F mov bl,byte ptr ds:[edi] 00401288 . 80FB 20 cmp bl,0x20 ; 0x20 space 0040128B . 0F82 95000000 jb crcme1.00401326 00401291 . 03C3 add eax,ebx 00401293 . 47 inc edi 00401294 . 803F 00 cmp byte ptr ds:[edi],0x0 00401297 .^ 75 ED jnz short crcme1.00401286
bl is the lower part of ebx rewrite it as python code:
1 2 3 4 5 6 7 8 9 10 edi = username ebx = eax = i = 0 while i < len (edi): ebx = edi[i] if ebx < 0x20 : jump eax += ebx i += 1 if edi[i] == 0x0 : jump
continue
1 2 3 00401299 . C1C0 03 rol eax,0x3 0040129C . 35 A5150500 xor eax,0x515A5 004012A1 . 50 push eax
python
1 2 3 eax <<= 3 eax ^= 0x515A5 temp = eax
continue, asm code
1 2 3 4 004012A2 . 33C0 xor eax,eax 004012A4 . 33DB xor ebx,ebx 004012A6 . 33FF xor edi,edi 004012A8 . BE 2E214000 mov esi,crcme1.0040212E ; ASCII "123456"
python code:
1 2 eax = ebx = edi = 0 esi = password
asm
1 2 3 4 5 6 7 8 9 10 11 12 13 14 004012AD > /B8 0A000000 mov eax,0xA 004012B2 . |8A1E mov bl,byte ptr ds:[esi] 004012B4 . |85DB test ebx,ebx 004012B6 . |74 15 je short crcme1.004012CD 004012B8 . |80FB 30 cmp bl,0x30 ; check if it is 0 004012BB . |72 69 jb short crcme1.00401326 004012BD . |80FB 39 cmp bl,0x39 ; check if it is 9 004012C0 . |7F 64 jg short crcme1.00401326 004012C2 . |83EB 30 sub ebx,0x30 004012C5 . |0FAFF8 imul edi,eax 004012C8 . |03FB add edi,ebx 004012CA . |46 inc esi ; crcme1.0040212E 004012CB .^\EB E0 jmp short crcme1.004012AD
interpret as python
1 2 3 4 5 6 7 8 eax = 0xA while i < len (esi): ebx = esi[i] if ebx < 0 or ebx > 9 : jump edi = edi * 10 + ebx. i += 1
asm
1 2 3 4 5 6 7 8 004012CD > \81F7 CA870000 xor edi,0x87CA 004012D3 . 8BDF mov ebx,edi 004012D5 . 58 pop eax ; 00050295 004012D6 . 03C3 add eax,ebx 004012D8 . 35 E7970700 xor eax,0x797E7 004012DD . 85C0 test eax,eax 004012DF 75 45 jnz short crcme1.00401326
python
1 2 3 4 5 6 7 8 9 edi ^= 0x87CA ebx = edi eax = temp eax += ebx eax ^= 0x797E7 if eax == 0 : jump else : succeed
we can see, this app check both username and password , password and username must have some relationship, let’s revese engineer the relationship at line 5, and 6, final result of eax must be 0x797E7 , at line 3 we know eax has value of temp , which is calcuated by f(username) so we get
1 2 3 0x797E7 - temp = f(password) ^0x87CA => f(password) = 0x87CA ^(0x797E7 - temp)
write keygen as such:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 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 #include <stdio.h> #include <stdlib.h> #include <string.h> int main (int argc, char *argv[] ) { char username[100 ]; printf ("Enter username: " ); scanf ("%99s" , username); printf ("you entered: %s\n" , username); size_t username_len = strlen (username); if (username_len < 5 ) { printf ("username is too short" ); return 1 ; } int32_t eax = 0 ; for (size_t i = 0 ; i < username_len; i++) { int c = username[i]; if ( c < 0x20 ) { printf ("invalid characters\n" ); return 1 ; } eax += c; } eax <<= 3 ; eax ^= 0x515A5 ; int32_t password = 0x87CA ^(0x797E7 -eax); printf ("keygen code: %d\n" ,password); return 0 ; }
generate the output as such:
1 2 3 4 ~/github/algorithm-practice/crackme (master ✗) ./crack11.out Enter username: testabc you entered: testabc keygen code: 135832
test it: looks good!