Target: rezk2ll’s KeygenmeNasm
URL: http://www.crackmes.de/users/rezk2ll/keygenmenasm/
Protection: Serial.
Description: Crackme with a serial protection.
Tools: objdump / x86 assembly knowledge.
First disassemble the keygenme and take a look at what it does.
objdump -d -M intel keygenme
keygenme: file format elf32-i386 Disassembly of section .text: 08048080 <_start>: ; print out headers 8048080: b8 04 00 00 00 mov eax,0x4 8048085: bb 01 00 00 00 mov ebx,0x1 804808a: b9 d0 91 04 08 mov ecx,0x80491d0 804808f: ba 2f 00 00 00 mov edx,0x2f 8048094: cd 80 int 0x80 8048096: b8 04 00 00 00 mov eax,0x4 804809b: bb 01 00 00 00 mov ebx,0x1 80480a0: b9 ff 91 04 08 mov ecx,0x80491ff 80480a5: ba 0c 00 00 00 mov edx,0xc 80480aa: cd 80 int 0x80 ; read name 80480ac: b8 03 00 00 00 mov eax,0x3 ; sys_read 80480b1: bb 00 00 00 00 mov ebx,0x0 ; stdin 80480b6: b9 84 92 04 08 mov ecx,0x8049284 ; variable to use 80480bb: ba 0f 00 00 00 mov edx,0xf ; length 0xf 80480c0: cd 80 int 0x80 ; syscall 80480c2: 83 f8 03 cmp eax,0x3 ; if len(name) <= 3 80480c5: 0f 8e df 00 00 00 jle 80481aa ; jump to invalid name message 80480cb: 50 push eax ; push len(name) on to the stack 80480cc: 83 f8 0e cmp eax,0xe ; if len(name) > 0xe 80480cf: 0f 8f d5 00 00 00 jg 80481aa ; jump to invalid name message ; print out serial input request 80480d5: b8 04 00 00 00 mov eax,0x4 80480da: bb 01 00 00 00 mov ebx,0x1 80480df: b9 0b 92 04 08 mov ecx,0x804920b 80480e4: ba 0c 00 00 00 mov edx,0xc 80480e9: cd 80 int 0x80 ; read serial 80480eb: b8 03 00 00 00 mov eax,0x3 ; sys_read 80480f0: bb 00 00 00 00 mov ebx,0x0 ; stdin 80480f5: b9 93 92 04 08 mov ecx,0x8049293 ; variable to use 80480fa: ba 0f 00 00 00 mov edx,0xf ; length 0xf 80480ff: cd 80 int 0x80 ; syscall 8048101: 5b pop ebx ; ebx = len(name) 8048102: 39 d8 cmp eax,ebx ; if len(name) != len(serial) 8048104: 89 c7 mov edi,eax 8048106: 75 5c jne 8048164 ; jump to invalid serial message 8048108: 50 push eax ; push len(serial) to the stack 8048109: 31 c0 xor eax,eax 804810b: 31 db xor ebx,ebx 804810d: 31 c9 xor ecx,ecx 804810f: 31 d2 xor edx,edx 8048111: 5a pop edx ; edx = len(serial) 8048112: 4a dec edx ; len(serial)-- 8048113: be 84 92 04 08 mov esi,0x8049284 ; move our entered name to esi 8048118: b0 05 mov al,0x5 ; init value for the OR operation 0804811a : 804811a: 8a 1c 0e mov bl,BYTE PTR [esi+ecx1] ; bl = name[i] 804811d: 88 df mov bh,bl ; bh = name[i] 804811f: 08 c3 or bl,al ; bl = name[i] OR value 8048121: 88 f8 mov al,bh ; value = name[i] 8048123: 88 1c 0e mov BYTE PTR [esi+ecx1],bl ; name[i] = bl 8048126: 41 inc ecx ; i++ 8048127: 39 d1 cmp ecx,edx ; if i < len(serial) 8048129: 7c ef jl 804811a ; loop 804812b: 31 db xor ebx,ebx 804812d: bb 93 92 04 08 mov ebx,0x8049293 ; ebx = our entered serial 8048132: 31 c0 xor eax,eax 08048134 : 8048134: 8a 04 0e mov al,BYTE PTR [esi+ecx1] ; al = name[i] 8048137: 8a 24 0b mov ah,BYTE PTR [ebx+ecx1] ; ah = serial[i] 804813a: 38 c4 cmp ah,al ; if name[i] != serial[i] 804813c: 75 26 jne 8048164 ; jump to fail 804813e: 49 dec ecx ; i-- 804813f: 83 f9 00 cmp ecx,0x0 ; if i >= 0 8048142: 7d f0 jge 8048134 ; loop 8048144: eb 45 jmp 804818b ; if all characters match, jump to success message 08048146 : 8048146: ba 01 00 00 00 mov edx,0x1 804814b: b9 a2 92 04 08 mov ecx,0x80492a2 8048150: bb 00 00 00 00 mov ebx,0x0 8048155: b8 03 00 00 00 mov eax,0x3 804815a: cd 80 int 0x80 804815c: 80 7c 11 ff 0a cmp BYTE PTR [ecx+edx*1-0x1],0xa 8048161: 75 e3 jne 8048146 8048163: c3 ret ; wrong serial message 08048164 : 8048164: 83 ff 0f cmp edi,0xf 8048167: b8 04 00 00 00 mov eax,0x4 804816c: bb 01 00 00 00 mov ebx,0x1 8048171: b9 3f 92 04 08 mov ecx,0x804923f 8048176: ba 14 00 00 00 mov edx,0x14 804817b: cd 80 int 0x80 804817d: e8 c4 ff ff ff call 8048146 8048182: b8 01 00 00 00 mov eax,0x1 8048187: 31 db xor ebx,ebx 8048189: cd 80 int 0x80 ; correct serial message 0804818b : 804818b: b8 04 00 00 00 mov eax,0x4 8048190: bb 01 00 00 00 mov ebx,0x1 8048195: b9 17 92 04 08 mov ecx,0x8049217 804819a: ba 28 00 00 00 mov edx,0x28 804819f: cd 80 int 0x80 80481a1: b8 01 00 00 00 mov eax,0x1 80481a6: 31 db xor ebx,ebx 80481a8: cd 80 int 0x80 ; invalid name message 080481aa : 80481aa: b8 04 00 00 00 mov eax,0x4 80481af: bb 01 00 00 00 mov ebx,0x1 80481b4: b9 53 92 04 08 mov ecx,0x8049253 80481b9: ba 2e 00 00 00 mov edx,0x2e 80481be: cd 80 int 0x80 80481c0: e8 81 ff ff ff call 8048146 80481c5: b8 01 00 00 00 mov eax,0x1 80481ca: 31 db xor ebx,ebx 80481cc: cd 80 int 0x80
So a basic OR operation is made on each character of the name to generate the serial. The first value is 0x05 and the subsequent values are the previous character value of the name. So lets write a keygen.
# keygen.py by Klefz
print("rezk2ll's KeygenmeNasm keygen by Klefz")
name = input("Name: ")
serial = ""
value = 0x5
if len(name) < 3 or len(name) > 13:
print("Name has to be 3-13 characters.")
raise SystemExit
for c in name:
charValue = value | ord(c)
value = ord(c)
serial += chr(charValue)
print("Serial: " + serial)