Advanced MP3WMA Recorder 3.7.3破解手記--完美演算法分析

看雪資料發表於2015-11-15

標 題:Advanced MP3WMA Recorder 3.7.3破解手記--完美演算法分析 

發信人: newlaos 

時 間:2003/04/15 02:59pm

詳細資訊: 




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"

相關文章