楼主分析的不错!这个CrackME以前我也做过注册机(Python写的),有一点点和楼主分析的不一样,贴出来跟大家交流:
Cruehead.3.exe我是在看雪下的哈,但是看楼主分析应该是一样的~
00401311 /$ 33C9 xor ecx,ecx ; 关键CALL1-计算前14个字符
00401313 |. 33C0 xor eax,eax ; kernel32.BaseThreadInitThunk
00401315 |. 8B7424 04 mov esi,dword ptr ss:[esp+0x4] ; esi里面存储从文件读取的18位序列号字符串
00401319 |. B3 41 mov bl,0x41 ; 大写字母A的ASCII,存入bl
0040131B |> 8A06 /mov al,byte ptr ds:[esi] ; 循环取字符
0040131D |. 32C3 |xor al,bl ; 与'A'的ASCII做异或,下一个循环'A'++
0040131F |. 8806 |mov byte ptr ds:[esi],al ; 最终结果存回去,逆向成功后显示用户名
00401321 |. 46 |inc esi ; 取下一个字母
00401322 |. FEC3 |inc bl ; 'A'++
00401324 |. 0105 F9204000 |add dword ptr ds:[0x4020F9],eax ; 加上每一轮循环的结果,并存入ds:[0x4020F9]
0040132A |. 3C 00 |cmp al,0x0
0040132C |. 74 07 |je short Cruehead.00401335 ; al==0 则跳出,否则cl++,bl != 0x4F (大写字母O)继续循环
0040132E |. FEC1 |inc cl
00401330 |. 80FB 4F |cmp bl,0x4F ; 字母'O'
00401333 |.^ 75 E6 \jnz short Cruehead.0040131B ; 只计算前14个字符 4F-41
00401335 |> 890D 49214000 mov dword ptr ds:[0x402149],ecx
0040133B \. C3 retn
0040133C /$ 8B7424 04 mov esi,dword ptr ss:[esp+0x4] ; 关键CALL2-取后四个字符值
00401340 |. 83C6 0E add esi,0xE ; 字符串指针偏移14
00401343 |. 8B06 mov eax,dword ptr ds:[esi] ; 将后面4个字符的ASCII值小端序放入EAX
00401345 \. C3 retn
Python注册机代码(支持中文用户名):
- #!/usr/bin/env python
- #-*- coding: UTF-8 -*-
- #########################
- # Cruehead.3.keygen.py
- # By Herowuking
- import sys #使用sys模块,标准输入
- def CalcKeyFileString(name):
- arr = range(0x41,0x50)
- name14 = "{0: <14}".format(name) #用空格补全14个字符
- nameNew = "" <font color="#ff0000">#用来存储加密后的用户名</font>
- #print "{0}:{1}".format(name14,len(name14))
- nameXOR = 0 #用来存储用户名异或运算结果
- i=0
- for c in name14:
- nameNew += chr(ord(c)^arr[i])
- nameXOR += ord(c) #nameNew中的字符与arr[i]异或运算之后,得到的是加密之前用户名对应的字符,因此直接加ASCII即可
- i += 1 # name14[i] = nameNew[i]^arr[i] = (name14[i]^arr[i])^arr[i]
- nameXOR ^= 0x12345678
- namekey = nameNew
- HEXkey = "{0:x}".format(nameXOR)
- #print HEXkey
- for i in range(8,0,-2):
- #print HEXkey[i-2:i]
- asc = int(HEXkey[i-2:i],16) #16进制字符串转整数
- namekey += chr(asc)
- return namekey
-
- nameStr = raw_input(u"请输入用户名,不要超过14个字符或7个中文:\n".encode("GBK"))
- nameLen = len(nameStr)
- while nameLen<=0 or nameLen>14:
- nameStr = raw_input(u"输入无效,请重新输入用户名,不要超过14个字符或7个中文:\n".encode("GBK"))
- keyStr = CalcKeyFileString(nameStr)
- KEYFILE = open('CRACKME3.KEY','w+')
- KEYFILE.write(keyStr)
- KEYFILE.flush()
- KEYFILE.seek(0)
- print "The KEYFILE string is:%s" % KEYFILE.readline()
- print u"授权文件CRACKME3.KEY创建成功!".encode("GBK")
- KEYFILE.close()
复制代码
|