Solution-jockcranley-T0AD-K3YG3N
Jump to navigation
Jump to search
Description
Objective
The objective of this challenge is to crack the serial generation algorithm from the username and write your own keygen.
My keygen in action
Below is the output of mykeygen in action, with debug set to True.
$ ./keygen.py myusername [DEBUG] username=myuserna [DEBUG] 0x4014ED EAX=0x28 EDX=0x28 EBX=0x28 --- index 0 --- [DEBUG] 0x4014FF EAX=0x6d [DEBUG] 0x401503 EAX=0x45 [DEBUG] 0x401506 EAX=0x4 [DEBUG] 0x401511 EAX=0x34 --- index 1 --- [DEBUG] 0x4014FF EAX=0x79 [DEBUG] 0x401503 EAX=0x75 [DEBUG] 0x401506 EAX=0x34 [DEBUG] 0x401511 EAX=0x64 --- index 2 --- [DEBUG] 0x4014FF EAX=0x75 [DEBUG] 0x401503 EAX=0xe9 [DEBUG] 0x401506 EAX=0x28 [DEBUG] 0x401511 EAX=0x58 --- index 3 --- [DEBUG] 0x4014FF EAX=0x73 [DEBUG] 0x401503 EAX=0xb [DEBUG] 0x401506 EAX=0x8 [DEBUG] 0x401511 EAX=0x38 --- index 4 --- [DEBUG] 0x4014FF EAX=0x65 [DEBUG] 0x401503 EAX=0x7d [DEBUG] 0x401506 EAX=0x3c [DEBUG] 0x401511 EAX=0x6c --- index 5 --- [DEBUG] 0x4014FF EAX=0x72 [DEBUG] 0x401503 EAX=0xc6 [DEBUG] 0x401506 EAX=0x4 [DEBUG] 0x401511 EAX=0x34 --- index 6 --- [DEBUG] 0x4014FF EAX=0x6e [DEBUG] 0x401503 EAX=0x62 [DEBUG] 0x401506 EAX=0x20 [DEBUG] 0x401511 EAX=0x50 --- index 7 --- [DEBUG] 0x4014FF EAX=0x61 [DEBUG] 0x401503 EAX=0x1 [DEBUG] 0x401506 EAX=0x0 [DEBUG] 0x401511 EAX=0x30 Serial: 4dX8l4P0
Code Analysis
Username length
The username should be at least 7 characters long. The following routine checks each character of the username and if a NULL character is met before the loop finishes, the program jumps to the end and fails.
If the provided username is longer than 8 characters, only the first 8 characters will be taken to generate the serial. As a consequence, 'myusername' will produce the same serial as 'myuserna'.
Serial
The rest of the code is commented in my keygen code.
My keygen
#!/usr/bin/env python
import sys
def make_serial(username):
# if username is 6 characters, last character is a line feed
if len(username) < 8:
username += '\n'
username = username[:8] # Only 8 first characters of username are considered
# 00401530 cmp [esp+44h+counter1], 8
if debug:
print "[DEBUG] username=%s" % username
eax = ord(username[1]) # .text:004014C5 movzx eax, [esp+44h+user_name+1] ; 2nd letter of username
edx = eax # .text:004014CA movsx dx, al ; DX = 2nd letter of username
edx *= 0x56 # .text:004014CE imul edx, 56h ; EDX*=0x56
edx = edx >> 0x8 # .text:004014D1 shr dx, 8 ; EDX = EDX >> 0x8
eax = eax >> 0x7 # .text:004014D5 sar al, 7 ; AL = 2nd letter username >> 0x7
ebx = edx # .text:004014D8 mov ebx, edx ; EBX = EDX
ebx -= eax # .text:004014DA sub ebx, eax ; EBX = EBX - EAX
eax = ebx # .text:004014DC mov eax, ebx ; EAX = EBX
# .text:004014DE movsx eax, al
var_8 = eax # .text:004014E1 mov [esp+44h+var_8], eax ; username[1]
var_33 = 0x20202020 # .text:00401419 mov [esp+44h+var_33], 20202020h
if debug:
print "[DEBUG] 0x4014ED EAX=%s EDX=%s EBX=%s" % (hex(eax), hex(edx), hex(ebx))
serial = []
#for c, i in enumerate(username):
for c in range(8):
i = username[c]
if debug:
print "--- index %s ---" % c
edx = username # .text:004014EF lea edx, [esp+44h+user_name]
"""
# .text:004014F3 mov eax, [esp+44h+counter1] ; EAX = username letter counter
# .text:004014F7 add eax, edx
# .text:004014F9 movzx eax, byte ptr [eax] ; EAX = letter of username
# .text:004014FC movsx eax, al
"""
eax = ord(i)
if debug:
print "[DEBUG] 0x4014FF EAX=%s" % hex(eax)
eax = eax ^ var_8 # .text:004014FF xor eax, [esp+44h+var_8]
if debug:
print "[DEBUG] 0x401503 EAX=%s" % hex(eax)
eax = eax & 0x3C # .text:00401503 and eax, 3Ch
if debug:
print "[DEBUG] 0x401506 EAX=%s" % hex(eax)
var_18 = eax # .text:00401506 mov [esp+44h+var_18], eax
eax = var_18 # .text:0040150A mov eax, [esp+44h+var_18]
eax += 0x30 # .text:0040150E add eax, 30h
if debug:
print "[DEBUG] 0x401511 EAX=%s" % hex(eax)
serial.append(eax)
ecx = var_33 # .text:00401511 lea ecx, [esp+44h+var_33]
edx = c # .text:00401515 mov edx, [esp+44h+counter1]
edx += ecx # .text:00401519 add edx, ecx
edx = eax # .text:0040151B mov [edx], al
edx = var_18 # .text:0040151D mov edx, [esp+44h+var_18]
eax = edx # .text:00401521 mov eax, edx
eax += eax # .text:00401523 add eax, eax
eax += edx # .text:00401525 add eax, edx
var_8 = eax # .text:00401527 mov [esp+44h+var_8], eax
return serial
if __name__ == '__main__':
debug = True
if len(sys.argv) < 2:
print "Usage: %s <username>" % sys.argv[0]
sys.exit()
username = sys.argv[1]
# 0x401488 - 0x40147C
if len(username) < 7:
print "[ERROR] Username should be at least 7 characters"
sys.exit()
serial = make_serial(username)
print "Serial: %s" % ''.join([chr(i) for i in serial])
Comments
Keywords: assembly x86 reverse-engineering crackme jockcranley toad keygen