mIRC v5.81版註冊碼演算法分析和序號產生器編寫

看雪資料發表於2000-12-11

mIRC v5.81版註冊碼演算法分析和序號產生器編寫

軟體名稱:mIRC v5.81
下載網址:http://soft.hn.cninfo.net/
除錯工具:SoftICE 4.05
除錯平臺:Win2K、W32dsm89

    作者:chn-boy
    日期:2000-12-11

    先用W32dsm89進行靜態分析,查詢字串“”,然後上下察看,發現在地址0049D875處有點問題,記下這個地址。下回在mIRC領空時
下中斷:bpx 0049D875,從新再進行註冊,程式攔斷在0049D875處:

:0049D861 E8D89B0800              Call 0052743E
:0049D866 68D33B5400              push 00543BD3
:0049D86B 68EC375400              push 005437EC
:0049D870 E850FBFFFF              call 0049D3C5  <-- 註冊碼的計算Call,跟蹤進去詳細看看。程式執行到此,d *esp和d esp->4
                                                      你可以看到你輸入的Name和Code。
:0049D875 85C0                    test eax, eax  <-- 第一次攔斷在此,如果EAX=1,則註冊成功
:0049D877 0F84B0000000            je 0049D92D
:0049D87D BED41F5300              mov esi, 00531FD4
:0049D882 BFEC375400              mov edi, 005437EC
:0049D887 33C0                    xor eax, eax


將0049D870處的Call 0049D3C5程式碼取出片斷如下:
:0049D41D 68044B5500              push 00554B04 <-- 你輸入的Code
:0049D422 68004A5500              push 00554A00 <-- 你輸入的Name
:0049D427 E8A6FEFFFF              call 0049D2D2 <-- 將你輸入的Code和Name分別進行運算,然後進行比較,如果相等,則EAX=1。
:0049D42C 85C0                    test eax, eax
:0049D42E 7407                    je 0049D437
:0049D430 B801000000              mov eax, 00000001  <-- 將 EAX 置 1,也是註冊成功的標誌
:0049D435 EB74                    jmp 0049D4AB     

將0049D427處的Call 0049D2D2程式碼取出片斷如下:
:0049D2F3 6A2D                    push 0000002D  <-- 字元'-'
:0049D2F5 56                      push esi      <-- Code字串的offset
:0049D2F6 E841B00700              call 0051833C  <-- 得出Code字串中'-'的位置,值返回到EAX中
:0049D2FB 83C408                  add esp, 00000008
:0049D2FE 8BD8                    mov ebx, eax
:0049D300 85DB                    test ebx, ebx
:0049D302 7507                    jne 0049D30B
:0049D304 33C0                    xor eax, eax
:0049D306 E9B1000000              jmp 0049D3BC
:0049D30B C60300                  mov byte ptr [ebx], 00  <-- 將Code字串中的'-'字元置為0x00
:0049D30E 56                      push esi                <-- Code字串的offset
:0049D30F E848440800              call 0052175C          <-- 算出第一部分的值,比如:'781', 最後得到0x030D=781
                                                          <-- 將值返回到EAX中
:0049D314 59                      pop ecx
:0049D315 8945FC                  mov dword ptr [ebp-04], eax
:0049D318 C6032D                  mov byte ptr [ebx], 2D  <-- 將以前轉換的'-'恢復
:0049D31B 43                      inc ebx               
:0049D31C 803B00                  cmp byte ptr [ebx], 00  |
:0049D31F 7507                    jne 0049D328            |看看第二部分是否存在,若否,則跳到註冊不成功的地方
:0049D321 33C0                    xor eax, eax            |
:0049D323 E994000000              jmp 0049D3BC            |

:0049D328 53                      push ebx
:0049D329 E82E440800              call 0052175C          <-- 得到第二部分的值
:0049D32E 59                      pop ecx
:0049D32F 8945F8                  mov dword ptr [ebp-08], eax
:0049D332 FF7508                  push [ebp+08]
:0049D335 E8A2B00700              call 005183DC
:0049D33A 59                      pop ecx
:0049D33B 8945F4                  mov dword ptr [ebp-0C], eax
:0049D33E 33C0                    xor eax, eax
:0049D340 33DB                    xor ebx, ebx
:0049D342 BA03000000              mov edx, 00000003
:0049D347 8B4D08                  mov ecx, dword ptr [ebp+08]    <-- 將Name字串的長度值給ECX
:0049D34A 83C103                  add ecx, 00000003              <-- Name從第3+1=4個字元開始處理
:0049D34D 3B55F4                  cmp edx, dword ptr [ebp-0C]
:0049D350 7D1C                    jge 0049D36E                  <-- 如果Name長度少於等於3,則註冊不成功

:0049D352 0FB631                  movzx esi, byte ptr [ecx]            |
:0049D355 0FAF3485341F5300        imul esi, dword ptr [4*eax+00531F34]  |
:0049D35D 03DE                    add ebx, esi                          |
:0049D35F 40                      inc eax                              |從Name的第4個字元開始,分別用值*對應
:0049D360 83F826                  cmp eax, 00000026 (Name長度要少於0x29)|的一個固定字串(演算法分析中給出),
:0049D363 7E02                    jle 0049D367                          |並求和,將和總值給EBX,用d 0053F34你
:0049D365 33C0                    xor eax, eax                          |可以看到這個固定的字串。
:0049D367 42                      inc edx                              |
:0049D368 41                      inc ecx                              |
:0049D369 3B55F4                  cmp edx, dword ptr [ebp-0C]          |
:0049D36C 7CE4                    jl 0049D352                          |
:0049D36E 3B5DFC                  cmp ebx, dword ptr [ebp-04]          <-- 比較EBX和前面算出的那個第一部分是否相等
:0049D371 7404                    je 0049D377
:0049D373 33C0                    xor eax, eax                          <-- 不等,則註冊不成功
:0049D375 EB45                    jmp 0049D3BC
:0049D377 33C0                    xor eax, eax
:0049D379 33DB                    xor ebx, ebx
:0049D37B BA03000000              mov edx, 00000003
:0049D380 8B4D08                  mov ecx, dword ptr [ebp+08]
:0049D383 83C103                  add ecx, 00000003
:0049D386 3B55F4                  cmp edx, dword ptr [ebp-0C]
:0049D389 7D23                    jge 0049D3AE
:0049D38B 0FB631                  movzx esi, byte ptr [ecx]            |
:0049D38E 0FB679FF                movzx edi, byte ptr [ecx-01]          |
:0049D392 0FAFF7                  imul esi, edi                        |
:0049D395 0FAF3485341F5300        imul esi, dword ptr [4*eax+00531F34]  |
:0049D39D 03DE                    add ebx, esi                          |從Name的第4個字元開始,分別用值*前一個字元
:0049D39F 40                      inc eax                              |得值*固定字串對應值,求和後將值存放到EBX
:0049D3A0 83F826                  cmp eax, 00000026                    |
:0049D3A3 7E02                    jle 0049D3A7                          |
:0049D3A5 33C0                    xor eax, eax                          |
:0049D3A7 42                      inc edx                              |
:0049D3A8 41                      inc ecx                              |
:0049D3A9 3B55F4                  cmp edx, dword ptr [ebp-0C]          |
:0049D3AC 7CDD                    jl 0049D38B                          |
:0049D3AE 3B5DF8                  cmp ebx, dword ptr [ebp-08]          <-- 比較EBX和前面算出的那個第二部分是否相等
:0049D3B1 7404                    je 0049D3B7
:0049D3B3 33C0                    xor eax, eax                          <-- 不等,則註冊不成功
:0049D3B5 EB05                    jmp 0049D3BC
:0049D3B7 B801000000              mov eax, 00000001                    <-- 置EAX=1,註冊成功的標誌
:0049D3BC 5F                      pop edi
:0049D3BD 5E                      pop esi
:0049D3BE 5B                      pop ebx
:0049D3BF 8BE5                    mov esp, ebp
:0049D3C1 5D                      pop ebp
:0049D3C2 C20800                  ret 0008


【演算法分析】
    這個註冊碼演算法很簡單,形式就是:假定Name(簡稱N)和Code(簡稱C),令N'=Fn1(N), N''=Fn2(N), C'=Fc1(C), C''=Fc2(C),
如果能讓C'=N' && C''=N''那麼註冊成功。
    根據前面分析,固定字串為0B 06 11 0C 0C 0E 05 0C 10 0A 0B 06 0E 0E 04 0B 06 0E 0E 04 0B 09 0C 0B 0A 08 0A 0A ...
        N'=Fn1(N)的定義為:從Name第4個字元開始,分別用值*這個固定的字串,求出總和。
        N''=Fn2(N)的定義為:從Name第4個字元開始,分別用值*前一個字元值*這個固定的字串,求出總和。

    下面關鍵問題是得到C', C'',由上面的分析可以知道C'=N'=Fn1(N),C''=N''=Fn2(N),那麼:
        C=Fc1逆(C') + '-' + Fc2逆(C'') = Fc1逆(Fn1(N)) + '-' + Fc2逆(Fn2(N))
這個C是很好根據N來得到的。

    詳細的序號產生器請看下文。

相關文章