XnView1.68演算法分析(高手勿進)

看雪資料發表於2004-05-25

破解工具:OLLYDBG1.09d,PEID0.8
破解物件:XnView1.68
下載地址:http://www.skycn.com/soft/3110.html
軟體簡介:
支援多達 70 種格式的圖形瀏覽、轉換、編輯軟體, 還可製作 Slide Show。是否嫌ACDSEE太大功能太少?XNVIEW能很好地解決問題,他具有抓圖、編輯圖象、增加特效的功能,支援你所知道的所有格式及你不知道的格式(包括電影、MP3)。
破解說明:
    我真的需要這個軟體。前幾天買了數位相機,拍了些照片,想稍微修飾一下,順便作看圖軟體。本來想用ACDSEE,但剛好看到一篇文章說其功能強大,可代替ACDSEE,人怕出名豬怕壯,所以當然要用用它了。
破解過程:
    用PEID偵出用ASPACK加殼。是個弱殼,很容易脫,不過我不想脫它,檔案大了佔地方。
    執行XnView1.68,點註冊按鈕出現註冊框,執行OD,點ATTACH(附加)按鈕,選擇XnView程式,就可以用OD帶殼除錯它了。
    隨便填入註冊資訊,確定後彈出非法註冊的警告,於是在OD中下斷點:bp MessageBoxA(注意大小寫),再次註冊,OD攔截下來,按CTRL+F9執行到返回,當按警告框確定按鈕後OD再次攔下,F8返回到程式,到如下位置。
004696E7  CALL DWORD PTR DS:[541584]               ; USER32.MessageBoxA
004696ED  PUSH 7D0   --->返回到此,上面即是警告框
向上找找有沒有跳轉可跳過,發現如下程式碼:
004696A6  PUSH EDX
004696A7  PUSH EAX
004696A8  CALL xnview.0040B3C0         --->對NAME進行計算
004696AD  LEA ECX,DWORD PTR SS:[ESP+18]
004696B1  PUSH ECX
004696B2  CALL xnview.004734E3         --->將輸入碼轉化為十六進位制
004696B7  MOV ECX,DWORD PTR SS:[ESP+14]
004696BB  ADD ESP,0C
004696BE  CMP ECX,EAX                 --->比較
004696C0  JE SHORT xnview.0046971F    --->不跳則OVER
程式用十六進位制明碼比較,讓我們在40B3C0處下斷進去看看演算法。跟進後看到如下程式碼。
0040B3C0    MOV EDX,DWORD PTR SS:[ESP+4]
0040B3C4    PUSH EBX
0040B3C5    PUSH EBP
0040B3C6    PUSH ESI
0040B3C7    PUSH EDI
0040B3C8    MOV EDI,EDX
0040B3CA    OR ECX,FFFFFFFF
0040B3CD    XOR EAX,EAX
0040B3CF    REPNE SCAS BYTE PTR ES:[EDI]
0040B3D1    NOT ECX
0040B3D3    DEC ECX
0040B3D4    MOV ESI,xnview.0056B798
0040B3D9    MOV EBP,ECX
0040B3DB    MOV ECX,5
0040B3E0    MOV EDI,xnview.0058BA08
0040B3E5    REP MOVS DWORD PTR ES:[EDI],DWORD PTR>; 複製表的內容
0040B3E7    MOV ESI,EAX
0040B3E9    JE SHORT xnview.0040B40C
0040B3EB    MOV CL,BYTE PTR DS:[ESI+EDX]          ; 逐字取出NAME
0040B3EE    MOV BL,CL
0040B3F0    XOR BL,BYTE PTR DS:[EAX+58BA08]       ; 與查表結果(1~5位元組)進行XOR運算
0040B3F6    INC EAX
0040B3F7    CMP EAX,5                             ; 將迴圈5次
0040B3FA    MOV BYTE PTR DS:[ESI+EDX],BL          ; 結果儲存
0040B3FD    MOV BYTE PTR DS:[EAX+58BA07],CL       ; 用NAME覆蓋表中內容
0040B403    JNZ SHORT xnview.0040B407
0040B405    XOR EAX,EAX                           ;若EAX=5則重0開始計數,即NAME長度大於5時表中內容會被迴圈覆蓋(5個一迴圈),下類似
0040B407    INC ESI
0040B408    CMP ESI,EBP
0040B40A    JB SHORT xnview.0040B3EB
0040B40C    XOR EDI,EDI
0040B40E    XOR ECX,ECX
0040B410    TEST EBP,EBP
0040B412    JBE SHORT xnview.0040B43A
0040B414    MOV BL,BYTE PTR DS:[EDI+58BA0D]       ; 繼續查表(6~10位元組)準備第二輪運算
0040B41A    MOV ESI,EBP
0040B41C    SUB ESI,ECX
0040B41E    DEC ESI
0040B41F    MOV AL,BYTE PTR DS:[ESI+EDX]          ; 從最後一位開始倒過來取第一輪運算的結果
0040B422    XOR BL,AL                             ; XOR計算
0040B424    INC EDI
0040B425    MOV BYTE PTR DS:[ESI+EDX],BL          ; 用第二輪結果覆蓋第一輪結果
0040B428    MOV BYTE PTR DS:[EDI+58BA0C],AL       ; 用第一輪結果覆蓋表內容
0040B42E    CMP EDI,5
0040B431    JNZ SHORT xnview.0040B435
0040B433    XOR EDI,EDI
0040B435    INC ECX
0040B436    CMP ECX,EBP
0040B438    JB SHORT xnview.0040B414
0040B43A    XOR ESI,ESI
0040B43C    XOR EDI,EDI
0040B43E    TEST EBP,EBP
0040B440    JBE SHORT xnview.0040B463
0040B442    MOV AL,BYTE PTR DS:[EDI+EDX]          ; 取第二輪計算結果準備進行第三次運算
0040B445    MOV CL,BYTE PTR DS:[ESI+58BA12]       ; 繼續查表(11~15位元組)
0040B44B    XOR CL,AL                             ; XOR計算
0040B44D    INC ESI
0040B44E    MOV BYTE PTR DS:[EDI+EDX],CL          ; 用第三輪結果覆蓋第二輪結果
0040B451    MOV BYTE PTR DS:[ESI+58BA11],AL       ; 第二輪結果覆蓋表內容
0040B457    CMP ESI,5
0040B45A    JNZ SHORT xnview.0040B45E
0040B45C    XOR ESI,ESI
0040B45E    INC EDI
0040B45F    CMP EDI,EBP
0040B461    JB SHORT xnview.0040B442
0040B463    XOR EDI,EDI
0040B465    XOR ECX,ECX
0040B467    TEST EBP,EBP
0040B469    JBE SHORT xnview.0040B491
0040B46B    MOV BL,BYTE PTR DS:[EDI+58BA17]       ; 查表(16~20位元組)準備第四輪計算
0040B471    MOV ESI,EBP
0040B473    SUB ESI,ECX
0040B475    DEC ESI
0040B476    MOV AL,BYTE PTR DS:[ESI+EDX]          ; 取第三輪結果倒過來進行第四輪計算結果計算
0040B479    XOR BL,AL
0040B47B    INC EDI
0040B47C    MOV BYTE PTR DS:[ESI+EDX],BL          ; 用第四輪結果覆蓋第三輪結果
0040B47F    MOV BYTE PTR DS:[EDI+58BA16],AL       ; 將第三輪結果覆蓋表中內容
0040B485    CMP EDI,5
0040B488    JNZ SHORT xnview.0040B48C
0040B48A    XOR EDI,EDI
0040B48C    INC ECX
0040B48D    CMP ECX,EBP
0040B48F    JB SHORT xnview.0040B46B
0040B491    MOV EDI,DWORD PTR SS:[ESP+18]
0040B495    XOR EAX,EAX
0040B497    TEST EBP,EBP
0040B499    MOV DWORD PTR DS:[EDI],0
0040B49F    JBE SHORT xnview.0040B4B8
0040B4A1    MOV ECX,EAX
0040B4A3    AND ECX,3                             ; 取位計數器,使其到第5次時又從0開始
0040B4A6    MOV BL,BYTE PTR DS:[ECX+EDI]          ; 取值,前4次為空,第5次從頭開始取,即取得第四輪結果首位
0040B4A9    LEA ESI,DWORD PTR DS:[ECX+EDI]        ; ESI為儲存註冊碼的地址
0040B4AC    MOV CL,BYTE PTR DS:[EAX+EDX]          ; 取第四輪計算結果,準備轉化為註冊碼
0040B4AF    ADD BL,CL                             ; 相加,前4位加0,第五次時首位與末位相加
0040B4B1    INC EAX
0040B4B2    CMP EAX,EBP
0040B4B4    MOV BYTE PTR DS:[ESI],BL              ; 結果儲存在[ESI]
0040B4B6    JB SHORT xnview.0040B4A1
0040B4B8    POP EDI
0040B4B9    POP ESI
0040B4BA    POP EBP
0040B4BB    POP EBX
0040B4BC    RETN

演算法小結:
NAME(i)為每個位元組,S(i)為表中內容
第一輪:
取表中1~5位元組分別與NAME(i)進行XOR計算,儲存在A(i)中
然後將S(i)用NAME(i)覆蓋,若NAME長度大於5,用第6位覆蓋第1位,依次類推
第二輪:
A(i)從最後一位開始分別與表中6~10位元組進行XOR計算,儲存在B(i)中
然後表6~10位用A(i)覆蓋,若NAME長度大於5,用第6位覆蓋第6位,依次類推
第三輪:
取表中11~15位元組分別與B(i)進行XOR計算,儲存在C(i)中
然後表11~15位用B(i)覆蓋,若NAME長度大於5,用第6位覆蓋第11位,依次類推
第四輪:
C(i)從最後一位開始分別與表中16~20位元組進行XOR計算,儲存在D(i)中
然後表16~20位用A(i)覆蓋,若NAME長度大於5,用第6位覆蓋第16位,依次類推
第五輪:
將D(i)組合為註冊碼:將D(i)四個一組,得到一個四位元組的結果,儲存在E(i)中。如:
E(1)=D(1)+D(5)+D(9)+....得到一個位元組,依次類推。
然後將E(1)~E(4)反向讀取得到一個十六進位制結果,如AABBCCDD反向為DDCCBBAA,即為最終註冊碼。


表中內容為: &HAA &H89 &HC4 &HFE &H46 &H78 &HF0 &HD0 &H03 &HE7 
             &HF7 &HFD &HF4 &HE7 &HB9 &HB5 &H1B &HC9 &H50 &H73, 共20位元組

用VB可做成序號產生器:
Dim A(), C()

Private Sub Text1_Change()
   t = Text1.Text: ln = Len(t)
   B = Array(0, &HAA, &H89, &HC4, &HFE, &H46, &H78, &HF0, &HD0, &H3, &HE7, _
             &HF7, &HFD, &HF4, &HE7, &HB9, &HB5, &H1B, &HC9, &H50, &H73)
   ReDim A(ln)
      For i = 1 To ln
         k = (i - 1) Mod 5 + 1
         A(i) = Asc(Mid(t, i, 1))
         R = A(i) Xor B(k): B(k) = A(i): A(i) = R
         If A(i) >= 256 Then A(i) = A(i) - 256
      Next
      Text2.Text = A(ln)
      j = ln
      For i = 1 To ln
         k = (i - 1) Mod 5 + 1 + 5
         R = A(j) Xor B(k): B(k) = A(j): A(j) = R
         If A(j) >= 256 Then A(j) = A(j) - 256
         j = j - 1
      Next
      j = 1
      For i = 1 To ln
         k = (i - 1) Mod 5 + 1 + 10
         R = A(j) Xor B(k): B(k) = A(j): A(j) = R
         If A(j) >= 256 Then A(j) = A(j) - 256
         j = j + 1
      Next
      j = ln
      For i = 1 To ln
         k = (i - 1) Mod 5 + 1 + 15
         R = A(j) Xor B(k): B(k) = A(j): A(j) = R
         If A(j) >= 256 Then A(j) = A(j) - 256
         j = j - 1
      Next
      ReDim C(1 To 4)
      For i = 1 To ln
         k = (i - 1) Mod 4 + 1
         C(k) = C(k) + A(i)
         If C(k) >= 256 Then C(k) = C(k) - 256
      Next
      Text2.Text = C(4) * 256 * 256 * 256 + _
                   C(3) * 256 * 256 + C(2) * 256 + C(1)
End Sub

相關文章