《飛天餐飲娛樂管理系統》註冊碼演算法分析以及暴力破解

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

《飛天餐飲娛樂管理系統》的暴力破解法:

  1)在004A2A48處
    改:0F 85 8A 00 00 00 C7 05 74 2C 52 00 01 00 00 00
        ^^ ^^ ^^ ^^ ^^ ^^
    為:90 90 90 90 90 90

  2)在004A1B29處
    改:74 04 33 C0 EB 0A 42 40 49 75 F1
        ^^
    為:EB

    然後,隨便用你的姓名和足夠長的Code註冊,註冊完以後關閉程式,重新執行你就可以看到結果了。


【演算法程式碼分析】
    此軟體的註冊碼演算法很複雜(真的不知道有沒有弄懂的必要,呵呵)。
    假設姓名為Name 簡稱 N 字串;註冊碼為Code 簡稱 C 字串;另外此演算法還根據C得到了一個 KEY 簡稱 K 字串。
    令C' = Fc(C) ―― 其中 Fc()為函式其意義為:將字串 C 去掉 '-'後兩兩合併,例如:1234-56789012-3456 合
併成 12 34 56 78 90 12 34 56(16進位制)共八個位元組。又如:1a2b-3c4d5e6f-7g8h 合併成:1a 2b 3c 4d 5e 6f 7g 8h 。
這個函式是004A1AE3處的call 004A187C 。
:004A1AD0 55                      push ebp
:004A1AD1 8BEC                    mov ebp, esp
:004A1AD3 83C4F0                  add esp, FFFFFFF0
:004A1AD6 53                      push ebx
:004A1AD7 56                      push esi
:004A1AD8 57                      push edi
:004A1AD9 8BD9                    mov ebx, ecx
:004A1ADB 8BF8                    mov edi, eax
:004A1ADD 8B7508                  mov esi, dword ptr [ebp+08]
:004A1AE0 8D45F0                  lea eax, dword ptr [ebp-10]
:004A1AE3 E894FDFFFF              call 004A187C <-- Fc()函式,在這裡下中斷,用do "d eax; p;"可以看到C'字串
:004A1AE8 85C0                    test eax, eax
:004A1AEA 7504                    jne 004A1AF0
:004A1AEC 33C0                    xor eax, eax
:004A1AEE EB49                    jmp 004A1B39

    令K = Fk(C') = Fk(Fc(C)) ―― 其中Fk()的定義如下面程式碼段:
:004A1AF0 8BC6                    mov eax, esi
:004A1AF2 8D55F0                  lea edx, dword ptr [ebp-10]
:004A1AF5 E806FDFFFF              call 004A1800  <-- 這個Call是根據C'得到一個Key,簡稱K字串
  <-- 具體的定義為:將Fc(C)後面的4個位元組的值分別*4+xxxx(xxxx表示0x0004, 0x0404, 0x0804, 0x0C04),將得到的值
      從一個長度為1000H的表中查詢出值進行加和xor運算,得到的值作為入口引數再進行運算,共迴圈0x10次。程式碼如:
        :004A14A6 C645F7F0                mov [ebp-09], F0
        :004A14AA 8D75F0                  lea esi, dword ptr [ebp-10]
        :004A14AD 331E                    xor ebx, dword ptr [esi]
        :004A14AF 8D95ACEFFFFF            lea edx, dword ptr [ebp+FFFFEFAC]
        :004A14B5 8BC3                    mov eax, ebx
        :004A14B7 E8D4FEFFFF              call 004A1390  <-- 運算在這個Call中執行
        :004A14BC 33F8                    xor edi, eax
        :004A14BE 8BC3                    mov eax, ebx
        :004A14C0 8BDF                    mov ebx, edi
        :004A14C2 8BF8                    mov edi, eax
        :004A14C4 83EE04                  sub esi, 00000004
        :004A14C7 FE45F7                  inc [ebp-09]
        :004A14CA 75E1                    jne 004A14AD
  <-- Call 004A1390的程式碼為:
          :004A1390 56                      push esi
          :004A1391 57                      push edi
          :004A1392 81C404F0FFFF            add esp, FFFFF004
          :004A1398 50                      push eax
          :004A1399 83C4FC                  add esp, FFFFFFFC
          :004A139C 8BF2                    mov esi, edx
          :004A139E 8D7C2404                lea edi, dword ptr [esp+04]
          :004A13A2 B900040000              mov ecx, 00000400
          :004A13A7 F3                      repz
          :004A13A8 A5                      movsd
          :004A13A9 890424                  mov dword ptr [esp], eax
          :004A13AC 8BC4                    mov eax, esp
          :004A13AE 33D2                    xor edx, edx
          :004A13B0 8A5003                  mov dl, byte ptr [eax+03]
          :004A13B3 8B549404                mov edx, dword ptr [esp+4*edx+04]
          :004A13B7 33C9                    xor ecx, ecx
          :004A13B9 8A4802                  mov cl, byte ptr [eax+02]
          :004A13BC 03948C04040000          add edx, dword ptr [esp+4*ecx+00000404]
          :004A13C3 33C9                    xor ecx, ecx
          :004A13C5 8A4801                  mov cl, byte ptr [eax+01]
          :004A13C8 33948C04080000          xor edx, dword ptr [esp+4*ecx+00000804]
          :004A13CF 0FB600                  movzx eax, byte ptr [eax]
          :004A13D2 039484040C0000          add edx, dword ptr [esp+4*eax+00000C04]
          :004A13D9 8BC2                    mov eax, edx
          :004A13DB 81C404100000            add esp, 00001004
          :004A13E1 5F                      pop edi
          :004A13E2 5E                      pop esi
          :004A13E3 C3                      ret
  <--------------------------------------------------------------------------------------------

:004A1AFA 8903                    mov dword ptr [ebx], eax
:004A1AFC 8B06                    mov eax, dword ptr [esi]

    下面的一個Call是計算另一個字串的,假定為C'',共分三步走:第一步:計算出N'=Fn(N);第二步:然後將N'的前3個字元
用K字串的前三個字元代替,假定為N''=F3(K, N')=F3(Fk(C'), N')=F3(Fk(Fc(C)), Fn(N));第三步:將得到的N''字串按照
Fk()類似的方法透過一定量的Add和xor運算後(也是呼叫了Call 004A1390,只是不同的輸入引數,哪怕是1bit的不同也會得到一個
完全不同的新字串,痛苦),得到C'',可以令C''=F(N''),那麼如果C'==C'',那麼,一切就是OK。嘿嘿
:004A1AFE 50                      push eax
:004A1AFF 8B0B                    mov ecx, dword ptr [ebx]
:004A1B01 8D45F8                  lea eax, dword ptr [ebp-08]
:004A1B04 8BD7                    mov edx, edi
:004A1B06 E845FBFFFF              call 004A1650 <-- 這個Call是根據N和K字串得到一個新的字串C''=F0(N, K)
:004A1B0B 85C0                    test eax, eax
:004A1B0D 7504                    jne 004A1B13
:004A1B0F 33C0                    xor eax, eax
:004A1B11 EB26                    jmp 004A1B39
:004A1B13 8B0DC0F15100            mov ecx, dword ptr [0051F1C0]
:004A1B19 49                      dec ecx
:004A1B1A 85C9                    test ecx, ecx
:004A1B1C 7C16                    jl 004A1B34
:004A1B1E 41                      inc ecx
:004A1B1F 8D45F8                  lea eax, dword ptr [ebp-08]
:004A1B22 8D55F0                  lea edx, dword ptr [ebp-10]

:004A1B25 8A18                    mov bl, byte ptr [eax]    |
:004A1B27 3A1A                    cmp bl, byte ptr [edx]    |
:004A1B29 EB04                    jmp 004A1B2F              |不用看就知道是在比較兩個運算好的
:004A1B2B 33C0                    xor eax, eax              |新的字串,其實就是我上面提到的
:004A1B2D EB0A                    jmp 004A1B39              |那個C' 和 C''。相等就是了
:004A1B2F 42                      inc edx                  |
:004A1B30 40                      inc eax                  |
:004A1B31 49                      dec ecx                  |
:004A1B32 75F1                    jne 004A1B25              |

:004A1B34 B801000000              mov eax, 00000001 <--關鍵就是要得到這個Eax=1;
:004A1B39 5F                      pop edi
:004A1B3A 5E                      pop esi
:004A1B3B 5B                      pop ebx
:004A1B3C 8BE5                    mov esp, ebp
:004A1B3E 5D                      pop ebp
:004A1B3F C20400                  ret 0004

最終你會得到一個表示式 C'==C'' 即 Fc(C)=F(N'')=F(F3(K, N'))=F(F3(Fk(Fc(C)), Fn(N))),那麼誰能告訴我如何根據這個表示式
用N求出C來?

相關文章