IrfanView演算法淺析-第一次貼演算法文章,希望不會錯得太離譜!

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

IrfanView演算法淺析

【軟體簡介】:IrfanView是非常優秀的看圖工具,支援幾十種格式(需外掛)。它還能對不同檔案格式進行轉換,批次重新命名等。甚至還支援mpg、mp3、mid等多媒體格式的播放。絲毫不遜色於ACDSEE。
  

【聲    明】:剛學彙編不久,下面分析中難免有錯誤之處,敬請諸位大俠賜教!

【程 序 名】:i_view32.ExE
【版    本】:3.85
【大    小】:492KB
【語    言】:Visual C++
【執行平臺】:W9x/NT/W2K/WXP
【保護方式】:telock0.98加殼+註冊碼
【分析方式】:追註冊碼+序號產生器
【難    度】:容易(明碼比較)
【工    具】:PE-SCAN v3.31/WKTtElockDumper v1.2/W32dasm8.93+/TRW2000 v1.23
【程式下載】:http://www.irfanview.com

【作    者】:xbb_NCG

【分    析】:
      1、獲取資訊:安裝後執行程式,我們可以在程式的幫助裡看到註冊選項,單擊後知道僅需要使用者名稱和註冊碼兩條資訊。
      2、脫殼:用PE-SCAN v3.31檢測出該程式用telock0.98加殼。OK,我們用WKTtElockDumper v1.2(風飄雪的網站上有下載)脫掉它。  
      3、靜態分析:用W32Dasm8.93+反彙編脫殼後的程式。檢視字串,找不到有用的。
      4、動態跟蹤:執行TRW2000 v1.23,選擇脫殼後的程式,點選Load。按G,讓程式先執行。然後我們點 幫助>註冊 ,在彈出的註冊框中填入使用者名稱和註冊碼。我填的是xbb_NCG和123456789,先不在按確定。按CTRL+N撥出TRW,鍵入bpx hmemcpy,回車,鍵入G,回到程式,現在我們按確定,程式會被TRW中斷,輸入pmodule回到程式的領空,按2次f12,再輸入pmodule我們會在下面的程式碼入停住。
   
* Reference To: USER32.DialogBoxParamA, Ord:0093h
                                  |
:00455115 FF15F4844C00            Call dword ptr [004C84F4]
:0045511B 85C0                    test eaxeax  <-我們停在這裡,檢測使用者名稱和註冊碼是否為空。
:0045511D 0F84AD000000            je 004551D0  <-為零則跳
:00455123 8DBC245C050000          lea edidword ptr [esp+0000055C]  <-將使用者名稱讀入EDI
:0045512A 83C9FF                  or ecx, FFFFFFFF
:0045512D 33C0                    xor eaxeax                       <-EAX清零
:0045512F F2                      repnz  
:00455130 AE                      scasb                              <-掃描使用者名稱位數
:00455131 F7D1                    not ecx                            <-ECX取反
:00455133 49                      dec ecx                            <-ECX減1
:00455134 83F902                  cmp ecx, 00000002                  <-ECX的值和2比較
:00455137 0F825C010000            jb 00455299                        <-使用者名稱小於2位則跳
:0045513D 8DBC245C050000          lea edidword ptr [esp+0000055C]
:00455144 83C9FF                  or ecx, FFFFFFFF
:00455147 F2                      repnz
:00455148 AE                      scasb
:00455149 F7D1                    not ecx
:0045514B 49                      dec ecx
:0045514C 83F955                  cmp ecx, 00000055                  <-ECX的值和55比較
:0045514F 0F8744010000            ja 00455299                        <-使用者名稱大於55位則跳
:00455155 8DBC245C060000          lea edidword ptr [esp+0000065C]
:0045515C 83C9FF                  or ecx, FFFFFFFF
:0045515F 33D2                    xor edxedx                       <-EDX置0
:00455161 F2                      repnz
:00455162 AE                      scasb
:00455163 F7D1                    not ecx
:00455165 49                      dec ecx
:00455166 85C9                    test ecxecx                      <-檢測ECX是否為0.
:00455168 7E75                    jle 004551DF                       <-不小於0則跳到計算註冊碼Call

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00455192(C)
|
:0045516A 8A84145C060000          mov albyte ptr [esp+edx+0000065C]-----  <-取註冊碼的第一位
:00455171 3C30                    cmp al, 30     <-是否小於0                
:00455173 7C04                    jl 00455179                               
:00455175 3C39                    cmp al, 39     <-是否大於9                  
:00455177 7E05                    jle 0045517E                                
                                                                               
* Referenced by a (U)nconditional or (C)onditional Jump at Address:             
|:00455173(C)                                                                    |
|                                                                                |
                                                                                 |
* Possible Ref to Menu: IRFANVIEW, Item: "er(M)"                              |
                                  |                                              |
:00455179 BB01000000              mov ebx, 00000001  <-EBX置1                    |--這一段是將我們輸入的
                                                                                 |假註冊碼轉換為16進位制
* Referenced by a (U)nconditional or (C)onditional Jump at Address:              |
|:00455177(C)                                                                    |
|                                                                                |
:0045517E 8DBC245C060000          lea edidword ptr [esp+0000065C]              |
:00455185 83C9FF                  or ecx, FFFFFFFF                               |
:00455188 33C0                    xor eaxeax                                  /
:0045518A 42                      inc edx       <-迴圈記數器,EDX加1           /
:0045518B F2                      repnz                                       /
:0045518C AE                      scasb                                      /
:0045518D F7D1                    not ecx                                   /
:0045518F 49                      dec ecx       <-假註冊碼位數,ECX減1     /
:00455190 3BD1                    cmp edxecx  <-比較EDX和ECX的值        /
:00455192 7CD6                    jl 0045516A  __________________________/   <-迴圈記數小於註冊碼位數則跳
:00455194 85DB                    test ebxebx <-EBX是否為0?
:00455196 7447                    je 004551DF   <-為0就跳到註冊碼計算處。
:00455198 8B0D4C394F00            mov ecxdword ptr [004F394C]
:0045519E 6804010000              push 00000104
:004551A3 6860C84F00              push 004FC860

....................

***********************************

    我們由上面程式碼中的455192處跳來此處:
    
* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00455168(C), :00455196(C)
|
:004551DF 8D84245C060000          lea eaxdword ptr [esp+0000065C]  <-使用者名稱入EAX
:004551E6 8D8C245C050000          lea ecxdword ptr [esp+0000055C]  <-註冊碼入ECX
:004551ED 50                      push eax                           <-EAX入堆疊
:004551EE 51                      push ecx                           <-ECX入堆疊
:004551EF E8CC16FEFF              call 004368C0                      <-關鍵Call,計算註冊碼處,後面分析。
:004551F4 83C408                  add esp, 00000008                  <-在這裡D EAX可以見到真的註冊碼
:004551F7 85C0                    test eaxeax  
:004551F9 7533                    jne 0045522E                       <-不=0則跳,到註冊成功處。
:004551FB 8B154C394F00            mov edxdword ptr [004F394C]
:00455201 6804010000              push 00000104
:00455206 6860C84F00              push 004FC860

....................

:00455211 FF15A0834C00            Call dword ptr [004C83A0]
:00455217 A188CB4F00              mov eaxdword ptr [004FCB88]
:0045521C 6830200000              push 00002030
:00455221 6800DF4F00              push 004FDF00
:00455226 6860C84F00              push 004FC860
:0045522B 50                      push eax
:0045522C EB9C                    jmp 004551CA                       <-這裡跳到出錯提示

***********************************

4551EF處關鍵Call,我們進入。
* Referenced by a CALL at Addresses:
|:00436D8E   , :004550A4   , :004551EF   
|
:004368C0 8B442408                mov eaxdword ptr [esp+08]
:004368C4 83EC14                  sub esp, 00000014
:004368C7 53                      push ebx---
:004368C8 55                      push ebp    
:004368C9 56                      push esi     |--各寄存入棧
:004368CA 57                      push edi    /
:004368CB 50                      push eax___/
:004368CC 33DB                    xor ebxebx   <-EBX清零
:004368CE E82AFF0700              call 004B67FD  <-此Call將我們輸入的註冊碼即123456789轉為16進製為75BCD15
                                                   EDX=4ED99A 這個數在後的要用到。
:004368D3 8B74242C                mov esidword ptr [esp+2C]
:004368D7 8BE8                    mov ebpeax
:004368D9 8BFE                    mov ediesi
:004368DB 83C9FF                  or ecx, FFFFFFFF
:004368DE 33C0                    xor eaxeax
:004368E0 83C404                  add esp, 00000004
:004368E3 33D2                    xor edxedx
:004368E5 F2                      repnz
:004368E6 AE                      scasb
:004368E7 F7D1                    not ecx
:004368E9 49                      dec ecx
:004368EA 85C9                    test ecxecx
:004368EC 7E17                    jle 00436905

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00436903(C)
|
:004368EE 0FBE0C32                movsx ecxbyte ptr [edx+esi]-
:004368F2 03D9                    add ebxecx                   
:004368F4 8BFE                    mov ediesi                    
:004368F6 83C9FF                  or ecx, FFFFFFFF                 
:004368F9 33C0                    xor eaxeax                      |將使用者名稱的ASCII碼逐位相加,和放入EBX
:004368FB 42                      inc edx                           |
:004368FC F2                      repnz                            / 
:004368FD AE                      scasb                           /
:004368FE F7D1                    not ecx                        /
:00436900 49                      dec ecx                       /
:00436901 3BD1                    cmp edxecx                 /<-比較EDX和ECX的值
:00436903 7CE9                    jl 004368EE  _______________/ <-小於則跳

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004368EC(C)
|
:00436905 B804010000              mov eax, 00000104                    <-104放入EAX

* Possible Reference to Dialog: DialogID_0402, CONTROL_ID:000A, ""
                                  |
:0043690A 6A0A                    push 0000000A                        <-A入棧
:0043690C 2BC3                    sub eaxebx                         
:0043690E 99                      cdq                                  <-擴充套件EAX
:0043690F 33C2                    xor eaxedx                         
:00436911 2BC2                    sub eaxedx                        
:00436913 054C010000              add eax, 0000014C                    
:00436918 8D14C500000000          lea edxdword ptr [8*eax+00000000]  
:0043691F 2BD0                    sub edxeax                        
:00436921 8D0C90                  lea ecxdword ptr [eax+4*edx]      
:00436924 8D542414                lea edxdword ptr [esp+14]
:00436928 52                      push edx
:00436929 8D3448                  lea esidword ptr [eax+2*ecx]       <-ESI=A119
:0043692C C1E603                  shl esi, 03                          <-A119做邏輯左移
:0043692F 56                      push esi
:00436930 E851B00800              call 004C1986                        <-令ESP+10=關鍵數,此關
                                                                         鍵數根據使用者名稱的不同而不同。
:00436935 83C40C                  add esp, 0000000C
:00436938 81FE3F420F00            cmp esi, 000F423F                    <-ESI與999999比較
:0043693E 0F87EF000000            ja 00436A33                          <-大於則跳走
:00436944 8A4C2414                mov clbyte ptr [esp+14]      <-cl=2----------------ESP+10是註冊碼第1位
:00436948 8A442415                mov albyte ptr [esp+15]      <-al=8-----------------  這幾行是對上面
:0043694C 8A542413                mov dlbyte ptr [esp+13]      <-dl=9------------------關鍵數進行移位計
:00436950 884C2416                mov byte ptr [esp+16], cl      <-註冊碼第七位為ESP+16=2-算的,六位數移
:00436954 8A4C2411                mov clbyte ptr [esp+11]      <-cl=2--------------------位後成為九位數
:00436958 88442418                mov byte ptr [esp+18], al      <-註冊碼第九位為ESP+18=8--- 即註冊碼的位
:0043695C 8A442412                mov albyte ptr [esp+12]      <-al=9----------------------|數。但這不是
:00436960 88542415                mov byte ptr [esp+15], dl      <-註冊碼第六位為ESP+15=9----|真的註冊碼,
:00436964 884C2412                mov byte ptr [esp+12], cl      <-註冊碼第三位為ESP+12=2----|真註冊碼的第
:00436968 8B4C2414                mov ecxdword ptr [esp+14]    <-取註冊碼的第五位         /二、五、八位
:0043696C 81E1FF000000            and ecx, 000000FF              <-ECX=32                  /要透過這個九位
:00436972 88442413                mov byte ptr [esp+13], al      <-註冊碼第四位為ESP+13=9-/數來計算得出。
:00436976 8BC1                    mov eaxecx                   
:00436978 C1E005                  shl eax, 05                    
:0043697B 2BC1                    sub eaxecx                   
:0043697D 8B4C2418                mov ecxdword ptr [esp+18]    <-取註冊碼第9位數
:00436981 81E1FF000000            and ecx, 000000FF              
:00436987 8D1440                  lea edxdword ptr [eax+2*eax
:0043698A 8D0489                  lea eaxdword ptr [ecx+4*ecx
:0043698D C1E003                  shl eax, 03                    
:00436990 2BC1                    sub eaxecx                   
:00436992 2BC2                    sub eaxedx                  
:00436994 99                      cdq
:00436995 8BC8                    mov ecxeax                   
:00436997 33CA                    xor ecxedx                   
:00436999 2BCA                    sub ecxedx                  
:0043699B 8D0489                  lea eaxdword ptr [ecx+4*ecx
:0043699E C1E003                  shl eax, 03                    <-EAX的值左移3次
:004369A1 2BC1                    sub eaxecx                   

* Possible Ref to Menu: IRFANVIEW, Item: "?u JPM(J)"
                                  |

* Possible Reference to Dialog: DialogID_0402, CONTROL_ID:0009, ""
                                  |
:004369A3 B909000000              mov ecx, 00000009              <-ECX置9
:004369A8 99                      cdq
:004369A9 F7F9                    idiv ecx                       <-EAX/9 商為29BE,餘數為0
:004369AB 8B442413                mov eaxdword ptr [esp+13]    <-取註冊碼的第四位
:004369AF 25FF000000              and eax, 000000FF              <-EAX=39
:004369B4 80C230                  add dl, 30                    
:004369B7 88542417                mov byte ptr [esp+17], dl      <-註冊碼第8位為ESP+17=0
:004369BB 8D1440                  lea edxdword ptr [eax+2*eax
:004369BE C1E204                  shl edx, 04                   
:004369C1 2BD0                    sub edxeax                   
:004369C3 8B442415                mov eaxdword ptr [esp+15]    <-取註冊碼的第六位
:004369C7 25FF000000              and eax, 000000FF              
:004369CC 8D0CC0                  lea ecxdword ptr [eax+8*eax
:004369CF 8D0488                  lea eaxdword ptr [eax+4*ecx
:004369D2 8D0442                  lea eaxdword ptr [edx+2*eax
:004369D5 99                      cdq
:004369D6 33C2                    xor eaxedx                  
:004369D8 2BC2                    sub eaxedx                   
:004369DA 8D0CC0                  lea ecxdword ptr [eax+8*eax
:004369DD 8D0488                  lea eaxdword ptr [eax+4*ecx

* Possible Ref to Menu: IRFANVIEW, Item: "?u JPM(J)"
                                  |

* Possible Reference to Dialog: DialogID_0402, CONTROL_ID:0009, ""
                                  |
:004369E0 B909000000              mov ecx, 00000009
:004369E5 D1E0                    shl eax, 1                     
:004369E7 99                      cdq
:004369E8 F7F9                    idiv ecx                       <-EAX/9 商為DD84 餘數6
:004369EA 8B4C2410                mov ecxdword ptr [esp+10]    <-取註冊碼的第一位
:004369EE 81E1FF000000            and ecx, 000000FF              
:004369F4 8D0449                  lea eaxdword ptr [ecx+2*ecx
:004369F7 8D04C0                  lea eaxdword ptr [eax+8*eax
:004369FA D1E0                    shl eax, 1                     
:004369FC 2BC1                    sub eaxecx                   
:004369FE 80C230                  add dl, 30                     
:00436A01 88542414                mov byte ptr [esp+14], dl      <-註冊碼第五位為ESP+14=6
:00436A05 8B4C2411                mov ecxdword ptr [esp+11]    <-取註冊碼的第二位
:00436A09 81E1FF000000            and ecx, 000000FF
:00436A0F 8D14CD00000000          lea edxdword ptr [8*ecx+00000000]  
:00436A16 2BD1                    sub edxecx                   
:00436A18 8D1492                  lea edxdword ptr [edx+4*edx
:00436A1B 2BC2                    sub eaxedx                   
:00436A1D 99                      cdq
:00436A1E 8BC8                    mov ecxeax                   
:00436A20 33CA                    xor ecxedx                   
:00436A22 2BCA                    sub ecxedx                   
:00436A24 8D0449                  lea eaxdword ptr [ecx+2*ecx
:00436A27 8D04C0                  lea eaxdword ptr [eax+8*eax
:00436A2A D1E0                    shl eax, 1                    
:00436A2C 2BC1                    sub eaxecx                   
:00436A2E E9F5000000              jmp 00436B28

..................中間省略

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00436A2E(U)
|
:00436B28 99                      cdq

* Possible Ref to Menu: IRFANVIEW, Item: "?u JPM(J)"
                                  |

* Possible Reference to Dialog: DialogID_0402, CONTROL_ID:0009, ""
                                  |
:00436B29 B909000000              mov ecx, 00000009
:00436B2E C644241900              mov [esp+19], 00
:00436B33 F7F9                    idiv ecx                       <-商為15EC,餘數為EDX=1
:00436B35 80C230                  add dl, 30                     <-dl=dl+30=31
:00436B38 88542411                mov byte ptr [esp+11], dl      <-註冊碼第2位為1
:00436B3C 8D542410                lea edxdword ptr [esp+10]    <-真註冊碼入EDX
:00436B40 52                      push edx                       <-EDX入棧
:00436B41 E8B7FC0700              call 004B67FD                  <-將真註冊碼轉換為16進位制,EBP為假註冊碼
:00436B46 83C404                  add esp, 00000004
:00436B49 33C9                    xor ecxecx                   <-ECX清零
:00436B4B 3BE8                    cmp ebpeax                   <-真假註冊碼比較
:00436B4D 5F                      pop edi
:00436B4E 5E                      pop esi
:00436B4F 0F94C1                  sete cl                        <-設定cl
:00436B52 5D                      pop ebp
:00436B53 8BC1                    mov eaxecx                   <-EAX清零
:00436B55 5B                      pop ebx
:00436B56 83C414                  add esp, 00000014
:00436B59 C3                      ret                            <-返回EAX值




***********************************

程式的註冊資訊儲存在程式的安裝目錄裡的i_view32.ini檔案中。
取消註冊只要把此檔案中的[Registration]段下的name和code兩行刪除即可。


***********************************

註冊演算法總結:軟體根據使用者名稱算出一個六位關鍵數,再將其進行移位,形成一個九位數。然後用用這個九位數算出註冊碼。最後將真註冊碼轉換為16進位制數與假註冊碼的16進位制數進行比較。

關鍵數與九位數關係如下:

關鍵數的第六位---------九位數的第九位
關鍵數的第五位---------九位數的第五、七位
關鍵數的第四位---------九位數的第六位
關鍵數的第三位---------九位數的第四位
關鍵數的第二位---------九位數的第二、三位
關鍵數的第一位---------九位數的第一位
                       九位數的第八位為空

九位數中除第二、五、八位需要由其它數計算得出外,第一、三、四、六、七、九位就是真註冊碼的相應位。

註冊碼的第二位由九位數中的第一、二位計算得出;
註冊碼的第五位由九位數中的第四、六位計算得出;
註冊碼的第八位由九位數中的第五、九位計算得出。

***********************************




    ..............................................
    .                 __         ___   ____  __  .
    .   / |    |    |   |   | |   | |    |   | .
    .  /  |    |    |   |   | |     |  __    | .
    .  /  |~~| |~~| |   |   | |     |    |   | .
    . /   |__| |__| |__ |   | |___| |____| __| .
    ..............................................
                             
                      2003.11.28 傍晚

相關文章