虛擬光碟機2000 V5.1 網路版21天評估版序列號的計算部分(半年多以前做的) (16千字)

看雪資料發表於2001-05-07

軟體名稱:Virtual Drive 2000 網路版
整理日期:2000.8.12
最新版本:5.1c
檔案大小:4824KB
軟體授權:共享軟體
使用平臺:Win95/98
釋出公司:http://www.farstone.com/
下載地址:http://www.newhua.com.cn/down/virtdnet.zip
軟體簡介:一個非常不錯WIN95/98下的CD-ROM模擬程式,可以把CD-ROM複製為硬碟的一個檔案,這個版本連CD音軌、保護都可以模擬,最多模擬出二十部光碟機。此版為多語言版,包括:中文版、英文版、和日文版,安裝時會自動檢測作業系統的語言版本並自動安裝。
破解工具:W32Dasm,exescope 6.0
說明:這是我將近一年前破解的軟體,當時由於工作需要,想找一個網路版的虛擬光碟機,找是找到了,但為評估版,上網搜尋也沒有找到關於網路版的完整破解,於是只好自力更生。在破解過程中,我還發現了在番外地裡介紹的修改setup.sys後試用版變正式版的過程,而且還發現,如果使用該網路版的是中國的使用者,則需要軟體狗,我全給他解了。這個軟體的全部破解過程很長,有50多K,這裡僅介紹註冊碼的計算過程。另外,網路版與單機版的序列號計算過程基本一樣,其中,網路版的序列號為15位,而單機版為11位,就差在最後4位數字,最後的4位數字表示的是允許使用的使用者數。
這個軟體可以自動判別作業系統的型別,根據作業系統的型別自動選擇用繁體、簡體、日語、法語、德語及英語來顯示安裝介面,雖然這給使用者的使用上簡便了,但用pwdasm反彙編時,卻出現了很多一些看不懂的字串――因為預設是顯示繁體中文,雖然不影響程式流程,但這給破解造成了麻煩,為了更好地破解這個軟體,我對該軟體做一下處理,讓w32dasm能夠識別字串,方法是用exescope對程式進行處理,將繁體中文和簡體中文均改為英文字元顯示,嘿嘿,本來用作漢化的常用工具,反其道而行之,可以稱為反漢化,反漢化的相應字串提示不用擔心,軟體公司已經給做好了,用exescope改好後,用w32dasm進行反彙編,竟取得了很好的效果,這回,w32dasm將字元全部顯示出來了,當然是英文的,現在我們開始破解吧。
目標程式:SerSetup.exe,大小331776 Bytes
執行SerSetup.exe,安裝程式要求輸入公司名稱和序列號等,下面為序列號的計算部分的流程

* Referenced by a CALL at Address:
|:00401F5C 
|
:00402890 64A100000000            mov eax, dword ptr fs:[00000000]
:00402896 6AFF                    push FFFFFFFF
:00402898 68F8834100              push 004183F8
:0040289D 50                      push eax
:0040289E 64892500000000          mov dword ptr fs:[00000000], esp
:004028A5 81EC00010000            sub esp, 00000100
:004028AB 53                      push ebx
:004028AC 55                      push ebp
:004028AD 56                      push esi
:004028AE 57                      push edi
:004028AF 8BD9                    mov ebx, ecx
:004028B1 8BBC2420010000          mov edi, dword ptr [esp+00000120]    ====> 指向註冊碼
:004028B8 83CDFF                  or ebp, FFFFFFFF
:004028BB 8BCD                    mov ecx, ebp
:004028BD 33C0                    xor eax, eax
:004028BF F2                      repnz
:004028C0 AE                      scasb          ====> 檢測註冊碼的字串長度
:004028C1 F7D1                    not ecx
:004028C3 2BF9                    sub edi, ecx
:004028C5 8D542410                lea edx, dword ptr [esp+10]
:004028C9 8BC1                    mov eax, ecx
:004028CB 8BF7                    mov esi, edi
:004028CD 8BFA                    mov edi, edx
:004028CF C1E902                  shr ecx, 02
:004028D2 F3                      repz
:004028D3 A5                      movsd            ====> 將註冊碼中的字串送入[esp+10],為後面計算做準備
:004028D4 8BC8                    mov ecx, eax
:004028D6 33C0                    xor eax, eax
:004028D8 83E103                  and ecx, 00000003
:004028DB F3                      repz
:004028DC A4                      movsb
:004028DD 8D7C2410                lea edi, dword ptr [esp+10]
:004028E1 8BCD                    mov ecx, ebp
:004028E3 F2                      repnz
:004028E4 AE                      scasb              ====> 再次檢測新的字串長度
:004028E5 F7D1                    not ecx
:004028E7 49                      dec ecx
:004028E8 83F90F                  cmp ecx, 0000000F  ====> 字串長度是否為15個
:004028EB 7515                    jne 00402902        ====> 不是,則序列號錯誤
:004028ED 8D4C2410                lea ecx, dword ptr [esp+10]
:004028F1 8844241B                mov byte ptr [esp+1B], al    ====> [esp+1B]處置0,對註冊碼進行擷取到11位,為後面的計算做準備
:004028F5 51                      push ecx
:004028F6 E8B5EFFFFF              call 004018B0                ====> 關鍵的CALL
:004028FB 83C404                  add esp, 00000004
:004028FE 85C0                    test eax, eax                ====> EAX作為旗標
:00402900 751A                    jne 0040291C                ====> 如果EAX=0則序列號錯誤

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:004028EB(C), :0040294D(C), :00402953(C)
|
:00402902 8D8C2420010000          lea ecx, dword ptr [esp+00000120]
:00402909 89AC2418010000          mov dword ptr [esp+00000118], ebp
:00402910 E81EDB0000              call 00410433
:00402915 33C0                    xor eax, eax    ====> 失敗旗標
:00402917 E9B1000000              jmp 004029CD

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00402900(C)
|
:0040291C 8BBC2420010000          mov edi, dword ptr [esp+00000120]    ====> 指向原始的字串
:00402923 8BCD                    mov ecx, ebp
:00402925 33C0                    xor eax, eax
:00402927 8D542410                lea edx, dword ptr [esp+10]          ====> 指向剛才合成的字串
:0040292B F2                      repnz
:0040292C AE                      scasb
:0040292D F7D1                    not ecx
:0040292F 2BF9                    sub edi, ecx
:00402931 8BC1                    mov eax, ecx
:00402933 8BF7                    mov esi, edi
:00402935 8BFA                    mov edi, edx
:00402937 B230                    mov dl, 30
:00402939 C1E902                  shr ecx, 02
:0040293C F3                      repz
:0040293D A5                      movsd                                ====> 向[ESP+10]處複製"0"
:0040293E 8BC8                    mov ecx, eax
:00402940 83E103                  and ecx, 00000003
:00402943 F3                      repz
:00402944 A4                      movsb
:00402945 33C9                    xor ecx, ecx

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040295F(C)
|
:00402947 8A440C1B                mov al, byte ptr [esp+ecx+1B]        ====> 將最後的4個數字分別置入al中
:0040294B 3C39                    cmp al, 39                          ====> 是否大於"9"
:0040294D 7FB3                    jg 00402902                          ====> 大於則完蛋
:0040294F 38540C10                cmp byte ptr [esp+ecx+10], dl        ====> 註冊碼的第1加ecx位字元是否小於"0"
:00402953 7CAD                    jl 00402902                          ====> 小於則完蛋
:00402955 2AC2                    sub al, dl                          ====> 將最後的4個數字的ascii取"0"改為相應的機器碼
:00402957 88440C1B                mov byte ptr [esp+ecx+1B], al        ====> 結果送回[esp+ecx+1B]中
:0040295B 41                      inc ecx                              ====> +1
:0040295C 83F904                  cmp ecx, 00000004                    ====> 是否轉換了4個
:0040295F 7CE6                    jl 00402947                          ====> 不是則繼續
:00402961 0FBE4C241B              movsx ecx, byte ptr [esp+1B]      \
:00402966 0FBE44241E              movsx eax, byte ptr [esp+1E]      \ ====> 將剛才的結果分別送入這四個中
:0040296B 0FBE7C241C              movsx edi, byte ptr [esp+1C]      /
:00402970 0FBE74241D              movsx esi, byte ptr [esp+1D]      /
:00402975 03C1                    add eax, ecx                        ====> 累加起來
:00402977 BD0A000000              mov ebp, 0000000A
:0040297C 03C7                    add eax, edi
:0040297E 03C6                    add eax, esi
:00402980 99                      cdq                                  ====> mod 0Ah
:00402981 F7FD                    idiv ebp
:00402983 85D2                    test edx, edx                        ====> 餘數是否為0
:00402985 741B                    je 004029A2                          ====> 是,則走,否則等死吧
:00402987 8D8C2420010000          lea ecx, dword ptr [esp+00000120]
:0040298E C7842418010000FFFFFFFF  mov dword ptr [esp+00000118], FFFFFFFF
:00402999 E895DA0000              call 00410433
:0040299E 33C0                    xor eax, eax                        ====> 置失敗標誌
:004029A0 EB2B                    jmp 004029CD

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00402985(C)
|
:004029A2 8D0C89                  lea ecx, dword ptr [ecx+4*ecx]            ====> 第12位數字乘以5
:004029A5 C7842418010000FFFFFFFF  mov dword ptr [esp+00000118], FFFFFFFF    ====> 這也應該是與setup.sys某個特殊標誌
:004029B0 8D044F                  lea eax, dword ptr [edi+2*ecx]            ====> 再乘以2加上第13位數字
:004029B3 8D8C2420010000          lea ecx, dword ptr [esp+00000120]
:004029BA 8D1480                  lea edx, dword ptr [eax+4*eax]            ====> 再乘以5
:004029BD 8D0456                  lea eax, dword ptr [esi+2*edx]            ====> 再乘以2加上第14位數字
:004029C0 894360                  mov dword ptr [ebx+60], eax              ====> 結果放到[ebx+60]中,應該也是在setup.sys中,經試驗發現,最後4位數字表示授權使用的人數
:004029C3 E86BDA0000              call 00410433
:004029C8 B801000000              mov eax, 00000001                        ====> 置成功標誌

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00402917(U), :004029A0(U)
|
:004029CD 8B8C2410010000          mov ecx, dword ptr [esp+00000110]
:004029D4 5F                      pop edi
:004029D5 5E                      pop esi
:004029D6 5D                      pop ebp
:004029D7 5B                      pop ebx
:004029D8 64890D00000000          mov dword ptr fs:[00000000], ecx
:004029DF 81C40C010000            add esp, 0000010C
:004029E5 C20400                  ret 0004


* Referenced by a CALL at Address:
|:004028F6 
|
:004018B0 81EC00010000            sub esp, 00000100
:004018B6 83C9FF                  or ecx, FFFFFFFF
:004018B9 33C0                    xor eax, eax
:004018BB 53                      push ebx
:004018BC 8B9C2408010000          mov ebx, dword ptr [esp+00000108]
:004018C3 55                      push ebp
:004018C4 56                      push esi
:004018C5 57                      push edi
:004018C6 8BFB                    mov edi, ebx        ====> [esp+00000108]指向輸入的註冊碼
:004018C8 F2                      repnz              ====> 檢測註冊碼的字串長度
:004018C9 AE                      scasb
:004018CA F7D1                    not ecx
:004018CC 49                      dec ecx
:004018CD 8BFB                    mov edi, ebx
:004018CF 8BD1                    mov edx, ecx        ====> edx為字串長度
:004018D1 83C9FF                  or ecx, FFFFFFFF
:004018D4 F2                      repnz
:004018D5 AE                      scasb
:004018D6 F7D1                    not ecx
:004018D8 2BF9                    sub edi, ecx
:004018DA 8D6C2410                lea ebp, dword ptr [esp+10]
:004018DE 8BC1                    mov eax, ecx
:004018E0 8BF7                    mov esi, edi
:004018E2 8BFD                    mov edi, ebp
:004018E4 C1E902                  shr ecx, 02
:004018E7 F3                      repz
:004018E8 A5                      movsd
:004018E9 8BC8                    mov ecx, eax
:004018EB 83E103                  and ecx, 00000003
:004018EE 83FA0B                  cmp edx, 0000000B        ====> 比較字串長度是否為11
:004018F1 F3                      repz
:004018F2 A4                      movsb
:004018F3 0F85A5000000            jne 0040199E              ====> 不相等,那麼就等死吧
:004018F9 B803000000              mov eax, 00000003

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00401922(C)
|
:004018FE 8A0C18                  mov cl, byte ptr [eax+ebx]    \
:00401901 80F939                  cmp cl, 39                    \
:00401904 0F8794000000            ja 0040199E                    |
:0040190A 80F930                  cmp cl, 30                      |
:0040190D 0F828B000000            jb 0040199E                    |
:00401913 8A4C0410                mov cl, byte ptr [esp+eax+10]  | ====> 是否為數字,如果是,則轉換為機器碼數字,否則完蛋
:00401917 80C1D0                  add cl, D0                      |
:0040191A 884C0410                mov byte ptr [esp+eax+10], cl  |
:0040191E 40                      inc eax                        |
:0040191F 83F80B                  cmp eax, 0000000B              /
:00401922 7CDA                    jl 004018FE                  /
:00401924 8B4C2418                mov ecx, dword ptr [esp+18]      ====> 第9位數字置入ecx
:00401928 81E1FF000000            and ecx, 000000FF
:0040192E 41                      inc ecx                          ====> +1
:0040192F 8BC1                    mov eax, ecx
:00401931 C1E005                  shl eax, 05                      ====> 乘以32
:00401934 2BC1                    sub eax, ecx                    ====> 減去原數,相當於乘以31
:00401936 8B4C241A                mov ecx, dword ptr [esp+1A]      ====> 第11位數字置入ecx
:0040193A 81E1FF000000            and ecx, 000000FF
:00401940 8BD1                    mov edx, ecx
:00401942 C1E204                  shl edx, 04                      ====> 乘以16
:00401945 03D1                    add edx, ecx                    ====> 加上原數,相當於乘以17
:00401947 8B4C2419                mov ecx, dword ptr [esp+19]      ====> 第10位數字置入ecx
:0040194B 81E1FF000000            and ecx, 000000FF
:00401951 03C2                    add eax, edx                    ====> 加入到eax中
:00401953 8D1449                  lea edx, dword ptr [ecx+2*ecx]
:00401956 C1E203                  shl edx, 03
:00401959 2BD1                    sub edx, ecx                    ====> 乘以7
:0040195B B963000000              mov ecx, 00000063
:00401960 03C2                    add eax, edx                    ====> 加入到eax中,這樣我們可以算出,eax的值=([esp+18]+1)*31+[esp+1A]*17+[esp+19]*7
:00401962 99                      cdq
:00401963 F7F9                    idiv ecx                        ====> mod 63h,十進位制為99
:00401965 8B442413                mov eax, dword ptr [esp+13]      ====> 將第4位數字置入eax中
:00401969 8B4C2414                mov ecx, dword ptr [esp+14]      ====> 將第5位數字置入ecx中
:0040196D 25FF000000              and eax, 000000FF
:00401972 81E1FF000000            and ecx, 000000FF
:00401978 8D0480                  lea eax, dword ptr [eax+4*eax]  ====> 第4位數字乘以5
:0040197B 8D0441                  lea eax, dword ptr [ecx+2*eax]  ====> 得到的結果乘以2再加上第5位數字的值
:0040197E 3BC2                    cmp eax, edx                    ====> 餘數是否等於eax的值
:00401980 751C                    jne 0040199E                    ====> 不等,註冊碼錯誤
:00401982 8A442412                mov al, byte ptr [esp+12]
:00401986 3C58                    cmp al, 58                      ====> 序列號中的第3個字母是否為X
:00401988 7404                    je 0040198E
:0040198A 3C78                    cmp al, 78                      ====> 或者x
:0040198C 7510                    jne 0040199E                    ====> 二者都不等,去死吧

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00401988(C)
|
:0040198E 5F                      pop edi
:0040198F 5E                      pop esi
:00401990 5D                      pop ebp
:00401991 B802000000              mov eax, 00000002
:00401996 5B                      pop ebx
:00401997 81C400010000            add esp, 00000100
:0040199D C3                      ret

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:004018F3(C), :00401904(C), :0040190D(C), :00401980(C), :0040198C(C)
|
:0040199E 5F                      pop edi
:0040199F 5E                      pop esi
:004019A0 5D                      pop ebp
:004019A1 33C0                    xor eax, eax
:004019A3 5B                      pop ebx
:004019A4 81C400010000            add esp, 00000100
:004019AA C3                      ret

從上面的程式中,我們可以知道網路版註冊碼的情況:
1. 註冊碼必須為15位(單機版前11位),第3個字元必須為x或X,從第4位開始,必須全是數字
2. 第1、2個字元必須大於等於"0"(即ascii中的30)
3. ((第9位數字+1)*31+第10位*7+第11位*17) mod 63h=第4位乘以10+第5位數字
4. 最後4位數字相加應等於10或者0,其中,前3個數字表示授權使用的人數
根據上面的結果我們可以給出一個註冊碼:FSX310000009993(網上常見的) 或 FSX000000045555,其他的自己去造吧

相關文章