学无止境

-------至弱即为至强!

导航

用keymake写算法注册机教程

Posted on 2005-11-16 14:00  赵国亮  阅读(3906)  评论(1编辑  收藏  举报

用keymake写算法注册机教程1

===============引用开始====================================================
象棋桥2.1--------简单注册算法分析
软件介绍:
象棋桥是一个功能强大的中国象棋打谱软件,支持局域网的联机对弈,
可以进行人机的模拟对弈,已有的韬略元机、适情雅趣、桔中密、梅花谱、
崇本堂梅花秘谱等精彩棋谱定会让您爱不释手。
下载地址: 天空下载

过程:
虽然网上已经有了注册机,但品尝自己的劳动成果,应该是最甜的。:)
我比较喜欢静动两用,如能找到关键信息,设好断点,会省很多事。
程序由fi未侦测出是何编译软件写的,用language2000侦测出用的是
Object Pascal语言,晕倒…用W32Dasm反汇编-串式参考,找到相关信息
CCB2000R-SHARE、CCB2000-12345、CCB21R-,看来前两个是上了榜的,
先用CCB2000R-54321一试,告知是2000版的注册码,可以向作者换取
再用CCB21R-54321试,注册码错误,差不多就是这个格式了,开始跟踪。
步骤和方法略。(其实大家都知道,再写就罗嗦了。)
具体请参看下面:

Possible StringData Ref from Code Obj->"CCB21R"
:0051E3EB BA70E65100 mov edx, 0051E670
:0051E3F0 E8EB5BEEFF call 00403FE0-----<<比较有无"CCB21R"
:0051E3F5 751E jne 0051E415
:0051E3F7 8D55E4 lea edx, dword ptr [ebp-1C]
:0051E3FA 8B45FC mov eax, dword ptr [ebp-04]
:0051E3FD 8B8070090000 mov eax, dword ptr [eax+00000970]
:0051E403 E85462F6FF call 0048465C-----<<计算注册码的地方
:0051E408 8B55E4 mov edx, dword ptr [ebp-1C]
:0051E40B 8B45F0 mov eax, dword ptr [ebp-10]
:0051E40E E8CD5BEEFF call 00403FE0-----<<只是注册码比较的call
:0051E413 7406 je 0051E41B-------<<跳转,下面的比较,写入
注册信息等代码省略。
///////////////////////////call 0048465C///////////////////////////////////////
:0048465C 55 push ebp
:0048465D 8BEC mov ebp, esp
:0048465F 83C4F0 add esp, FFFFFFF0
:00484662 53 push ebx
:00484663 56 push esi
:00484664 57 push edi
:00484665 33C9 xor ecx, ecx
:00484667 894DF4 mov dword ptr [ebp-0C], ecx
:0048466A 8955F8 mov dword ptr [ebp-08], edx
:0048466D 8945FC mov dword ptr [ebp-04], eax
:00484670 8B45FC mov eax, dword ptr [ebp-04]
:00484673 E80CFAF7FF call 00404084
:00484678 33C0 xor eax, eax
:0048467A 55 push ebp
:0048467B 6848474800 push 00484748
:00484680 64FF30 push dword ptr fs:[eax]
:00484683 648920 mov dword ptr fs:[eax], esp
:00484686 8D45F4 lea eax, dword ptr [ebp-0C]
:00484689 8B55FC mov edx, dword ptr [ebp-04]
:0048468C E857F6F7FF call 00403CE8
:00484691 8B45F4 mov eax, dword ptr [ebp-0C]
:00484694 E837F8F7FF call 00403ED0----<<注册名的长度
:00484699 40 inc eax----------<:0048469A 8BD8 mov ebx, eax-----<:0048469C 83FB05 cmp ebx, 00000005--<<比较是否大于5位
:0048469F 7F13 jg 004846B4--------<<大于跳
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
:004846B2(C)
:004846A1 8D45F4 lea eax, dword ptr [ebp-0C]
:004846A4 BA60474800 mov edx, 00484760
:004846A9 E82AF8F7FF call 00403ED8---<<不足位数用空格补位
:004846AE 43 inc ebx----------<:004846AF 83FB06 cmp ebx, 00000006--<<补到6位?
:004846B2 75ED jne 004846A1-------<<相等不跳

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0048469F(C)
:004846B4 8B45F4 mov eax, dword ptr [ebp-0C]--<:004846B7 33C9 xor ecx, ecx
:004846B9 8A08 mov cl, byte ptr [eax]---<<将注册名的第1位传送给cl
:004846BB 8B45F4 mov eax, dword ptr [ebp-0C]
:004846BE 33DB xor ebx, ebx
:004846C0 8A5801 mov bl, byte ptr [eax+01]--<<将注册名的第2位传送给cl
:004846C3 8B45F4 mov eax, dword ptr [ebp-0C]
:004846C6 0FB67002 movzx esi, byte ptr [eax+02]--<<将注册名的第3位传送给esi
:004846CA 8B45F4 mov eax, dword ptr [ebp-0C]
:004846CD 0FB67803 movzx edi, byte ptr [eax+03]---<<将注册名的第4位传送给edi
:004846D1 8B45F4 mov eax, dword ptr [ebp-0C]
:004846D4 0FB64004 movzx eax, byte ptr [eax+04]---<<将注册名的第5位传送给eax
:004846D8 8945F0 mov dword ptr [ebp-10], eax----<:004846DB 8D040B lea eax, dword ptr [ebx+ecx]---<:004846DE 03FE add edi, esi----------------<:004846E0 F7EF imul edi--------------------<<乘以edi
:004846E2 F76DF0 imul [ebp-10]---------------<<乘以ebp-10
:004846E5 B9A0860100 mov ecx, 000186A0-----------<:004846EA 99 cdq
:004846EB F7F9 idiv ecx
:004846ED 8BDA mov ebx, edx----------------<<将余数送到edx
:004846EF 8D55F4 lea edx, dword ptr [ebp-0C]
:004846F2 8BC3 mov eax, ebx
:004846F4 E8B745F8FF call 00408CB0
:004846F9 8B45F4 mov eax, dword ptr [ebp-0C]
:004846FC E8CFF7F7FF call 00403ED0
:00484701 40 inc eax
:00484702 8BD8 mov ebx, eax
:00484704 83FB05 cmp ebx, 00000005-----------<<比较转换十进制后位数
:00484707 7F16 jg 0048471F----------------<<大于5时跳

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0048471D(C)
|
:00484709 8D45F4 lea eax, dword ptr [ebp-0C]
:0048470C 8B4DF4 mov ecx, dword ptr [ebp-0C]
:0048470F BA6C474800 mov edx, 0048476C
:00484714 E803F8F7FF call 00403F1C------<<
:00484719 43 inc ebx------------<<不足时,从左位补0
:0048471A 83FB06 cmp ebx, 00000006
:0048471D 75EA jne 00484709

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00484707(C)
|
:0048471F 8B45F8 mov eax, dword ptr [ebp-08]
:00484722 8B55F4 mov edx, dword ptr [ebp-0C]
:00484725 E87AF5F7FF call 00403CA4
:0048472A 33C0 xor eax, eax
:0048472C 5A pop edx
:0048472D 59 pop ecx
:0048472E 59 pop ecx
:0048472F 648910 mov dword ptr fs:[eax], edx
:00484732 684F474800 push 0048474F
////////////////////////////////////////////////////////////////////////////////
注册信息保存在:
HKEY_CURRENT_USER\Software\ShengYu\CCBridge
"CCBPath"="C:\\PROGRAM FILES\\CCBRIDGE\\"
"GBCode"=dword:00000001
"RT"=dword:0000015a
"ShowTip"=dword:00000000
"TipNum"=dword:00000001
"RegistryName"="nobody"
"Reg21OK"=dword:00000001
请将下面源程序保存为.rek文件,用注册机编写器编译,注册机编写器2.0预览版测试通过!
注:因为本人水平有限,所以只写出了注册名大于5位的计算过程。不过你可以自己去编一个。
.data
szHomePage db "http://www.365hz.net";,0
szEmail db "mailto:ljyljx@163.com",0
szErrMess db "没有输入注册名!",0
szErr db "注册名不能小于5位!",0
szXor db "%lu",0
data1 dd 10 dup (0)
hChar db "CCB21R-",0
hKey db 20 dup(0)
hShow db 20 dup(0)
.code
invoke lstrlen,eax
cmp eax,5
jb ERR
lea eax,hInput1
xor ecx,ecx
mov cl,byte ptr [eax]
lea eax,hInput1
xor ebx,ebx
mov bl, byte ptr [eax+01]
movzx esi, byte ptr [eax+02]
movzx edi, byte ptr [eax+03]
movzx eax, byte ptr [eax+04]
mov dword ptr [data1], eax
lea eax, dword ptr [ebx+ecx]
add edi, esi
imul edi
imul [data1]
mov ecx, 000186A0h
idiv ecx
mov ebx, edx
push ebx
invoke wsprintf,addr hKey,addr szXor,ebx ;转换为十进制
lea edi,hShow
lea esi,hChar
mov ecx,7
rep movsb ; 移动"CCB21R-"到将显示的注册码位置
lea esi,hKey
n1:
lodsb
cmp al,0
jz n2
stosb
jmp n1
n2: ;将刚才转换为十进制后的计算结果附加在后面
lea eax,hShow ; 让EAX指向注册码
jmp nobody
ERR:
lea eax,szErr
nobody: ;祝我们可爱的iPB蒸蒸日上!

nobody/iPB
--------------------引用结束---------------------------

作者写keymake注册机时,各堆栈的参数基本根据反汇编代码,
传递的很漂亮,值得好好研习.但是最后一部分写的很不好,原因是
不熟悉32位汇编..
hChar db "CCB21R-",0 此定义多余,没必要
改后如下:

.data
szHomePage db "http://www.365hz.net";,0
szEmail db "mailto:ljyljx@163.com",0
szErrMess db "没有输入注册名!",0
szErr db "注册名不能小于5位!",0
szXor db "CCB21R-%lu",0
hKey db 20 dup(0)
.code
invoke lstrlen,eax
cmp eax,5
jb ERR
lea eax,hInput1
xor ecx,ecx
mov cl,byte ptr [eax]
lea eax,hInput1
xor ebx,ebx
mov bl, byte ptr [eax+01]
movzx esi, byte ptr [eax+02]
movzx edi, byte ptr [eax+03]
movzx eax, byte ptr [eax+04]
mov dword ptr [data1], eax
lea eax, dword ptr [ebx+ecx]
add edi, esi
imul edi
imul [data1]
mov ecx, 000186A0h
idiv ecx
mov ebx, edx
push ebx
invoke wsprintf,addr hKey,addr szXor,ebx ;转换为十进制
lea eax,szXor
ERR:
lea eax,szErr

用keymake制作算法注册机教程2
   护花使者2.1.1注册号生成算法分析
作者:毕强
  跟进计算注册号的程序段:

:004552C0 55        push ebp
:004552C1 8BEC       mov ebp, esp
:004552C3 81C4F4FDFFFF   add esp, FFFFFDF4
:004552C9 53        push ebx

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00455255(C)
|
:004552CA 56        push esi
:004552CB 57        push edi
:004552CC 8BF8       mov edi, eax
:004552CE C745FCD2040000  mov [ebp-04], 000004D2
:004552D5 68FF000000    push 000000FF
:004552DA 8D85F4FDFFFF   lea eax, dword ptr [ebp+FFFFFDF4]
:004552E0 50        push eax
:004552E1 8D45F4      lea eax, dword ptr [ebp-0C]
:004552E4 50        push eax
:004552E5 8D45F8      lea eax, dword ptr [ebp-08]
:004552E8 50        push eax
:004552E9 8D45FC      lea eax, dword ptr [ebp-04]
:004552EC 50        push eax
:004552ED 68FF000000    push 000000FF
:004552F2 8D85F4FEFFFF   lea eax, dword ptr [ebp+FFFFFEF4]
:004552F8 50        push eax

* Possible StringData Ref from Code Obj ->"c:\"
|
:004552F9 684C534500    push 0045534C

* Reference To: kernel32.GetVolumeInformationA, Ord:0000h
|
:004552FE E8F917FBFF    Call 00406AFC ****C盘的卷标序列号即为软件的序列号
:00455303 8B45FC      mov eax, dword ptr [ebp-04] ****EAX得序列号的十六制数
:00455306 05E1100000    add eax, 000010E1 ****设序列号为a,EAX为a+10E1
:0045530B 6BC00D      imul eax, 0000000D ****EAX乘以0D
:0045530E B907000000    mov ecx, 00000007
:00455313 33D2       xor edx, edx
:00455315 F7F1       div ecx ****再除以7
:00455317 8BD8       mov ebx, eax ****EBX保存商
:00455319 8B45FC      mov eax, dword ptr [ebp-04]
:0045531C 2DD2040000    sub eax, 000004D2 ****EAX为a-4D2
:00455321 8BD0       mov edx, eax
:00455323 C1E003      shl eax, 03
:00455326 2BC2       sub eax, edx ****乘以7
:00455328 B90D000000    mov ecx, 0000000D
:0045532D 33D2       xor edx, edx
:0045532F F7F1       div ecx ****再除以0D
:00455331 8BF0       mov esi, eax ****ESI为商
:00455333 8BCF       mov ecx, edi ****ECX为保存注册号地址的地址
:00455335 8D141E      lea edx, dword ptr [esi+ebx] ****EDX为两商之和

* Possible StringData Ref from Code Obj ->"hazz"
|
:00455338 B858534500    mov eax, 00455358 ****"hazz"地址
:0045533D E89E060000    call 004559E0 ****继续计算注册号并将地址放入ECX指向地址
:00455342 5F        pop edi
:00455343 5E        pop esi
:00455344 5B        pop ebx
:00455345 8BE5       mov esp, ebp
:00455347 5D        pop ebp
:00455348 C3        ret

  继续跟进4559E0分析,代码如下:

:004559E0 55        push ebp ****EAX为"hazz"地址
:004559E1 8BEC       mov ebp, esp ****ECX注册号地址的存放地址
:004559E3 83C4C8      add esp, FFFFFFC8 ****EDX为根据序列号算出的东西,记为b
:004559E6 53        push ebx
:004559E7 33DB       xor ebx, ebx ****EBX置0
:004559E9 895DC8      mov dword ptr [ebp-38], ebx
:004559EC 895DEC      mov dword ptr [ebp-14], ebx
:004559EF 894DF4      mov dword ptr [ebp-0C], ecx
:004559F2 8955F8      mov dword ptr [ebp-08], edx
:004559F5 8945FC      mov dword ptr [ebp-04], eax
:004559F8 8B45FC      mov eax, dword ptr [ebp-04]
:004559FB E800E6FAFF    call 00404000
:00455A00 33C0       xor eax, eax
:00455A02 55        push ebp
:00455A03 68F95A4500    push 00455AF9
:00455A08 64FF30      push dword ptr fs:[eax]
:00455A0B 648920      mov dword ptr fs:[eax], esp
:00455A0E 33C0       xor eax, eax
:00455A10 8945F0      mov dword ptr [ebp-10], eax
:00455A13 33DB       xor ebx, ebx
:00455A15 8B45FC      mov eax, dword ptr [ebp-04] ****EAX为"hazz"地址
:00455A18 E82FE4FAFF    call 00403E4C ****求出其长度放入EAX中
:00455A1D 85C0       test eax, eax
:00455A1F 7E13       jle 00455A34
:00455A21 BA01000000    mov edx, 00000001

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00455A32(C)
|
:00455A26 8B4DFC      mov ecx, dword ptr [ebp-04] ****以下几句将"hazz"ASCII码相加
:00455A29 0FB64C11FF    movzx ecx, byte ptr [ecx+edx-01] ****并将和1BD置入EBX
:00455A2E 03D9       add ebx, ecx
:00455A30 42        inc edx
:00455A31 48        dec eax
:00455A32 75F2       jne 00455A26

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00455A1F(C)
|
:00455A34 035DF8      add ebx, dword ptr [ebp-08] ****EBX为b+1BD
:00455A37 6BC30D      imul eax, ebx, 0000000D ****EAX为EBX*0D
:00455A3A 8945F8      mov dword ptr [ebp-08], eax ****重新保存新数据
:00455A3D 8D45EC      lea eax, dword ptr [ebp-14]

* Possible StringData Ref from Code Obj ->"delphi"
|
:00455A40 BA105B4500    mov edx, 00455B10 ****EDX为"delphi"地址
:00455A45 E81AE2FAFF    call 00403C64 ****交换EBP-14内容和EDX的值
:00455A4A 33D2       xor edx, edx
:00455A4C 8D45CC      lea eax, dword ptr [ebp-34] ****EAX=EBP-34

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00455A5F(C) ****下面一段将"delphi"每字符扩展为DWORD存于EBP-34开始的地址中
|
:00455A4F 8B4DEC      mov ecx, dword ptr [ebp-14]
:00455A52 0FB60C11     movzx ecx, byte ptr [ecx+edx]
:00455A56 8908       mov dword ptr [eax], ecx
:00455A58 42        inc edx
:00455A59 83C004      add eax, 00000004
:00455A5C 83FA06      cmp edx, 00000006
:00455A5F 75EE       jne 00455A4F
:00455A61 C745E808000000  mov [ebp-18], 00000008 ****循环次数8

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00455AAB(C) ****开始计算,此段估计为某一算法,但我搞不懂
|
:00455A68 8B45DC      mov eax, dword ptr [ebp-24]
:00455A6B 2B45E0      sub eax, dword ptr [ebp-20]
:00455A6E 99        cdq
:00455A6F 33C2       xor eax, edx
:00455A71 2BC2       sub eax, edx
:00455A73 8B4DCC      mov ecx, dword ptr [ebp-34]
:00455A76 034DD0      add ecx, dword ptr [ebp-30]
:00455A79 8B55D4      mov edx, dword ptr [ebp-2C]
:00455A7C 3355D8      xor edx, dword ptr [ebp-28]
:00455A7F 03CA       add ecx, edx
:00455A81 2BC8       sub ecx, eax
:00455A83 894DE4      mov dword ptr [ebp-1C], ecx
:00455A86 8B45F8      mov eax, dword ptr [ebp-08]
:00455A89 33C1       xor eax, ecx
:00455A8B 0145F0      add dword ptr [ebp-10], eax
:00455A8E 0FAF4DF0     imul ecx, dword ptr [ebp-10]
:00455A92 894DE4      mov dword ptr [ebp-1C], ecx
:00455A95 BA06000000    mov edx, 00000006
:00455A9A 8D45D0      lea eax, dword ptr [ebp-30]

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00455AA6(C) ****此段将从EBP-30开始的6个DWORD数据向前移一个位置
| ****即将EBP-30至EBP-1C移至EBP-34至EBP-20,用于下次循环运算
:00455A9D 8B08       mov ecx, dword ptr [eax]
:00455A9F 8948FC      mov dword ptr [eax-04], ecx
:00455AA2 83C004      add eax, 00000004
:00455AA5 4A        dec edx
:00455AA6 75F5       jne 00455A9D
:00455AA8 FF4DE8      dec [ebp-18]
:00455AAB 75BB       jne 00455A68 ****整个循环完毕后,EBP-10中即为注册号的十六进制
:00455AAD 8B45F4      mov eax, dword ptr [ebp-0C] ****要保存注册号地址的地址
:00455AB0 50        push eax
:00455AB1 8D4DC8      lea ecx, dword ptr [ebp-38]
:00455AB4 BA08000000    mov edx, 00000008
:00455AB9 8B45F0      mov eax, dword ptr [ebp-10] ****EAX为注册号十六进制
:00455ABC E8972EFBFF    call 00408958 ****将十六进制数转换为字符串置入EBP-38开始地址
:00455AC1 8B45C8      mov eax, dword ptr [ebp-38]
:00455AC4 B908000000    mov ecx, 00000008
:00455AC9 BA01000000    mov edx, 00000001
:00455ACE E881E5FAFF    call 00404054 ****将注册号地址置入刚压栈的EAX地址中
:00455AD3 33C0       xor eax, eax
:00455AD5 5A        pop edx
:00455AD6 59        pop ecx
:00455AD7 59        pop ecx
:00455AD8 648910      mov dword ptr fs:[eax], edx
:00455ADB 68005B4500    push 00455B00

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00455AFE(U)
|
:00455AE0 8D45C8      lea eax, dword ptr [ebp-38]
:00455AE3 E8E4E0FAFF    call 00403BCC
:00455AE8 8D45EC      lea eax, dword ptr [ebp-14]
:00455AEB E8DCE0FAFF    call 00403BCC
:00455AF0 8D45FC      lea eax, dword ptr [ebp-04]
:00455AF3 E8D4E0FAFF    call 00403BCC
:00455AF8 C3        ret

  由上面代码分析可知,软件的序列号为C盘的卷标序列号,记为a,将(((a+10E1)*0D\7+(a-4d2)*7\0D)+1BD)*0D用于循环时初始运算,具体算法就不管它了。

  根据前面分析,可以写注册机了。因为运算时值很可能超过DWORD,用VB编写难以正确处理,所以改用keymake注册机编写器制作注册机,此处要用MASM32汇编语言编写。具体代码如下:

  数据部分(按F2输入):
szHomePage db "http://www.biqiang.com";,0
szEmail db "mailto:biqiang@kzinfo.net",0
szErrMess db "输入的序列号不正确!",0
a1 dd 0
a2 dd 0
a3 dd 0
a4 db 10 dup(0) ;用于存放注册号
a5 db "%1X",0 ;用于输出时设置格式,即将十六进制数转换为字符串
a6 dd 64h,65h,6ch,70h,68h,69h,0 ;"delphi"扩展为DWORD后的数据

  代码部分(窗口中输入):
MOV ECX,EAX ;EAX为输入序列号地址
XOR EBX,EBX ;下面将序列号换为十六进制数存于EBX中
n1:
MOVZX EAX,BYTE PTR [ECX]
OR AL,AL
JZ n3
CMP AL,3Ah
JC n2
and al,0dfh
SUB AL,7
n2:
SUB AL,30h
SHL EBX,4
ADD EBX,EAX
INC ECX
JMP n1
n3:
xor eax,eax ;以下模拟前面程序中的算法
mov a1,eax
mov a2,eax
mov a3,eax
mov eax,ebx
push eax
add eax,10e1h
imul eax,0dh
xor edx,edx
mov ecx,7
div ecx
mov ebx,eax
pop eax
sub eax,4d2h
mov edx,eax
shl eax,3
sub eax,edx
xor edx,edx
mov ecx,0dh
div ecx
add eax,ebx
add eax,1bdh
mov ebx,eax
imul eax,ebx,0dh
mov a1,eax
mov a2,8
mov edx,6
mov a6,64h
mov a6+4,65h
mov a6+8,6ch
mov a6+0ch,70h
mov a6+10h,68h
mov a6+14h,69h
mov a6+18h,0
loop1:
mov eax,a6+10h
sub eax,a6+14h
cdq
xor eax,edx
sub eax,edx
mov ecx,a6
add ecx,a6+4
mov edx,a6+8
xor edx,a6+0ch
add ecx,edx
sub ecx,eax
mov a6+18h,ecx
mov eax,a1
xor eax,ecx
add a3,eax
imul ecx,a3
mov a6+18h,ecx
mov edx,6
lea eax,a6
loop2:
mov ecx,dword ptr [eax+4]
mov dword ptr[eax],ecx
add eax,4
dec edx
jne loop2
dec a2
jne loop1
mov eax,a3
push eax
lea eax,a5
push eax
lea eax,a4
push eax
CALL wsprintfA
lea eax,a4

  最后编译即可。另外要说明的是:在安装keymake时不要使用默认目录(C:\Program Files\KeyMake),即在安装目录名选择时不能有空格,这是因为编译时,MASM32编译程序检查include文件时,如果目录名有空格,将导致找不到包含文件,就无法完成编译了。


用keymake制作算法注册机教程3

===========================
Talisman 2.3 注册算法分析
Crack by simonyan
程序地址: http://www.skycn.com/download.php?id=3877&url=http://js.skycn.net/down/talisman.zip
一: DEDE反编译可找到下面

0047B5E8   E82787F8FF             call    00403D14
0047B5ED   85C0                   test    eax, eax
0047B5EF   7E13                   jle     0047B604
0047B5F1   BA01000000             mov     edx, $00000001
0047B5F6   8B4DF8                 mov     ecx, [ebp-$08]  (ECX为用户名)          
0047B5F9   0FB64C11FF             movzx   ecx, byte ptr [ecx+edx-$01]
0047B5FE   03F1                   add     esi, ecx
0047B600   42                     inc     edx
0047B601   48                     dec     eax
0047B602   75F2                   jnz     0047B5F6       (此处是一个用户名ASC值累加过程)
0047B604   8975EC                 mov     [ebp-$14], esi
0047B607   DB45EC                 fild    dword ptr [ebp-$14]

* Reference to: system.@ROUND;
|
0047B60A   E8B173F8FF             call    004029C0
0047B60F   69C009030000           imul    eax, eax, $00000309 (将累加值*309h)
0047B615   8BF0                   mov     esi, eax
0047B617   3B75FC                 cmp     esi, [ebp-$04]
0047B61A   0F85BF000000           jnz     0047B6DF  (相等则注册成功)
0047B620   B201                   mov     dl, $01

keymake 编写注册机源码
.data
szHomePage db "http://www.365hz.net";,0
szEmail    db "mailto:ljyljx@163.com",0
szErrMess  db "输入的序列号不正确!",0
szdec      db "%1u",0
hShow     db 30 dup(0)
.code
MOV ESI,EAX                
invoke lstrlen,esi  
XOR EBX,EBX    
XOR ECX,ECX                
XOR EDX,EDX                
XOR EDI,EDI
MOV EDX,1                
begin:
MOVZX EBX, byte ptr [ESI+EDX-1]
ADD EDI,EBX
INC EDX
CMP EDX,EAX
JLE begin
MOV EAX,EDI
IMUL EAX,EAX,309h
PUSH EAX
PUSH OFFSET szdec
PUSH OFFSET hShow
CALL wsprintf
LEA EAX,hShow