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)