• 标 题:Advanced MP3WMA Recorder 3.7.3破解手记--完美算法分析 
  • 作 者: newlaos
  • 时 间:2003/04/15 02:59pm
  • 链 接:http://bbs.pediy.com

dvanced MP3WMA Recorder 3.7.3破解手记--完美算法分析
作者:newlaos[CCG][DFCG]


Advanced MP3WMA Recorder 3.7.3(音频工具)
整理日期:2003.3.29(华军网)
最新版本:3.7.3
文件大小:5317KB
软件授权:共享软件
使用平台:Win9x/Me/2000/XP
发布公司:http://www.xaudiotools.com/
软件简介:Advanced Mp3/Wma Recorder 是一个完善且极专业的录音软件,使用它你可以轻易地从麦克风、流媒体中录制声音。它也可以从 Winamp、Windows 媒体播放器、Quick Time、Real Player 这些播放软件或者是 FLASH、游戏中录制,并能去除噪音。Advanced Mp3/Wma Recorder 录音保存的格式支持 Mp3、Wma 或 Wav 三种(只有在你可以听到声音时它才能够将流媒体 AVI/WMV/ASF/RM/AU/MIDI……录制成MP3/WMA/WAV)。宽带时代的来临,我们可以在网络上收广播、听歌曲、看电影、打网络电话,很多网页也有非常好听的背景音乐,但是我们不能下载到电脑中。现在除了在线上享受之外,Advanced MP3/WMA Recorder 可以帮你把所有在电脑上播放的声音录下来,还可以自由地存成WAV、MP3 及 WMA等格式喔。想永久保存你从电脑中听到的声音吗?那就用 Advanced MP3/WMA Recorder 吧。


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

1、用FI2.5查壳,发现加了UPX的壳,本想用TRW2000进行手动脱壳,可以一载入就出错,呵呵,程序有ANTI-DEBUG?有但是不完全,不然就没有后面一段了:-);再用GUW32 v1.0再脱,还出错。用UPX1.24脱不了,最后拿出作者号称不稳定的UPX1.9来脱,呵呵,成功了。生成UNPACK.exe文件,运行没错。 脱壳完成!

2、程序是VB编写的(我有些朋友一见VB程序,就delete。先别急),还好不是P-CODE形式的,用W32Dasm黄金修正版本进行静态反汇编,找到"Thank you,register successfully!"(注册成功标志),双击来到下面代码段。

3、找关键CALL,关键跳转。VB的程序都比较长,关键部分都拉得很长。幸好在00456294一行发现程序是从0045604E一行跳转过来的,正好象程序那样,如果注册信息不正确就没有任何提示。呵呵,那里就是关键跳转了。我们来到0045604E一行再分析,向上看__vbaStrCmp函数(字符对比),有门!

4、动态跟踪调试。呵呵,再请出国宝TRW2000,这会体现出它的威力来了(OLLYDBG1.09用__vbaStrCmp设断,没办法用)。注意我的步骤,运行TRW2000,不要加载任何程序,再运行unpack.exe,进行注册对话框,输入注册名:newlaos,再输入假码:78787878。不要点注册按钮,直接CTRL+N就可以呼出TRW2000,下断点BPX 455FE4(关键就在这,不用TRW2000载入程序,依然可以下断点,真绝,不知SOFTICE可不可以)。这下好了,可以动态跟踪调试了。
注:此程序花指令太多,尤其是在算法CALL里,天大一串,要有心理准备哟。

......
......
:00455FDD 50                      push eax      

* Reference To: MSVBVM60.__vbaHresultCheckObj, Ord:0000h
                                 |
:00455FDE FF1554104000            Call dword ptr [00401054]

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00455FCA(C)
|
:00455FE4 8D953CFFFFFF            lea edx, dword ptr [ebp+FFFFFF3C]<===在这里下断
:00455FEA 8D45D0                  lea eax, dword ptr [ebp-30] <===EAX为一地址指针指向一个定值4C29AGE8BC2YCX3N
:00455FED 52                      push edx
:00455FEE 8D4DB0                  lea ecx, dword ptr [ebp-50]
:00455FF1 50                      push eax
:00455FF2 51                      push ecx
:00455FF3 E8B80C0000              call 00456CB0 <===这个CALL,使真正的注册码进入EAX,F8跟进
:00455FF8 8BD0                    mov edx, eax
:00455FFA 8D4DC8                  lea ecx, dword ptr [ebp-38]
:00455FFD FFD3                    call ebx
:00455FFF 8B55CC                  mov edx, dword ptr [ebp-34]
:00456002 50                      push eax <===这是什么,呵呵是宽字符的真注册码
:00456003 52                      push edx <===宽字符的假码78787878,在这里可以制作内存注册机了

* Reference To: MSVBVM60.__vbaStrCmp, Ord:0000h
                                 |
:00456004 FF15BC104000            Call dword ptr [004010BC]<===字符串比较函数,想想是干什么用的:-)
:0045600A 8BF8                    mov edi, eax
:0045600C 8D45CC                  lea eax, dword ptr [ebp-34]
:0045600F 8D4DC8                  lea ecx, dword ptr [ebp-38]
:00456012 50                      push eax
:00456013 F7DF                    neg edi
:00456015 8D55D0                  lea edx, dword ptr [ebp-30]
:00456018 51                      push ecx
:00456019 8D45D4                  lea eax, dword ptr [ebp-2C]
:0045601C 52                      push edx
:0045601D 1BFF                    sbb edi, edi
:0045601F 8D4DD8                  lea ecx, dword ptr [ebp-28]
:00456022 50                      push eax
:00456023 47                      inc edi
:00456024 51                      push ecx
:00456025 6A05                    push 00000005
:00456027 F7DF                    neg edi

* Reference To: MSVBVM60.__vbaFreeStrList, Ord:0000h
                                 |
:00456029 FF1554114000            Call dword ptr [00401154]
:0045602F 8D55C0                  lea edx, dword ptr [ebp-40]
:00456032 8D45C4                  lea eax, dword ptr [ebp-3C]
:00456035 52                      push edx
:00456036 50                      push eax
:00456037 6A02                    push 00000002

* Reference To: MSVBVM60.__vbaFreeObjList, Ord:0000h
                                 |
:00456039 FF153C104000            Call dword ptr [0040103C]
:0045603F 83C424                  add esp, 00000024
:00456042 8D4DB0                  lea ecx, dword ptr [ebp-50]

* Reference To: MSVBVM60.__vbaFreeVar, Ord:0000h
                                 |
:00456045 FF1524104000            Call dword ptr [00401024]
:0045604B 6685FF                  test di, di
:0045604E 0F8440020000            je 00456294   <===这里就是关键的跳转了。再往上看00456004一行。
:00456054 66C7052AA04500FFFF      mov word ptr [0045A02A], FFFF
:0045605D 8B0E                    mov ecx, dword ptr [esi]
.......
此处略一段无关代码
.......
* Reference To: MSVBVM60.__vbaVarDup, Ord:0000h
                                 |
:004561B2 8B3578114000            mov esi, dword ptr [00401178]
:004561B8 B904000280              mov ecx, 80020004
:004561BD 894D88                  mov dword ptr [ebp-78], ecx
:004561C0 B80A000000              mov eax, 0000000A
:004561C5 894D98                  mov dword ptr [ebp-68], ecx
:004561C8 BB08000000              mov ebx, 00000008
:004561CD 8D9560FFFFFF            lea edx, dword ptr [ebp+FFFFFF60]
:004561D3 8D4DA0                  lea ecx, dword ptr [ebp-60]
:004561D6 894580                  mov dword ptr [ebp-80], eax
:004561D9 894590                  mov dword ptr [ebp-70], eax

* Possible StringData Ref from Code Obj ->"Register Successfully"
                                 |
:004561DC C78568FFFFFF10C74000    mov dword ptr [ebp+FFFFFF68], 0040C710
:004561E6 899D60FFFFFF            mov dword ptr [ebp+FFFFFF60], ebx
:004561EC FFD6                    call esi
:004561EE 8D9570FFFFFF            lea edx, dword ptr [ebp+FFFFFF70]
:004561F4 8D4DB0                  lea ecx, dword ptr [ebp-50]

* Possible StringData Ref from Code Obj ->"Thank you,register successfully!"
                                 |            <===注册成功的标志
:004561F7 C78578FFFFFFC8C64000    mov dword ptr [ebp+FFFFFF78], 0040C6C8
:00456201 899D70FFFFFF            mov dword ptr [ebp+FFFFFF70], ebx
:00456207 FFD6                    call esi
.......
此处略一段无关代码
.......
:0045628D 8D4DC4                  lea ecx, dword ptr [ebp-3C]
:00456290 FFD7                    call edi
:00456292 EB67                    jmp 004562FB

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0045604E(C)        <===这里就可以看出关键的跳转在0045604E上,向上看
|
:00456294 668B1528A04500          mov dx, word ptr [0045A028]
:0045629B A1CCA74500              mov eax, dword ptr [0045A7CC]
:004562A0 6683C201                add dx, 0001
:004562A4 0F80D0000000            jo 0045637A
:004562AA 85C0                    test eax, eax
:004562AC 66891528A04500          mov word ptr [0045A028], dx
:004562B3 7510                    jne 004562C5
:004562B5 68CCA74500              push 0045A7CC
:004562BA 6878AA4000              push 0040AA78
.......
.......

------------F8跟进来到下列代码段,天大一串,花指令太多--------------------------
.......
.......上面删除一大串花指令

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004581FF(U)              <===这里开始循环
|
:00458019 668B8D48FFFFFF          mov cx, word ptr [ebp+FFFFFF48]
:00458020 66038D38FEFFFF          add cx, word ptr [ebp+FFFFFE38]
:00458027 0F80F4090000            jo 00458A21
:0045802D 66898D48FFFFFF          mov word ptr [ebp+FFFFFF48], cx

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00458017(U)
|
:00458034 668B9548FFFFFF          mov dx, word ptr [ebp+FFFFFF48]
:0045803B 663B9534FEFFFF          cmp dx, word ptr [ebp+FFFFFE34] <===[ebp+FFFFFE34]里放的是注册名的长度
:00458042 0F8FBC010000            jg 00458204      <===循环结束后就这里跳出

*****略去中间一段花指令*****

:004580F8 8D8DDCFEFFFF            lea ecx, dword ptr [ebp+FFFFFEDC]
:004580FE 51                      push ecx
:004580FF 8D95FCFEFFFF            lea edx, dword ptr [ebp+FFFFFEFC]
:00458105 52                      push edx

* Reference To: MSVBVM60.__vbaStrVarVal, Ord:0000h
                                 |
:00458106 FF151C114000            Call dword ptr [0040111C] <===依次取出注册名的字符放在EAX里
:0045810C 50                      push eax

* Reference To: MSVBVM60.__vbaFreeObjList, Ord:0204h
                                 |
:0045810D FF1540104000            Call dword ptr [00401040]
       <===将取出的字符的ASC值放入EAX(依次取出的是6E 65 77 6C 61 6F 73)
:00458113 8B8D70FEFFFF            mov ecx, dword ptr [ebp+FFFFFE70]
:00458119 8B952CFFFFFF            mov edx, dword ptr [ebp+FFFFFF2C]
:0045811F 668B0C4A                mov cx, word ptr [edx+2*ecx]
:00458123 6603C8                  add cx, ax  <===ax为ASC值,
:00458126 0F80F5080000            jo 00458A21
:0045812C 6683F112                xor cx, 0012
       <===取出字符的ASC值与18做异或运算(依次结果7C 77 65 7E 73 7D 61)
:00458130 8B9574FEFFFF            mov edx, dword ptr [ebp+FFFFFE74]
:00458136 8B852CFFFFFF            mov eax, dword ptr [ebp+FFFFFF2C]
:0045813C 66890C50                mov word ptr [eax+2*edx], cx <===将依次得出的结果,每隔两位放在以EAX+2为开始的内存里(备用)
:00458140 8D8DFCFEFFFF            lea ecx, dword ptr [ebp+FFFFFEFC]

* Reference To: MSVBVM60.__vbaFreeStr, Ord:0000h
                                 |
:00458146 FF15D8114000            Call dword ptr [004011D8]
:0045814C 8D8DDCFEFFFF            lea ecx, dword ptr [ebp+FFFFFEDC]
:00458152 51                      push ecx
:00458153 8D95ECFEFFFF            lea edx, dword ptr [ebp+FFFFFEEC]
:00458159 52                      push edx
:0045815A 6A02                    push 00000002

* Reference To: MSVBVM60.__vbaFreeVarList, Ord:0000h
                                 |
:0045815C FF1534104000            Call dword ptr [00401034]
:00458162 83C40C                  add esp, 0000000C
:00458165 C745FC5F000000          mov [ebp-04], 0000005F
:0045816C 0FBF850CFFFFFF          movsx eax, word ptr [ebp+FFFFFF0C]
:00458173 898574FEFFFF            mov dword ptr [ebp+FFFFFE74], eax
:00458179 83BD74FEFFFF11          cmp dword ptr [ebp+FFFFFE74], 00000011
:00458180 730C                    jnb 0045818E
:00458182 C78594FDFFFF00000000    mov dword ptr [ebp+FFFFFD94], 00000000
:0045818C EB0C                    jmp 0045819A
*****略去中间一段花指令*****
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0045818C(U)
|
:0045819A 8B8D74FEFFFF            mov ecx, dword ptr [ebp+FFFFFE74]
:004581A0 8B952CFFFFFF            mov edx, dword ptr [ebp+FFFFFF2C]
:004581A6 668B45B4                mov ax, word ptr [ebp-4C]
:004581AA 6603044A                add ax, word ptr [edx+2*ecx] <===将依次得出的结果相加(327)
:004581AE 0F806D080000            jo 00458A21
:004581B4 668945B4                mov word ptr [ebp-4C], ax   <===将计算的结果(327)备用
:004581B8 C745FC60000000          mov [ebp-04], 00000060
:004581BF 668B8D0CFFFFFF          mov cx, word ptr [ebp+FFFFFF0C]
:004581C6 6683C101                add cx, 0001
:004581CA 0F8051080000            jo 00458A21
:004581D0 66898D0CFFFFFF          mov word ptr [ebp+FFFFFF0C], cx
:004581D7 C745FC61000000          mov [ebp-04], 00000061
:004581DE 6683BD0CFFFFFF09        cmp word ptr [ebp+FFFFFF0C], 0009
:004581E6 7510                    jne 004581F8
:004581E8 C745FC62000000          mov [ebp-04], 00000062
:004581EF 66C7850CFFFFFF0100      mov word ptr [ebp+FFFFFF0C], 0001

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004581E6(C)
|
:004581F8 C745FC64000000          mov [ebp-04], 00000064
:004581FF E915FEFFFF              jmp 00458019 <===从这里向上跳构成一个大循环,主要功能是将注册名进行变形处理

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00458042(C)
|
:00458204 C745FC65000000          mov [ebp-04], 00000065   <===从00458042一行跳出循环结构
:0045820B 668B55DC                mov dx, word ptr [ebp-24]
:0045820F 6689952CFEFFFF          mov word ptr [ebp+FFFFFE2C], dx
:00458216 66C78530FEFFFF0100      mov word ptr [ebp+FFFFFE30], 0001
:0045821F 66C78548FFFFFF0100      mov word ptr [ebp+FFFFFF48], 0001
:00458228 EB1B                    jmp 00458245   <===我跳

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00458404(U)                 <===呵呵,这里开始循环
|
:0045822A 668B8548FFFFFF          mov ax, word ptr [ebp+FFFFFF48]
:00458231 66038530FEFFFF          add ax, word ptr [ebp+FFFFFE30]
:00458238 0F80E3070000            jo 00458A21
:0045823E 66898548FFFFFF          mov word ptr [ebp+FFFFFF48], ax

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00458228(U)
|
:00458245 668B8D48FFFFFF          mov cx, word ptr [ebp+FFFFFF48]
:0045824C 663B8D2CFEFFFF          cmp cx, word ptr [ebp+FFFFFE2C]
:00458253 0F8FB0010000            jg 00458409  <===循环结束后就这里跳出

*****略去中间一段花指令*****

:00458306 8D85DCFEFFFF            lea eax, dword ptr [ebp+FFFFFEDC]
:0045830C 50                      push eax
:0045830D 8D8DFCFEFFFF            lea ecx, dword ptr [ebp+FFFFFEFC]
:00458313 51                      push ecx

* Reference To: MSVBVM60.__vbaStrVarVal, Ord:0000h
                                 |
:00458314 FF151C114000            Call dword ptr [0040111C]<===依次取出定数4C29AGE8BC2YCX3N的每个字符
:0045831A 50                      push eax

* Reference To: MSVBVM60.__vbaFreeObjList, Ord:0204h
                                 |
:0045831B FF1540104000            Call dword ptr [00401040]
<===将依次取出字符的ASC值放入EAX(34 43 32 39 41 47 45 38 42 43 32 59 43 58 33 4E)
:00458321 8B9570FEFFFF            mov edx, dword ptr [ebp+FFFFFE70]
:00458327 8B4D80                  mov ecx, dword ptr [ebp-80]
:0045832A 668B1451                mov dx, word ptr [ecx+2*edx]
:0045832E 6603D0                  add dx, ax
<===ax为ASC值,cx前8个一直为0(这等效一个MOV指令),后8个则为前8个数值计算的结果
:00458331 0F80EA060000            jo 00458A21
:00458337 6683F219                xor dx, 0019 <===ASC值与25做异或运算,见列表

**************     循环计算结果列表    *************************
原始ASC值(前8个):34    43    32    39    41    47    45    38
ECX的值:         0     0     0     0     0     0     0     0
做异或运算的结果:2D    5A    2B    20    58    5E    5C    21

原始ASC值(后8个):42    43    32    59    43    58    33    4E
ECX的值(前8结果):2D    5A    2B    20    58    5E    5C    21
做异或运算的结果:76    84    44    60    82    AF    96    76
****************************************************************

:0045833B 8B8574FEFFFF            mov eax, dword ptr [ebp+FFFFFE74]
:00458341 8B4D80                  mov ecx, dword ptr [ebp-80]
:00458344 66891441                mov word ptr [ecx+2*eax], dx

<===由于程序的设计,最后变形出来的值为(84 44 60 82 AF 96 76 76),第一个值放到最后去了。
********注:最后变形出来的值与注册名的长度有关********
1位长度注册名:76    76    84    44    60    82    AF    96  (和9位长度的一样)
7位长度注册名:84    44    60    82    AF    96    76    76
标准是8位长度:76    84    44    60    82    AF    96    76
9位长度注册名:76    76    84    44    60    82    AF    96    
10位长 注册名:96    76    76    84    44    60    82    AF    
******************************************************

:00458348 8D8DFCFEFFFF            lea ecx, dword ptr [ebp+FFFFFEFC]

* Reference To: MSVBVM60.__vbaFreeStr, Ord:0000h
                                 |
:0045834E FF15D8114000            Call dword ptr [004011D8]
:00458354 8D95DCFEFFFF            lea edx, dword ptr [ebp+FFFFFEDC]
:0045835A 52                      push edx
:0045835B 8D85ECFEFFFF            lea eax, dword ptr [ebp+FFFFFEEC]
:00458361 50                      push eax
:00458362 6A02                    push 00000002

* Reference To: MSVBVM60.__vbaFreeVarList, Ord:0000h
                                 |
:00458364 FF1534104000            Call dword ptr [00401034]
:0045836A 83C40C                  add esp, 0000000C
:0045836D C745FC67000000          mov [ebp-04], 00000067
:00458374 0FBF8D0CFFFFFF          movsx ecx, word ptr [ebp+FFFFFF0C]
:0045837B 898D74FEFFFF            mov dword ptr [ebp+FFFFFE74], ecx
:00458381 83BD74FEFFFF11          cmp dword ptr [ebp+FFFFFE74], 00000011
:00458388 730C                    jnb 00458396
:0045838A C78588FDFFFF00000000    mov dword ptr [ebp+FFFFFD88], 00000000
:00458394 EB0C                    jmp 004583A2
*****略去中间一段花指令*****
:004583A2 8B9574FEFFFF            mov edx, dword ptr [ebp+FFFFFE74]
:004583A8 8B4580                  mov eax, dword ptr [ebp-80]
:004583AB 668B4DA8                mov cx, word ptr [ebp-58]
:004583AF 66030C50                add cx, word ptr [eax+2*edx]
<===将2D 5A 2B 20 58 5E 5C 21 76 84 44 60 82 AF 96 76相加,最后结果是5E0,备用
:004583B3 0F8068060000            jo 00458A21
:004583B9 66894DA8                mov word ptr [ebp-58], cx
:004583BD C745FC68000000          mov [ebp-04], 00000068
:004583C4 668B950CFFFFFF          mov dx, word ptr [ebp+FFFFFF0C]
:004583CB 6683C201                add dx, 0001
:004583CF 0F804C060000            jo 00458A21
:004583D5 6689950CFFFFFF          mov word ptr [ebp+FFFFFF0C], dx
:004583DC C745FC69000000          mov [ebp-04], 00000069
:004583E3 6683BD0CFFFFFF09        cmp word ptr [ebp+FFFFFF0C], 0009
:004583EB 7510                    jne 004583FD
:004583ED C745FC6A000000          mov [ebp-04], 0000006A
:004583F4 66C7850CFFFFFF0100      mov word ptr [ebp+FFFFFF0C], 0001

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004583EB(C)
|
:004583FD C745FC6C000000          mov [ebp-04], 0000006C
:00458404 E921FEFFFF              jmp 0045822A  <===从这里向上跳构成一个大循环,主要功能是将定数4C29AGE8BC2YCX3N进行变形处理,最后变形出来的值为(84 44 60 82 AF 96 76 76)

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00458253(C)
|
:00458409 C745FC6D000000          mov [ebp-04], 0000006D  <===跳出循环后,到这里
:00458410 668B45B4                mov ax, word ptr [ebp-4C] <===AX=327 为前面注册名变形值相加总和
:00458414 660345A8                add ax, word ptr [ebp-58] <===[ebp-58]为前面定值变形值相加总和5E0
:00458418 0F8003060000            jo 00458A21
:0045841E 6625FF01                and ax, 01FF   <===AX=907 AND 1FF=107(这个值很关键,备用)
:00458422 7908                    jns 0045842C
:00458424 6648                    dec ax
:00458426 660D00FE                or ax, FE00
:0045842A 6640                    inc ax

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00458422(C)
|
:0045842C 66898550FFFFFF          mov word ptr [ebp+FFFFFF50], ax <===将107放入内存位置,后面用
:00458433 C745FC6E000000          mov [ebp-04], 0000006E
:0045843A 66C7850CFFFFFF0100      mov word ptr [ebp+FFFFFF0C], 0001
:00458443 C745FC6F000000          mov [ebp-04], 0000006F
:0045844A 66C78510FFFFFF0100      mov word ptr [ebp+FFFFFF10], 0001
:00458453 C745FC70000000          mov [ebp-04], 00000070
:0045845A 668B4DB8                mov cx, word ptr [ebp-48]
:0045845E 66898D24FEFFFF          mov word ptr [ebp+FFFFFE24], cx
:00458465 66C78528FEFFFF0100      mov word ptr [ebp+FFFFFE28], 0001
:0045846E 66C78548FFFFFF0100      mov word ptr [ebp+FFFFFF48], 0001
:00458477 EB1B                    jmp 00458494

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004588D5(U)            <===从这里开始循环
|
:00458479 668B9548FFFFFF          mov dx, word ptr [ebp+FFFFFF48]
:00458480 66039528FEFFFF          add dx, word ptr [ebp+FFFFFE28]
:00458487 0F8094050000            jo 00458A21
:0045848D 66899548FFFFFF          mov word ptr [ebp+FFFFFF48], dx

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00458477(U)
|
:00458494 668B8548FFFFFF          mov ax, word ptr [ebp+FFFFFF48]
:0045849B 663B8524FEFFFF          cmp ax, word ptr [ebp+FFFFFE24]
:004584A2 0F8F32040000            jg 004588DA   <===循环结束后,从这里跳出

*****略去一段花指令*******

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0045852B(U)
|
:00458539 8B8D70FEFFFF            mov ecx, dword ptr [ebp+FFFFFE70]
:0045853F 8B5580                  mov edx, dword ptr [ebp-80]  
  <===定数变形值84 44 60 82 AF 96 76 76(以注册名newlaos,7位长度的变形值)
:00458542 8B856CFEFFFF            mov eax, dword ptr [ebp+FFFFFE6C]
:00458548 8B75CC                  mov esi, dword ptr [ebp-34]  
  <===这里是一串不变值(2E 59 8E 3F E7 20 81 33 1C 61 F8 29 88 35 4E A4 47 5C),任何机器上都是一样的。在编注册机时可以直接拿来用了。
:0045854B 668B0C4A                mov cx, word ptr [edx+2*ecx]
:0045854F 66330C46                xor cx, word ptr [esi+2*eax]
  <===依次取出定数变形值与不变值进行异或运算,只要8位
:00458553 8B9574FEFFFF            mov edx, dword ptr [ebp+FFFFFE74]
:00458559 8B4580                  mov eax, dword ptr [ebp-80]
:0045855C 66890C50                mov word ptr [eax+2*edx], cx
  <===保存计算结果(依次是AA 1D EE BD 48 B6 F7 45),放回定数变形值的对应位置
:00458560 C745FC72000000          mov [ebp-04], 00000072

******略去一段花指令*******

:004585C3 8B8574FEFFFF            mov eax, dword ptr [ebp+FFFFFE74]
:004585C9 8B8D2CFFFFFF            mov ecx, dword ptr [ebp+FFFFFF2C]
  <===注册名处理变形后的值(依次是7C 77 65 7E 73 7D 61),如果不足8位,用00补。超过8位,只取前8位
:004585CF 8B9570FEFFFF            mov edx, dword ptr [ebp+FFFFFE70]
:004585D5 8B7580                  mov esi, dword ptr [ebp-80]<===上一步异或计算的结果(依次是AA 1D EE BD 48 B6 F7 45)
:004585D8 668B0441                mov ax, word ptr [ecx+2*eax]
:004585DC 66330456                xor ax, word ptr [esi+2*edx]
  <===再一次做异或运算(结果依次是D6 6A 8B C3 3B CB 96 45)
:004585E0 668BC8                  mov cx, ax
:004585E3 6681E1FF01              and cx, 01FF <===得出的结果分别与01FF做与运算,这里值没有变
:004585E8 7909                    jns 004585F3 <===跳走
:004585EA 6649                    dec cx
:004585EC 6681C900FE              or cx, FE00
:004585F1 6641                    inc cx

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004585E8(C)
|
:004585F3 662B8D50FFFFFF          sub cx, word ptr [ebp+FFFFFF50]<===哈哈,[ebp+FFFFFF50]是什么,就是前面备用的107呀,计算得出负值
:004585FA 0F8021040000            jo 00458A21

* Reference To: MSVBVM60.__vbaI2Abs, Ord:0000h
                                 |
:00458600 FF1548104000            Call dword ptr [00401048]
<===这里调用的是VB里的ABS函数(求绝对值函数),最终得出结果依次为31 9D 7C 44 CC 3C 71 C2(注册码出来了,就是319D-7C44-CC3C-71C2)
:00458606 66898514FFFFFF          mov word ptr [ebp+FFFFFF14], ax

***********略去一段无关代码******************(这一段代码的作用,是如果上面的结果出来,就只取前面两位)
|
:004588CE C745FC85000000          mov [ebp-04], 00000085
:004588D5 E99FFBFFFF              jmp 00458479   <===呵呵,这里向上跳构成一个大循环,每一循环计算出两位注册码

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004584A2(C)
|
:004588DA C745FC86000000          mov [ebp-04], 00000086

***********略去一段无关代码******************

* Reference To: MSVBVM60.__vbaFreeStr, Ord:0000h
                                 |
:00458A01 FF15D8114000            Call dword ptr [004011D8]
:00458A07 C3                      ret

-----------------------------------------------------------------------------------------
5、算法分析:---f(注册名)=注册码---
 a、将注册码取出每个字符的ASC值,分别与18做异或运算,成为新的一串值C(8),在后面计算中不足8位用0补足。超过8位的,如:第9位就和第1位生成的结果再相加,生成新的第1位,第10位就和第2位生的结果再相加,生成新的第2位,以此类推生成新的只有8位的串值。最后再将所有数,只要是与18做过异或运算的结果都参与相加,得出一个总数regsam备用。
 b、将定数4C29AGE8BC2YCX3N进行变形处理(具体过程见上面),得出一串数76,84,44,60,82,AF,96,76,这串数字与注册名的长度有关,产生一个移位后,再用于后面的运算。将这串值相加得出定数5E0(10进制1504),备用
 c、程序又取出一串定值2E 59 8E 3F E7 20 81 33 1C 61 F8 29 88 35 4E A4 47 5C,但只用前面8位
 d、将总数regsam加上5E0,再与1FF做与运算,生成lastsum,备用
 e、取a步骤中的第n位值与b步骤中的第n位值做异或运算,再与c中的第n位值做异或运算,得出结果与1FF做与运算,再减去lastsum,得出的结果,取绝对值,这时得到的数构成注册码的两位(超过2位,只取2位;不足2位,在前面补0),a、b、c串中共有8个数值,因此得出注册码的16位数值。

6、注册机:注册名可为英文、中文或中英文混合,但只要有中文输入后,长度不能大于8,纯英文(字符)的注册名不受长度限制
------------VB 注册机()------------------------
Private Sub Command1_Click()
Dim e As Integer
Dim h As Integer
Dim i As Integer
Dim j As Integer
Dim k As Integer
Dim l As Integer
Dim m As Integer
Dim reglen As Integer
Dim g As Long
Dim t As Long
Dim regsam As Long
Dim lastsum As Long
Dim laststr As String
Dim regname As String
Dim strtmp As String

Dim A As Variant
Dim B As Variant
Dim C As Variant

regname = Text1.Text    '取得注册名
reglen = Len(regname)   '取得注册名的长度,这里取决定数的变形情况
If reglen = 0 Then
m = MsgBox("你还没有输入注册名,请重新输入", 0, "连注册名也不愿输入???")
Else
A = Array(118, 132, 68, 96, 130, 175, 150, 118) '定义定数的数组,以0位长度注册名的变值作为初值(已经改为10进制)
B = Array(46, 89, 142, 63, 231, 32, 129, 51) '定义固定数值的数组,只取有用的前8位(已经改为10进制)
C = Array(0, 0, 0, 0, 0, 0, 0, 0)      '将注册名的数组初始化,只取8位,不足用0补
 For i = 1 To reglen   '对定数的数组,根据注册名长度进行移位处理
   numtmp = A(7)       '把最后一个值先拿出来,数组值的定义与VC一样A(7)代表数组中第8个值,A(0)代表第1个
   For j = 1 To 7      '小循环,后面各数值向前移一位
    A(8 - j) = A(7 - j)
   Next j
   A(0) = numtmp
 Next i
 
 l = 0
 k = 0
 h = 1
 Do                    '完成注册名的变形处理,及相加运算
   e = Asc(Mid(regname, (l + 1), 1))
   g = CLng("&H" + Hex(e))   '这里针对中文特别设计必须用clng函数,用CINT函数会出错
   C(k) = (g + C(k)) Xor 18  '后面这个C(k)只在注册名大于9的时候,才用到
   t = C(k)
'针对程序中的溢出异常处理(最气人的是程序运行时,只受理前两个汉字后,就不再加任何汉字,即使有再多,字符则不限)
   If (Abs(e) <> e) Then
   h = h + 1
   End If
   If (Abs(e) <> e) And (h > 3) Then
   t = 0
   End If
   If (regsam + t) >= 65536 Then  '正常溢出处理
   regsam = regsam + t - 65536
   Else
   regsam = regsam + t
   End If
   k = k + 1
   If k = 8 Then   '形成对数组内数的一个循环
   k = 0
   End If
   l = l + 1
 Loop While (l <> reglen)
lastsum = (regsam + 1504) And 511  '16进制的5E0对应10进制的1504(这是定值),16进制的1FF对应10进制的511
 
  For i = 0 To 7
    B(i) = B(i) Xor A(i) Xor C(i) And 511
    strtmp = Mid(Hex(Abs(B(i) - lastsum)), 1, 2) '得出结果后,只取前面两位,不足两位前面用0补
    If Len(strtmp) = 1 Then
    strtmp = "0" + strtmp
    End If
    laststr = laststr + strtmp
    If i = 1 Or i = 3 Or i = 5 Then
    laststr = laststr + "-"
    End If
  Next i
Text2.Text = laststr
End If

End Sub

7、注册信息保存在注册表:
[HKEY_CURRENT_USER\Software\VB and VBA Program Settings\daatools\sysstring]
"0"="newlaos[CCG][DFCG]"
"1"="CD0D-E5B9-AC98-7512"