Solution-LuCiFeR-First-CPP-Crackme
Jump to navigation
Jump to search
Description
Objective
The objective of this crackme (http://crackmes.de/users/lucifer/first_c_crackme/) is to crack the serial generation algorithm and develop a keygen.
My keygen in action
Here is the output of my keygen in action (with debug information set to True):
$ ./keygen.py lucifer [DEBUG] 0x40167E: edx=0x3b389b [DEBUG] 0x401685: edx=0x12f364, eax=0xccdd61c5 [DEBUG] 0x40168A: eax=0x979b [DEBUG] 0x401690: eax=0xfdf6db30 [INFO] Serial for lucifer: 1711276032-x019871
Code anlaysis
The code is relatively short. The interesting part is as below:
.text:00401668 lea eax, [ebp+var_108]
.text:0040166E mov [esp], eax ; EAX = username
.text:00401671 call _strlen ; username's length
.text:00401676 mov edx, eax ; save username's length into EDX
.text:00401678 imul edx, 875CDh ; multiply EDX by 0x875CD
.text:0040167E mov eax, 51EB851Fh ; move 0x51EB851F into EAX
.text:00401683 mul edx ; multiply EAX (0x51EB851F) by EDX (username's length)
.text:00401685 mov eax, edx ; save result into EAX
.text:00401687 shr eax, 5 ; shift right result by 5
.text:0040168A imul eax, 0FFFFFC90h ; multiply result by 0xFFFFFC90
.text:00401690 mov edx, 0
.text:00401695 push edx
.text:00401696 push eax
.text:00401697 fild qword ptr [esp] ; fetch the top of the stack (previously EAX) into a floating point value and stores it to ST(0)
.text:0040169A lea esp, [esp+8]
.text:0040169E fstp [ebp+var_410] ; save ST(0) into EBP - 0x410
.text:004016A4 fld [ebp+var_410] ; push the operand back onto the FPU register stack
.text:004016AA fstp qword ptr [esp+8] ; save ST(0) onto the base stack as ESP+8
.text:004016AE mov dword ptr [esp+4], offset aIX019871 ; "%i-x019871"
My keygen
#!/usr/bin/env python
import sys
import struct
def mul(reg, eax):
"""
Return (EDX, EAX) tuple as result of multiplication
"""
mulval = reg * eax
return (mulval >> 32, mulval & 0xFFFFFFFF)
def double_to_hex(f):
return struct.unpack('<Q', struct.pack('<d', f))[0]
def make_serial():
eax = len(myusername)
edx = eax * 0x875CD # 0x401673 imul edx, 8575CD
if debug:
print "[DEBUG] 0x40167E: edx=%s" % hex(edx)
eax = 0x51EB851F # 0x40167E mov eax, 51EB851F
edx, eax = mul(edx, eax) # 0x401683 mul edx
if debug:
print "[DEBUG] 0x401685: edx=%s, eax=%s" % (hex(edx), hex(eax))
eax = edx # 0x401685 MOV EAX,EDX
eax = eax >> 5 # 0x401687 SHR EAX,5
if debug:
print "[DEBUG] 0x40168A: eax=%s" % hex(eax)
eax = (eax * 0xFFFFFC90) & 0xFFFFFFFF # 0x40168A imul eax, 0FFFFFC90h
if debug:
print "[DEBUG] 0x401690: eax=%s" % hex(eax)
print "[INFO] Serial for %s: %s-x019871" % (myusername, str(double_to_hex(eax) & 0xFFFFFFFF))
if __name__ == '__main__':
if len(sys.argv) < 2:
print "Usage: %s <username>" % (sys.argv[0])
sys.exit()
debug = False
myusername = sys.argv[1]
make_serial()
Comments
Keywords: assembly x86 reverse-engineering crackme lucifer c++