• 标 题:奇门遁甲演义V6.3破解手记--注册码算法分析
  • 作 者:newlaos
  • 时 间:2003/03/24 01:09pm
  • 链 接:http://bbs.pediy.com

奇门遁甲演义V6.3破解手记--注册码算法分析
作者:newlaos[DFCG]

软件名称:奇门遁甲演义V6.3(周易)
文件大小:2360KB(软件做好后,没有做任何处理,建议作者有类似UPX将软件压缩一下)
软件授权:共享软件
使用平台:Win9x/Me/NT/2000/XP
发布公司:"http://www.380000.com/
软件简介:自动排出从1900年到2050年内的任意时间的时家、日家、月家、年家奇门遁甲局况;附有相应的古注语和现注解,用彩色标出其中常见的凶格和吉格;方便的时间查找功能,自动查找满足输入条件的时间;可以导出局图的纯文字版本,方便复制和传播;时间调整功能;更详细的帮助文档。


加密方式:注册码
功能限制:频繁弹出注册对话框
PJ工具:TRW20001.23注册版、W32Dasm8.93黄金版,FI2.5
PJ日期:2003-03-23
作者newlaos申明:只是学习,请不用于商业用途或是将本文方法制作的注册机任意传播,造成后果,本人一概不负。

1、先用FI2.5看一下主程序“奇门遁甲演义VI.exe”,没有加壳。是用VB编写的。

2、用W32Dasm8.93黄金版对主文件进行静态反汇编,再用串式数据参考,找到"注册成功!"(很经典的句子),双击来到下面代码段。这样就找到注册码的计算部分。

3、再用TRW20001.23注册版进行动态跟踪,下断BPX 0040B73E(通常在注册成功与否的前面一些下断,这样,才能找到关键部分),先输入假码78787878

.......
.......
:0040B73E FF15C4D14100            Call dword ptr [0041D1C4]
:0040B744 A1D0D64100              mov eax, dword ptr [0041D6D0]
:0040B749 8D4C2448                lea ecx, dword ptr [esp+48]
:0040B74D 50                      push eax

* Possible Reference to String Resource ID=00002: "212112121222#8"
                                |
:0040B74E 6A02                    push 00000002

* Possible StringData Ref from Data Obj ->"register.ini"
                                |
:0040B750 68782D4200              push 00422D78            <===文件里放了只有我们输入的假码(78787878)
:0040B755 E816830000              call 00413A70      
:0040B75A 8D7C2408                lea edi, dword ptr [esp+08]
:0040B75E 83C9FF                  or ecx, FFFFFFFF
:0040B761 33C0                    xor eax, eax
:0040B763 F2                      repnz
:0040B764 AE                      scasb
:0040B765 F7D1                    not ecx
:0040B767 49                      dec ecx
:0040B768 51                      push ecx
:0040B769 8D4C240C                lea ecx, dword ptr [esp+0C]
:0040B76D 51                      push ecx
:0040B76E 8D4C2450                lea ecx, dword ptr [esp+50]
:0040B772 E835830000              call 00413AAC
:0040B777 8D4C2448                lea ecx, dword ptr [esp+48]
:0040B77B E8827E0000              call 00413602
:0040B780 8B0D643F4200            mov ecx, dword ptr [00423F64]
:0040B786 E8F5020000              call 0040BA80  <===这个CALL会改变88FCA4处的值(这是一个标志位),所以F8跟进
:0040B78B 8B15643F4200            mov edx, dword ptr [00423F64]
:0040B791 5F                      pop edi
:0040B792 8A8228A40000            mov al, byte ptr [edx+0000A428]
                       <===EDX=88587C(在88FCA4处的值很关键, 不能为0)
:0040B798 84C0                    test al, al           <===要不为0,才能正确跳转
:0040B79A 7515                    jne 0040B7B1          <===关键跳转,跳才正确

* Possible Reference to String Resource ID=00016: "221212212121#3"
                                |
:0040B79C 6A10                    push 00000010

* Possible StringData Ref from Data Obj ->"错误"
                                |
:0040B79E 6874004200              push 00420074

* Possible StringData Ref from Data Obj ->"注册失败!"
                                |
:0040B7A3 686C2D4200              push 00422D6C
:0040B7A8 56                      push esi

* Reference To: USER32.MessageBoxA, Ord:01BEh
                                |
:0040B7A9 FF1580D14100            Call dword ptr [0041D180]
:0040B7AF EB78                    jmp 0040B829

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040B79A(C)
|

* Possible Reference to String Resource ID=00064: "212112121222#13"
                                |
:0040B7B1 6A40                    push 00000040

* Possible StringData Ref from Data Obj ->"提示"
                                |
:0040B7B3 68FC2C4200              push 00422CFC

* Possible StringData Ref from Data Obj ->"注册成功!"
                                |
:0040B7B8 68602D4200              push 00422D60
:0040B7BD 56                      push esi

* Reference To: USER32.MessageBoxA, Ord:01BEh
                                |
:0040B7BE FF1580D14100            Call dword ptr [0041D180]
:0040B7C4 A1643F4200              mov eax, dword ptr [00423F64]
:0040B7C9 6A00                    push 00000000
:0040B7CB 56                      push esi
:0040B7CC C78004A40000FA000000    mov dword ptr [ebx+0000A404], 000000FA

* Reference To: USER32.EndDialog, Ord:00B9h
                                |
:0040B7D6 FF15DCD14100            Call dword ptr [0041D1DC]
:0040B7DC EB4B                    jmp 0040B829
.......
.......


-----0040B786 call 0040BA80  我们按F8跟进来到下面代码段-------
这一段的功能:是把我的注册码以“-”为标志分成5串,而后与机器生成的5串依次比较,只一次错就跳出
:0040BA80 6AFF                    push FFFFFFFF
:0040BA82 6858BB4100              push 0041BB58
:0040BA87 64A100000000            mov eax, dword ptr fs:[00000000]
:0040BA8D 50                      push eax
:0040BA8E 64892500000000          mov dword ptr fs:[00000000], esp
:0040BA95 81EC80000000            sub esp, 00000080
:0040BA9B 55                      push ebp
:0040BA9C 8BE9                    mov ebp, ecx
:0040BA9E 57                      push edi

* Possible Reference to String Resource ID=00001: "121121212221#19"
                                |
:0040BA9F 6A01                    push 00000001
:0040BAA1 8D4C244C                lea ecx, dword ptr [esp+4C]
:0040BAA5 E8587A0000              call 00413502

* Possible Reference to String Resource ID=00007: "121212212121#13"
                                |
:0040BAAA B907000000              mov ecx, 00000007
:0040BAAF 33C0                    xor eax, eax
:0040BAB1 8D7C2428                lea edi, dword ptr [esp+28]
:0040BAB5 6A00                    push 00000000
:0040BAB7 F3                      repz
:0040BAB8 AB                      stosd

* Possible StringData Ref from Data Obj ->"register.ini"
                                |
:0040BAB9 68782D4200              push 00422D78
:0040BABE C784249800000000000000  mov dword ptr [esp+00000098], 00000000
:0040BAC9 66AB                    stosw
:0040BACB E879FC0000              call 0041B749
:0040BAD0 83C408                  add esp, 00000008
:0040BAD3 83F8FF                  cmp eax, FFFFFFFF      
:0040BAD6 0F84CC000000            je 0040BBA8            <===这是不能跳,跳过去就OVER了。
:0040BADC A1D0D64100              mov eax, dword ptr [0041D6D0]
:0040BAE1 8D4C2448                lea ecx, dword ptr [esp+48]
:0040BAE5 50                      push eax

* Possible Reference to String Resource ID=00001: "121121212221#19"
                                |
:0040BAE6 6A01                    push 00000001

* Possible StringData Ref from Data Obj ->"register.ini"
                                |
:0040BAE8 68782D4200              push 00422D78
:0040BAED E8D47A0000              call 004135C6
:0040BAF2 8B54244C                mov edx, dword ptr [esp+4C]

* Possible Reference to String Resource ID=00010: "121121212221#10"
                                |
:0040BAF6 6A0A                    push 0000000A
:0040BAF8 8D4C242C                lea ecx, dword ptr [esp+2C]

* Possible Reference to String Resource ID=00030: "1221123121221#30"
                                |
:0040BAFC 6A1E                    push 0000001E
:0040BAFE 42                      inc edx
:0040BAFF 51                      push ecx
:0040BB00 8D4C2454                lea ecx, dword ptr [esp+54]
:0040BB04 89542458                mov dword ptr [esp+58], edx
:0040BB08 E8E27F0000              call 00413AEF
:0040BB0D 8D4C2448                lea ecx, dword ptr [esp+48]
:0040BB11 E8EC7A0000              call 00413602
:0040BB16 8BCD                    mov ecx, ebp
:0040BB18 E8A3FDFFFF              call 0040B8C0
:0040BB1D 8D542414                lea edx, dword ptr [esp+14]
:0040BB21 89442408                mov dword ptr [esp+08], eax
:0040BB25 52                      push edx
:0040BB26 8D44242C                lea eax, dword ptr [esp+2C]

* Possible Reference to String Resource ID=00045: "112112122212#13"
                                |
:0040BB2A 6A2D                    push 0000002D
:0040BB2C 50                      push eax
:0040BB2D 8BCD                    mov ecx, ebp
:0040BB2F E8FC4F0000              call 00410B30        <===这个CALL主要功能是看输入的注册码里有没有五个“-”字符,到这里我们将假码改为78-78-78-78-78-78,重新来(为了说明方便,我们定义为注册码的1、2、3、4、5串)
:0040BB34 83F805                  cmp eax, 00000005    <===EAX必须等于5,否则就跳走出错了。
:0040BB37 756F                    jne 0040BBA8  
 <===因为跳到错的地方有两个,上面那不会跳,所以这里是一个很关键的跳转
:0040BB39 53                      push ebx
:0040BB3A 56                      push esi
:0040BB3B 33FF                    xor edi, edi         <===EDI是个计数器,共5次,对应注册码有5串
:0040BB3D 8D5C241C                lea ebx, dword ptr [esp+1C]

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040BB8D(C)
|
:0040BB41 8B542410                mov edx, dword ptr [esp+10]
:0040BB45 8D4C2414                lea ecx, dword ptr [esp+14]
:0040BB49 51                      push ecx
:0040BB4A 57                      push edi
:0040BB4B 52                      push edx
:0040BB4C 8BCD                    mov ecx, ebp
:0040BB4E E89DFDFFFF              call 0040B8F0   <===呵呵,这个就是算出正确的串值的CALL了。F8跟进
:0040BB53 8B33                    mov esi, dword ptr [ebx]
:0040BB55 8D442414                lea eax, dword ptr [esp+14]  
     <===我的机器出现EAX=为正确的串值(这里用于比较的),共5次,在这里设断,得到一个值就将它改为注册码的对应的串,再点注册,又失败,但得到下一串的值,如此循环,注册失败5次后,你就得到全部的注册码了,我的是PLT6D-1DNLD-1KFDD-0XXXX-PLSCG

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040BB77(C)
|
:0040BB59 8A10                    mov dl, byte ptr [eax]
:0040BB5B 8ACA                    mov cl, dl
:0040BB5D 3A16                    cmp dl, byte ptr [esi]  
:0040BB5F 751C                    jne 0040BB7D            
:0040BB61 84C9                    test cl, cl
:0040BB63 7414                    je 0040BB79
:0040BB65 8A5001                  mov dl, byte ptr [eax+01]
:0040BB68 8ACA                    mov cl, dl
:0040BB6A 3A5601                  cmp dl, byte ptr [esi+01]
:0040BB6D 750E                    jne 0040BB7D
:0040BB6F 83C002                  add eax, 00000002
:0040BB72 83C602                  add esi, 00000002
:0040BB75 84C9                    test cl, cl
:0040BB77 75E0                    jne 0040BB59  
      <===这里构成一个小循环功能是把我们输入的假码以“-”字符分开的字符与在0040BB55给出的EAX值作比较,只要一处错就跳到40BB7D,就OVER了。

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040BB63(C)
|
:0040BB79 33C0                    xor eax, eax
:0040BB7B EB05                    jmp 0040BB82

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0040BB5F(C), :0040BB6D(C)
|
:0040BB7D 1BC0                    sbb eax, eax         <===(带位减法)EAX清0
:0040BB7F 83D8FF                  sbb eax, FFFFFFFF    <===EAX=1

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040BB7B(U)
|
:0040BB82 85C0                    test eax, eax  
      <===EAX=1说明上面循环比较出错了,EAX=0就说明比较对了。
:0040BB84 750B                    jne 0040BB91   <===如果EAX=1,这里再跳走,EAX=0不跳
:0040BB86 47                      inc edi        
:0040BB87 83C304                  add ebx, 00000004
:0040BB8A 83FF05                  cmp edi, 00000005
:0040BB8D 7CB2                    jl 0040BB41  
     <===这里是个大循环,共5次,分别比较机器算出的5个串和我们输入的5个串做比较。
:0040BB8F EB07                    jmp 0040BB98    <===5次循环都正确,就到这里再跳向胜利。

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040BB84(C)
|
:0040BB91 C68528A4000000          mov byte ptr [ebp+0000A428], 00

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040BB8F(U)
|
:0040BB98 5E                      pop esi
:0040BB99 83FF05                  cmp edi, 00000005
     <===这里也是一个很关键的对比,上面0040BB91已经把标志位清0
:0040BB9C 5B                      pop ebx
:0040BB9D 7510                    jne 0040BBAF  <===如果这里跳走,就OVER
:0040BB9F C68528A4000001          mov byte ptr [ebp+0000A428], 01
     <===[ebp+0000A428]是个标志位,能到这里,说明成功
:0040BBA6 EB07                    jmp 0040BBAF

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0040BAD6(C), :0040BB37(C)
|
:0040BBA8 C68528A4000000          mov byte ptr [ebp+0000A428], 00
     <===[ebp+0000A428]是个标志位,要是到这里,说明失败      
* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0040BB9D(C), :0040BBA6(U)
|
:0040BBAF 8D4C2454                lea ecx, dword ptr [esp+54]
:0040BBB3 C7842490000000FFFFFFFF  mov dword ptr [esp+00000090], FFFFFFFF
:0040BBBE E8F0790000              call 004135B3
:0040BBC3 8D4C2454                lea ecx, dword ptr [esp+54]
:0040BBC7 E8DE780000              call 004134AA
:0040BBCC 8B8C2488000000          mov ecx, dword ptr [esp+00000088]
:0040BBD3 5F                      pop edi
:0040BBD4 5D                      pop ebp
:0040BBD5 64890D00000000          mov dword ptr fs:[00000000], ecx
:0040BBDC 81C48C000000            add esp, 0000008C
:0040BBE2 C3                      ret


-----0040BB4E call 0040B8F0   这个就是算出正确的串值的CALL了---------------
我的注册码机器454376902,注册码就是PLT6D-1DNLD-1KFDD-0XXXX-PLSCG
* Referenced by a CALL at Address:
|:0040BB4E  
|
:0040B8F0 83EC18                  sub esp, 00000018
:0040B8F3 33C0                    xor eax, eax   <===每次进来EAX都要清0
:0040B8F5 53                      push ebx
:0040B8F6 8B5C2428                mov ebx, dword ptr [esp+28]
:0040B8FA 8BCB                    mov ecx, ebx
:0040B8FC 56                      push esi
:0040B8FD 57                      push edi
:0040B8FE 8901                    mov dword ptr [ecx], eax
:0040B900 66894104                mov word ptr [ecx+04], ax
:0040B904 E8B68F0000              call 004148BF
:0040B909 99                      cdq

* Possible Reference to String Resource ID=00100: "221121121221#5"
                                |
:0040B90A B964000000              mov ecx, 00000064
:0040B90F F7F9                    idiv ecx  <===整数除法(EAX/ECX),商回EAX,余数回ECX
:0040B911 33C0                    xor eax, eax
:0040B913 85D2                    test edx, edx
:0040B915 7E14                    jle 0040B92B
:0040B917 8B4C2428                mov ecx, dword ptr [esp+28]

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040B929(C)
|
:0040B91B 85C0                    test eax, eax
:0040B91D 7405                    je 0040B924
:0040B91F 0FAFC8                  imul ecx, eax
:0040B922 EB02                    jmp 0040B926

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040B91D(C)
|
:0040B924 8BCA                    mov ecx, edx

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040B922(U)
|
:0040B926 40                      inc eax
:0040B927 3BC2                    cmp eax, edx
:0040B929 7CF0                    jl 0040B91B  <===这里是一个循环结构

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040B915(C)
|
:0040B92B 8B44242C                mov eax, dword ptr [esp+2C] <===从EAX=0开始,每次循环到里,就加1,最后
:0040B92F 83F804                  cmp eax, 00000004       <===最后EAX=4,退出,共循环5次,正好是注册码的5个串值
:0040B932 7761                    ja 0040B995
:0040B934 FF248560BA4000          jmp dword ptr [4*eax+0040BA60]
   <===注意由于每次EAX都加1,所以导致这个无条件跳转到的位置不同,每次不同跳转产生不同的值共同构成这个注册码。
         
:0040B93B 8B442428                mov eax, dword ptr [esp+28]
   <===第一次跳到这里,EAX=1B153DC6 ,它的十进制是454376732,正好是我的机器码!
:0040B93F 3503008519              xor eax, 19850003 <===1B153DC6与19850003做异或运算
:0040B944 0D34120000              or eax, 00001234  <===EAX再与1234做或运算,值放入EAX(为说明问题,我们定义为EAX1)
:0040B949 EB4E                    jmp 0040B999      <===跳走
:0040B94B 8B442428                mov eax, dword ptr [esp+28]
   <===第二次跳到这里,EAX=1B153DC6,它的十进制是454376732,正好是我的机器码!

* Possible Reference to String Resource ID=00001: "121121212221#19"
                                |
:0040B94F B901000000              mov ecx, 00000001     <===ECX初始化为1,计数器

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040B95D(C)
|
:0040B954 8BD1                    mov edx, ecx
:0040B956 0FAFC2                  imul eax, edx   <===但实际动态跟踪时发现是EAX=EAX*1*2*3*4*5*6*7*8*9*A*B*C*D*E*F*10*11*12*13
:0040B959 41                      inc ecx              <===ECX=ECX+1
:0040B95A 83F913                  cmp ecx, 00000013    
:0040B95D 7EF5                    jle 0040B954         <===共循环16(注13是十六进制)次。
:0040B95F 0D34120000              or eax, 00001234     <===EAX再与1234做或运算,值放入EAX(为说明问题,我们定义为EAX2)
:0040B964 EB33                    jmp 0040B999         <===跳走
:0040B966 8B442428                mov eax, dword ptr [esp+28]
  <===第三次跳到这里,EAX=1B153DC6,它的十进制是454376732,正好是我的机器码!
:0040B96A 69C03C642B01            imul eax, 012B643C   <===EAX=EAX*12B643C
:0040B970 0D34120000              or eax, 00001234     <===EAX再与1234做或运算,值放入EAX(为说明问题,我们定义为EAX3)
:0040B975 EB22                    jmp 0040B999         <===跳走
:0040B977 8B442428                mov eax, dword ptr [esp+28]
  <===第四次跳到这里,EAX=1B153DC6,它的十进制是454376732,正好是我的机器码!
* Possible Reference to String Resource ID=00010: "121121212221#10"
                                |
:0040B97B B90A000000              mov ecx, 0000000A    <===将ECX初始化为10,

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040B986(C)
|
:0040B980 8BD0                    mov edx, eax
:0040B982 0FAFC2                  imul eax, edx      
   <===最后(EAX的值用C语言表示)
    eax=1B153DC6;
    for(i=0;i<>10;i++)
    {eax=eax^2;
     }
:0040B985 49                      dec ecx              <===ECX=ECX-1
:0040B986 75F8                    jne 0040B980         <===共一个小的循环结构,共循环10次,后退出!
:0040B988 EB0F                    jmp 0040B999         <===跳走,这里的EAX(为说明问题,我们定义为EAX4)
:0040B98A 8B442428                mov eax, dword ptr [esp+28]
:0040B98E 3506068519              xor eax, 19850606
:0040B993 EB04                    jmp 0040B999

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040B932(C)
|
:0040B995 8B442428                mov eax, dword ptr [esp+28]
  <===第五次跳到这里,EAX=1B153DC6,它的十进制是454376732,正好是我的机器码!。这里EAX不再做任何处理,直接拿来用了。(为说明问题,我们定义为EAX5)
* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0040B949(U), :0040B964(U), :0040B975(U), :0040B988(U), :0040B993(U)
|
:0040B999 8D4C240C                lea ecx, dword ptr [esp+0C]

* Possible Reference to String Resource ID=00036: "2114112212221#24"
                                |
:0040B99D 6A24                    push 00000024
:0040B99F 51                      push ecx                    <====ECX=8850D8
:0040B9A0 50                      push eax    
 <====这里的EAX1,EAX2,EAX3,EAX4,EAX5分别为2903FF5,B2F61234,CB5DD27,0000000,2903BC0
:0040B9A1 E879FD0000              call 0041B71F    <===这里面,EAX1,EAX2,EAX3,EAX4,EAX5再进行处理,就生成最终对应的串值,并放在出来的EAX中,F8跟进
:0040B9A6 8D7C2418                lea edi, dword ptr [esp+18]
:0040B9AA 83C9FF                  or ecx, FFFFFFFF
:0040B9AD 33C0                    xor eax, eax
:0040B9AF 83C40C                  add esp, 0000000C
:0040B9B2 F2                      repnz
:0040B9B3 AE                      scasb
:0040B9B4 F7D1                    not ecx
:0040B9B6 49                      dec ecx
:0040B9B7 8BF1                    mov esi, ecx
:0040B9B9 33C9                    xor ecx, ecx
:0040B9BB 85F6                    test esi, esi
:0040B9BD 7E17                    jle 0040B9D6

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040B9D4(C)
|
:0040B9BF 8A440C0C                mov al, byte ptr [esp+ecx+0C]
:0040B9C3 3C61                    cmp al, 61
:0040B9C5 7C0A                    jl 0040B9D1
:0040B9C7 3C7A                    cmp al, 7A
:0040B9C9 7F06                    jg 0040B9D1
:0040B9CB 2C20                    sub al, 20
:0040B9CD 88440C0C                mov byte ptr [esp+ecx+0C], al

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0040B9C5(C), :0040B9C9(C)
|
:0040B9D1 41                      inc ecx
:0040B9D2 3BCE                    cmp ecx, esi
:0040B9D4 7CE9                    jl 0040B9BF

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040B9BD(C)
|
:0040B9D6 83FE05                  cmp esi, 00000005
:0040B9D9 7C1C                    jl 0040B9F7
:0040B9DB 8D54240C                lea edx, dword ptr [esp+0C]
:0040B9DF 52                      push edx

* Possible StringData Ref from Data Obj ->"%.5s"
                                |
:0040B9E0 68F82D4200              push 00422DF8
:0040B9E5 53                      push ebx
:0040B9E6 E8EE890000              call 004143D9
:0040B9EB 83C40C                  add esp, 0000000C
:0040B9EE 5F                      pop edi
:0040B9EF 5E                      pop esi
:0040B9F0 5B                      pop ebx
:0040B9F1 83C418                  add esp, 00000018
:0040B9F4 C20C00                  ret 000C

---------:0040B9A1 call 0041B71F  按F8跟进来到下面代码段--------------------  
这段代码的作用:将EAX1,EAX2,EAX3,EAX4,EAX5再进行处理,就生成最终对应的串值,并放在出来的EAX中

* Referenced by a CALL at Addresses:
|:0040B80D   , :0040B9A1  
|
:0041B71F 55                      push ebp
:0041B720 8BEC                    mov ebp, esp
:0041B722 33C0                    xor eax, eax
:0041B724 837D100A                cmp dword ptr [ebp+10], 0000000A  <===[EBP+10]每次都是24
:0041B728 7508                    jne 0041B732                      <===所以这里每次跳走
:0041B72A 394508                  cmp dword ptr [ebp+08], eax
:0041B72D 7D03                    jge 0041B732

* Possible Reference to String Resource ID=00001: "121121212221#19"
                                |
:0041B72F 6A01                    push 00000001
:0041B731 58                      pop eax

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0041B728(C), :0041B72D(C)
|
:0041B732 50                      push eax
:0041B733 FF7510                  push [ebp+10]   <===跳到这里,将24(十六进制)压入栈
:0041B736 FF750C                  push [ebp+0C]                <===将8850D8压入栈,这个是最终串值返回时的地址
:0041B739 FF7508                  push [ebp+08]                <===依次将EAX1,EAX2,EAX3,EAX4,EAX5压入栈
:0041B73C E882FFFFFF              call 0041B6C3                <===这个CALL出来,EAX里就是正确的串值了,F8再跟进
:0041B741 8B450C                  mov eax, dword ptr [ebp+0C]  <===最终将正确的串值放入EAX中
:0041B744 83C410                  add esp, 00000010
:0041B747 5D                      pop ebp
:0041B748 C3                      ret


---------:0041B73C call 0041B6C3  按F8跟进来到下面代码段--------------------  
这段代码的作用:将EAX1,EAX2,EAX3,EAX4,EAX5再进行处理,就生成最终对应的串值,并放在出来的EAX中

* Referenced by a CALL at Addresses:
|:0041B6B6   , :0041B73C  
|
:0041B6C3 55                      push ebp
:0041B6C4 8BEC                    mov ebp, esp
:0041B6C6 837D1400                cmp dword ptr [ebp+14], 00000000  <===这里5次都相等
:0041B6CA 8B4D0C                  mov ecx, dword ptr [ebp+0C]
:0041B6CD 53                      push ebx
:0041B6CE 56                      push esi
:0041B6CF 57                      push edi
:0041B6D0 740B                    je 0041B6DD                       <===这里5次都跳走
:0041B6D2 8B7508                  mov esi, dword ptr [ebp+08]
:0041B6D5 C6012D                  mov byte ptr [ecx], 2D
:0041B6D8 41                      inc ecx
:0041B6D9 F7DE                    neg esi
:0041B6DB EB03                    jmp 0041B6E0

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041B6D0(C)
|
:0041B6DD 8B7508                  mov esi, dword ptr [ebp+08]      <===跳到这里,ESI=EAX(1,2,3,4,5)

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041B6DB(U)
|
:0041B6E0 8BF9                    mov edi, ecx                     <===EDI=8850D8

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041B706(C)
|
:0041B6E2 8BC6                    mov eax, esi                     <===EAX=EAX(1,2,3,4,5)
:0041B6E4 33D2                    xor edx, edx                     <===将EDX清0
:0041B6E6 F77510                  div [ebp+10]   <===将EAX(1,2,3,4,5)除以24,商回EAX,余数回EDX
:0041B6E9 8BC6                    mov eax, esi   <===EAX=EAX(1,2,3,4,5)
:0041B6EB 8BDA                    mov ebx, edx   <===EBX=余数
:0041B6ED 33D2                    xor edx, edx   <===将EDX清0
:0041B6EF F77510                  div [ebp+10]   <===将EAX(1,2,3,4,5)除以24(十六进制),商回EAX,余数回EDX(不明白为什么又除一遍)
:0041B6F2 83FB09                  cmp ebx, 00000009 <===这个判断很重要!
:0041B6F5 8BF0                    mov esi, eax
:0041B6F7 7605                    jbe 0041B6FE      <===如果余数是数字,就跳转。如果余数是字符,就不跳转
:0041B6F9 80C357                  add bl, 57
:0041B6FC EB03                    jmp 0041B701

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041B6F7(C)
|
:0041B6FE 80C330                  add bl, 30

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041B6FC(U)
|
:0041B701 8819                    mov byte ptr [ecx], bl <===其实这个判断的处理作用就是将余数处理为其对应的ASCII值(字符是小写)
:0041B703 41                      inc ecx
:0041B704 85F6                    test esi, esi
:0041B706 77DA                    ja 0041B6E2  <===从这里向上,构成一个循环结构,共循环5次,第n次在bl处得到余数转为字符后,就构成串值的第n位
***** 这一小段的循环作用(以EAX1为例):
       公式           商      余数     对应的字符
     2903FF5/24     123AAA     D        d
      123AAA/24      81A1      6        6
       81A1/24       339       1D       t  (d字符后面的16位的字符)以ASC码表为顺序
        339/24       19        15       l  (数字5后面的16位的字符)
         19/24       0         19       p  (数字9后面的16位的字符)
***** 最后在内存的8850D8位置上得到串值d6tlp

:0041B708 802100                  and byte ptr [ecx], 00
:0041B70B 49                      dec ecx

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041B718(C)
|
:0041B70C 8A17                    mov dl, byte ptr [edi]
:0041B70E 8A01                    mov al, byte ptr [ecx]
:0041B710 8811                    mov byte ptr [ecx], dl
:0041B712 8807                    mov byte ptr [edi], al
:0041B714 49                      dec ecx
:0041B715 47                      inc edi
:0041B716 3BF9                    cmp edi, ecx
:0041B718 72F2                    jb 0041B70C  
      <===从这里向上,构成一个循环结构,作用是将上面得到串值反向再取值,所以最后8850D8位置上得到串值plt6d(其它程序段会把它转为大写)
:0041B71A 5F                      pop edi
:0041B71B 5E                      pop esi
:0041B71C 5B                      pop ebx
:0041B71D 5D                      pop ebp
:0041B71E C3                      ret
此段总结:依照上面的步骤将EAX1,EAX2,EAX3,EAX4,EAX5最后处理为plt6d,1dnld,1kfdd,0xxxx,plscg ----注册码浮出水面

-------------------------------------------------------------------------------------------------


4、算法总结:-----类型:f(机器码)=注册码------
 a、将机器码454376732(每台机器码都不一样),转换为十六进制1B153DC6

 b、将1B153DC6分别做5种的处理,得到相应串值的第一次变形
       第一种处理:1B153DC6与19850003做异或运算,再与1234做或运算,得到2903FF5
       第二种处理:1B153DC6EAX=EAX*1*2*3*4*5*6*7*8*9*A*B*C*D*E*F*10*11*12*13,再与1234做或运算,得到B2F61234
       第三种处理:1B153DC6*12B643C,再与1234做或运算,得到CB5DD27C
       第四种处理:eax=1B153DC6; for(i=0;i<>10;i++) {eax=eax^2;}一般情况EAX都会因为值太大,而爆为00000000
       第五种处理:1B153DC6不做处理

 c、分别将上一步得到的5串数字,做同样的处理,也就是(以EAX1为例):
       公式           商      余数     对应的字符
     2903FF5/24     123AAA     D        d
      123AAA/24      81A1      6        6
       81A1/24       339       1D       t  (d字符后面的16位的字符)以ASC码表为顺序
        339/24       19        15       l  (数字5后面的16位的字符)
         19/24       0         19       p  (数字9后面的16位的字符)
     最后改为字符串d6tlp,其它的四个串也依次类推。

 d、将上一步得到的5个字符分别反向取值,分别得到plt6d,1dnld,1kfdd,0xxxx,plscg,最后的注册码就是将它转为大写后,中间分别加上“-”,PLT6D-1DNLD-1KFDD-0XXXX-PLSCG

5、注册信息存放在奇门遁甲演义V6.3所在目录的register.ini文件中。以明文件形式保留。