loveasm的crackme演算法分析-----CRC32演算法的妙用

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

標 題:loveasm的crackme演算法分析-----CRC32演算法的妙用

發信人:onlyu

時 間:2004-2-20 週五, 下午12:14

詳細資訊:



loveasm的crackme演算法分析-----CRC32演算法的妙用
【作者】:onlyu[FCG][DFCG]
【軟體介紹】:loveasm[YCG][DFCG]兄弟的crackme,主要鍛鍊演算法分析,要求破解成功後出現顯示"恭喜您!您已經成功的註冊了本軟體!"的對話方塊。
【軟體下載】:點選此處本地下載
【軟體限制】:註冊碼
【作者宣告】:初學Crack,只是感興趣,沒有其它目的。失誤之處敬請諸位大俠賜教!
【破解工具】:Ollydbg1.09
【破解過程】:

執行程式,輸入
使用者名稱:onlyu[FCG][DFCG]
註冊碼:78787878787878787878787878787878

在OD命令列外掛裡下斷點:bpx getdlgitemtexta
點註冊,停在如下:
004014A9   .  68 A4374000   PUSH CRACKME.004037A4                    
004014AE   .  68 91010000   PUSH 191                            
004014B3   .  FF75 08       PUSH DWORD PTR SS:[EBP+8]             
004014B6   .  E8 27020000   CALL <JMP.&user32.GetDlgItemTextA><-----獲得輸入的註冊名   
004014BB   .  8BC8          MOV ECX,EAX
004014BD   .  83F8 00       CMP EAX,0<-------------------------輸入的註冊名是否為空
004014C0   .  77 0E         JA SHORT CRACKME.004014D0<---------不空往下跳
004014C2   .  B8 00000000   MOV EAX,0
004014C7   .  59            POP ECX
004014C8   .  5A            POP EDX
跳轉到這裡:
004014D0   >  33C0          XOR EAX,EAX
004014D2   .  8D35 A4374000 LEA ESI,DWORD PTR DS:[4037A4]<----使ESI指向註冊名"onlyu[FCG][DFCG]"
004014D8   >  33DB          XOR EBX,EBX--------------------
004014DA   .  8A1E          MOV BL,BYTE PTR DS:[ESI]       |
004014DC   .  03C3          ADD EAX,EBX                    |小迴圈
004014DE   .  46            INC ESI                        |
004014DF   .^ E2 F7         LOOPD SHORT CRACKME.004014D8---
上面這段小迴圈的功能是把輸入的使用者名稱的字元的ASCII碼累加起來儲存到EAX中,我的為58B
004014E1   .  8845 FF       MOV BYTE PTR SS:[EBP-1],AL<----把上面得到的值取後兩位存到ss:[ebp-1]處
004014E4   .  68 FF000000   PUSH 0FF                                 
004014E9   .  68 24364000   PUSH CRACKME.00403624  
004014EE   .  68 92010000   PUSH 192             
004014F3   .  FF75 08       PUSH DWORD PTR SS:[EBP+8]           
004014F6   .  E8 E7010000   CALL <JMP.&user32.GetDlgItemTextA><-----獲得輸入的註冊碼
004014FB   .  BE 24364000   MOV ESI,CRACKME.00403624<--------ESI->輸入的註冊碼"78787878..."
00401500   .  8D3D 70394000 LEA EDI,DWORD PTR DS:[403970]
00401506   .  B9 10000000   MOV ECX,10<---------------------置迴圈次數
0040150B   >  33DB          XOR EBX,EBX<--------------------把EBX清0
0040150D   .  33C0          XOR EAX,EAX<--------------------把EAX清0
0040150F   .  AC            LODS BYTE PTR DS:[ESI]<---------取註冊碼的字元到EAX中
00401510   .  83F8 39       CMP EAX,39<---------------------輸入字元ASCII碼是否大於39
00401513   .  7E 03         JLE SHORT CRACKME.00401518<-----小於或等於就跳
00401515   .  83E8 07       SUB EAX,7<----------------------EAX=EAX-7
00401518   >  83E8 30       SUB EAX,30<---------------------EAX=EAX-30
0040151B   .  0BD8          OR EBX,EAX<---------------------EBX=EBX or EAX
0040151D   .  C1E3 04       SHL EBX,4<----------------------EBX=EBX shl 4
00401520   .  33C0          XOR EAX,EAX<--------------------EAX清0
00401522   .  AC            LODS BYTE PTR DS:[ESI]<---------取註冊碼的下一個字元到EAX中
00401523   .  83F8 39       CMP EAX,39<---------------------輸入字元ASCII碼是否大於39
00401526   .  7E 03         JLE SHORT CRACKME.0040152B<-----小於或等於就跳
00401528   .  83E8 07       SUB EAX,7<----------------------EAX=EAX-7
0040152B   >  83E8 30       SUB EAX,30<---------------------EAX=EAX-30
0040152E   .  0BD8          OR EBX,EAX<---------------------EBX=EBX or EAX
00401530   .  881F          MOV BYTE PTR DS:[EDI],BL<-------把BL中數值存到DS:[EDI]處
00401532   .  47            INC EDI<------------------------EDI=EDI+1
00401533   .^ E2 D6         LOOPD SHORT CRACKME.0040150B<---迴圈到40150B處
上面這一段迴圈16次,輸入的註冊碼按兩個字元一組處理,字元若為小於或等於39,就把它的ASCII值減去30H,若大於39就減去37H,不妨設兩個字元為a,b,則c=(((a-常數) shl 4) or (b-常數))and FFH,如我輸入的註冊碼運算後在記憶體中如下:

00403970  78 78 78 78 78 78 78 78   xxxxxxxx
00403978  78 78 78 78 78 78 78 78   xxxxxxxx
這裡就可以猜測它的註冊碼可能為32位的。

00401535   .  B9 10000000   MOV ECX,10<------------------------置迴圈次數10H
0040153A   .  8D3D 80394000 LEA EDI,DWORD PTR DS:[403980]
00401540   .  8D35 70394000 LEA ESI,DWORD PTR DS:[403970]<-----ESI指向上面執行完的結果
00401546   >  8A06          MOV AL,BYTE PTR DS:[ESI]<----------把ESI指向的數賦給AL
00401548   .  3245 FF       XOR AL,BYTE PTR SS:[EBP-1]<--------AL=AL xor SS:[EBP-1]
0040154B   .  8807          MOV BYTE PTR DS:[EDI],AL<----------把AL的值儲存到DS:[EDI]中
0040154D   .  46            INC ESI<---------------------------ESI++
0040154E   .  47            INC EDI<---------------------------EDI++
0040154F   .^ E2 F5         LOOPD SHORT CRACKME.00401546<------迴圈到401546處
SS:[EBP-1]中儲存的是對使用者名稱運算後得到的結果,上面的迴圈的功能就是把SS:[EBP-1]和上面對註冊碼處理得到的結果按位元組異或儲存到DS:[EDI]中,結果在記憶體中如下:

00403980  F3 F3 F3 F3 F3 F3 F3 F3  篌篌篌篌
00403988  F3 F3 F3 F3 F3 F3 F3 F3  篌篌篌篌
00403990  76 71 32 7A 79 62 6D 6D  vq2zybmm
00403998  74 63 54 58 6F 72 4C 68  tcTXorLh
004039A0  77 63 75 78 76 73 6A 74  wcuxvsjt
004039A8  76 50 36 6A 6F 53 30 67  vP6joS0g
004039B0  54 47 39 32 5A 57 46 7A  TG92ZWFz
004039B8  62 56 74 5A 51 30 64 64  bVtZQ0dd
004039C0  57 30 52 47 51 30 64 64  W0RGQ0dd

  
00401551   .  B9 48000000   MOV ECX,48<-----------------------置迴圈次數48H
00401556   .  8D35 A7384000 LEA ESI,DWORD PTR DS:[4038A7]
ESI->"I Love Asm!I Love Crack!I Love Kathy!My Email:loveasm@sohu.com QQ:127095"
0040155C   .  8D3D 80394000 LEA EDI,DWORD PTR DS:[403980]<----EDI指向上面運算後得到的結果
00401562   >  8A07          MOV AL,BYTE PTR DS:[EDI]<---------AL=DS:[EDI]
00401564   .  3206          XOR AL,BYTE PTR DS:[ESI]<---------AL=AL xor DS:[ESI]
00401566   .  8807          MOV BYTE PTR DS:[EDI],AL<---------DS:[EDI]=AL
00401568   .  46            INC ESI<--------------------------ESI++
00401569   .  47            INC EDI<--------------------------EDI++
0040156A   .^ E2 F6         LOOPD SHORT CRACKME.00401562<-----迴圈到401562處
這一段迴圈的功能是把上面運算得到的結果與常串"vq2zybmmtcTXorLhwcuxvsjtvP6joS0gTG92ZWFzbVtZQ0ddW0RGQ0dd"連起來和字串"I Love Asm!I Love Crack!I Love Kathy!My Email:loveasm@sohu.com QQ:127095"進行異或運算,結果還儲存在DS:[403980]處。

 
0040156C   .  68 F0384000   PUSH CRACKME.004038F0 
00401571   .  68 80394000   PUSH CRACKME.00403980     
00401576   .  E8 2CFBFFFF   CALL CRACKME.004010A7<-------F7進去看看

F7進入CALL CRACKME.004010A7,如下:
004010A7  /$  55            PUSH EBP
004010A8  |.  8BEC          MOV EBP,ESP
004010AA  |.  83C4 FC       ADD ESP,-4
004010AD  |.  53            PUSH EBX
004010AE  |.  57            PUSH EDI
004010AF  |.  56            PUSH ESI
004010B0  |.  FF75 08       PUSH DWORD PTR SS:[EBP+8]               
004010B3  |.  E8 90060000   CALL <JMP.&kernel32.lstrlenA>           
004010B8  |.  8945 FC       MOV DWORD PTR SS:[EBP-4],EAX<--------EAX=48H
004010BB  |.  8B75 08       MOV ESI,DWORD PTR SS:[EBP+8]<--------ESI指向上面得到的結果
004010BE  |.  8B7D 0C       MOV EDI,DWORD PTR SS:[EBP+C]
004010C1  |.  8B4D FC       MOV ECX,DWORD PTR SS:[EBP-4]<--------ECX=48H
004010C4  |.  C1E9 02       SHR ECX,2<---------------------------ECX=ECX shr 2=12H
004010C7  |.  FC            CLD
004010C8  |>  51            /PUSH ECX
004010C9  |.  B9 04000000   |MOV ECX,4<--------------------------置大迴圈次數4
004010CE  |.  33DB          |XOR EBX,EBX<------------------------EBX清0
004010D0  |.  AD            |LODS DWORD PTR DS:[ESI]<------------裝入32位整數到EAX
004010D1  |>  50            |/PUSH EAX<--------------------------EAX壓棧
004010D2  |.  25 FF000000   ||AND EAX,0FF<-----------------------取AL
004010D7  |.  8A80 41344000 ||MOV AL,BYTE PTR DS:[EAX+403441]<---把DS:[EAX+403441]處資料賦給AL
004010DD  |.  3C FF         ||CMP AL,0FF<------------------------比較AL是否和FF相等
004010DF  |.  74 22         ||JE SHORT CRACKME.00401103<---------相等就跳
004010E1  |.  C1E3 06       ||SHL EBX,6<-------------------------EBX=EBX shl 6,EBX初值為0
004010E4  |.  0AD8          ||OR BL,AL<--------------------------BL=BL or AL
004010E6  |.  58            ||POP EAX<---------------------------重新裝入32位整數
004010E7  |.  C1E8 08       ||SHR EAX,8<-------------------------EAX=EAX shr 8
004010EA  |.  49            ||DEC ECX<---------------------------ECX=ECX-1
004010EB  |.^ 75 E4         |JNZ SHORT CRACKME.004010D1<--------不等就跳到4010D1處
004010ED  |.  8BC3          |MOV EAX,EBX<------------------------EAX=EBX
004010EF  |.  C1E0 08       |SHL EAX,8<--------------------------EAX=EAX shl 8
004010F2  |.  86E0          |XCHG AL,AH<-------------------------交換AL和AH的值
004010F4  |.  C1C8 10       |ROR EAX,10<-------------------------EAX=EAX ror 10
004010F7  |.  86E0          |XCHG AL,AH<-------------------------再交換AL和AH的值
004010F9  |.  AB            |STOS DWORD PTR ES:[EDI]<------------把EAX的值儲存到ES[EDI]中
004010FA  |.  4F            |DEC EDI<----------------------------EDI--
004010FB  |.  59            |POP ECX<----------------------------ECX出棧
004010FC  |.  49            |DEC ECX<----------------------------ECX--
004010FD  |.^ 75 C9         JNZ SHORT CRACKME.004010C8<---------不等於0就跳到4010C8處
004010FF  |.  33C0          XOR EAX,EAX<-------------------------EAX清0
00401101  |.  EB 05         JMP SHORT CRACKME.00401108<----------跳
00401103  |>  B8 FFFFFFFF   MOV EAX,-1
00401108  |>  5E            POP ESI
00401109  |.  5F            POP EDI
0040110A  |.  5B            POP EBX
0040110B  |.  C9            LEAVE
0040110C  .  C2 0800       RETN 8
這段函式好像沒有用,最後總是使EAX=0xFFFFFFFF,這是由於我們輸入的註冊碼不正確的原因。

從403441開始的常數表如下:

00403440  3D FF FF FF FF FF FF FF  
00403448  FF FF FF FF FF FF FF FF  
00403450  FF FF FF FF FF FF FF FF  
00403458  FF FF FF FF FF FF FF FF  
00403460  FF FF FF FF FF FF FF FF  
00403468  FF FF FF FF 3E FF FF FF  
00403470  3F 34 35 36 37 38 39 3A  
00403478  3B 3C 3D FF FF FF 00 FF  
00403480  FF FF 00 01 02 03 04 05  
00403488  06 07 08 09 0A 0B 0C 0D  
00403490  0E 0F 10 11 12 13 14 15  
00403498  16 17 18 19 FF FF FF FF  
004034A0  FF FF 1A 1B 1C 1D 1E 1F  
004034A8  20 21 22 23 24 25 26 27   
004034B0  28 29 2A 2B 2C 2D 2E 2F  
004034B8  30 31 32 33 FF FF FF FF  
004034C0  FF FF FF FF FF FF FF FF  
004034C8  FF FF FF FF FF FF FF FF  
004034D0  FF FF FF FF FF FF FF FF  
004034D8  FF FF FF FF FF FF FF FF  
004034E0  FF FF FF FF FF FF FF FF  
004034E8  FF FF FF FF FF FF FF FF  
004034F0  FF FF FF FF FF FF FF FF  
004034F8  FF FF FF FF FF FF FF FF  
00403500  FF FF FF FF FF FF FF FF  
00403508  FF FF FF FF FF FF FF FF  
00403510  FF FF FF FF FF FF FF FF  
00403518  FF FF FF FF FF FF FF FF  
00403520  FF FF FF FF FF FF FF FF  
00403528  FF FF FF FF FF FF FF FF  
00403530  FF FF FF FF FF FF FF FF  
00403538  FF FF FF FF FF FF FF FF  
  
0040157B   .  68 A4384000   PUSH CRACKME.004038A4 
00401580   .  68 F0384000   PUSH CRACKME.004038F0 
00401585   .  E8 B8010000   CALL <JMP.&kernel32.lstrcatA> 
這個函式的功能是把上面運算得到的結果接在字串"I Love Asm!I Love Crack!I Love Kathy!My Email:loveasm@sohu.com QQ:127095"的後面返回字串地址到EAX中。
0040158A   .  E8 CCFAFFFF   CALL CRACKME.0040105B<--------------按F7進去看看
進入CALL CRACKME.0040105B後如下:
0040105B  /$  B9 00010000   MOV ECX,100<------------------------ECX=100
00401060  |.  BA 2083B8ED   MOV EDX,EDB88320<-------------------EDX=EDB88320
00401065  |>  8D41 FF       /LEA EAX,DWORD PTR DS:[ECX-1]
00401068  |.  51            |PUSH ECX<--------------------------儲存ECX到堆疊中
00401069  |.  B9 08000000   |MOV ECX,8<-------------------------置小迴圈次數8
0040106E  |>  D1E8          |/SHR EAX,1<------------------------EAX=EAX shr 1
00401070  |.  73 02         ||JNB SHORT CRACKME.00401074
00401072  |.  33C2          ||XOR EAX,EDX<----------------------EAX=EAX xor EDX
00401074  |>  49            ||DEC ECX<--------------------------ECX--
00401075  |.^ 75 F7         |JNZ SHORT CRACKME.0040106E<-------不等於0就跳到40106E處
00401077  |.  59            |POP ECX<---------------------------恢復ECX
00401078  |.  89048D FC2F40>|MOV DWORD PTR DS:[ECX*4+402FFC],EAX<---把EAX的值放到[ECX*4+402FFC]中
0040107F  |.  49            |DEC ECX<-------------------------------ECX--
00401080  |.^ 75 E3         JNZ SHORT CRACKME.00401065<--------不等於0就跳到00401065處
00401082  .  C3            RETN

這一段的功能實際上是生成一個常數表,表中元素的個數為FFH。表的起始地址為403004。在記憶體中如下:
00403000     00000000    77073096    EE0E612C    990951BA
00403010     076DC419    706AF48F    E963A535    9E6495A3
00403020     0EDB8832    79DCB8A4    E0D5E91E    97D2D988
00403030     09B64C2B    7EB17CBD    E7B82D07    90BF1D91
00403040     1DB71064    6AB020F2    F3B97148    84BE41DE
00403050     1ADAD47D    6DDDE4EB    F4D4B551    83D385C7
00403060     136C9856    646BA8C0    FD62F97A    8A65C9EC
00403070     14015C4F    63066CD9    FA0F3D63    8D080DF5
00403080     3B6E20C8    4C69105E    D56041E4    A2677172
00403090     3C03E4D1    4B04D447    D20D85FD    A50AB56B
004030A0     35B5A8FA    42B2986C    DBBBC9D6    ACBCF940
004030B0     32D86CE3    45DF5C75    DCD60DCF    ABD13D59
004030C0     26D930AC    51DE003A    C8D75180    BFD06116
004030D0     21B4F4B5    56B3C423    CFBA9599    B8BDA50F
004030E0     2802B89E    5F058808    C60CD9B2    B10BE924
004030F0     2F6F7C87    58684C11    C1611DAB    B6662D3D
00403100     76DC4190    01DB7106    98D220BC    EFD5102A
00403110     71B18589    06B6B51F    9FBFE4A5    E8B8D433
00403120     7807C9A2    0F00F934    9609A88E    E10E9818
00403130     7F6A0DBB    086D3D2D    91646C97    E6635C01
00403140     6B6B51F4    1C6C6162    856530D8    F262004E
00403150     6C0695ED    1B01A57B    8208F4C1    F50FC457
00403160     65B0D9C6    12B7E950    8BBEB8EA    FCB9887C
00403170     62DD1DDF    15DA2D49    8CD37CF3    FBD44C65
00403180     4DB26158    3AB551CE    A3BC0074    D4BB30E2
00403190     4ADFA541    3DD895D7    A4D1C46D    D3D6F4FB
004031A0     4369E96A    346ED9FC    AD678846    DA60B8D0
004031B0     44042D73    33031DE5    AA0A4C5F    DD0D7CC9
004031C0     5005713C    270241AA    BE0B1010    C90C2086
004031D0     5768B525    206F85B3    B966D409    CE61E49F
004031E0     5EDEF90E    29D9C998    B0D09822    C7D7A8B4
004031F0     59B33D17    2EB40D81    B7BD5C3B    C0BA6CAD
00403200     EDB88320    9ABFB3B6    03B6E20C    74B1D29A
00403210     EAD54739    9DD277AF    04DB2615    73DC1683
00403220     E3630B12    94643B84    0D6D6A3E    7A6A5AA8
00403230     E40ECF0B    9309FF9D    0A00AE27    7D079EB1
00403240     F00F9344    8708A3D2    1E01F268    6906C2FE
00403250     F762575D    806567CB    196C3671    6E6B06E7
00403260     FED41B76    89D32BE0    10DA7A5A    67DD4ACC
00403270     F9B9DF6F    8EBEEFF9    17B7BE43    60B08ED5
00403280     D6D6A3E8    A1D1937E    38D8C2C4    4FDFF252
00403290     D1BB67F1    A6BC5767    3FB506DD    48B2364B
004032A0     D80D2BDA    AF0A1B4C    36034AF6    41047A60
004032B0     DF60EFC3    A867DF55    316E8EEF    4669BE79
004032C0     CB61B38C    BC66831A    256FD2A0    5268E236
004032D0     CC0C7795    BB0B4703    220216B9    5505262F
004032E0     C5BA3BBE    B2BD0B28    2BB45A92    5CB36A04
004032F0     C2D7FFA7    B5D0CF31    2CD99E8B    5BDEAE1D
00403300     9B64C2B0    EC63F226    756AA39C    026D930A
00403310     9C0906A9    EB0E363F    72076785    05005713
00403320     95BF4A82    E2B87A14    7BB12BAE    0CB61B38
00403330     92D28E9B    E5D5BE0D    7CDCEFB7    0BDBDF21
00403340     86D3D2D4    F1D4E242    68DDB3F8    1FDA836E
00403350     81BE16CD    F6B9265B    6FB077E1    18B74777
00403360     88085AE6    FF0F6A70    66063BCA    11010B5C
00403370     8F659EFF    F862AE69    616BFFD3    166CCF45
00403380     A00AE278    D70DD2EE    4E048354    3903B3C2
00403390     A7672661    D06016F7    4969474D    3E6E77DB
004033A0     AED16A4A    D9D65ADC    40DF0B66    37D83BF0
004033B0     A9BCAE53    DEBB9EC5    47B2CF7F    30B5FFE9
004033C0     BDBDF21C    CABAC28A    53B39330    24B4A3A6
004033D0     BAD03605    CDD70693    54DE5729    23D967BF
004033E0     B3667A2E    C4614AB8    5D681B02    2A6F2B94
004033F0     B40BBE37    C30C8EA1    5A05DF1B    2D02EF8D

此時記憶體如下:
004038F0  20 2D 20 49 20 4C 6F 76   - I Lov
004038F8  65 20 41 73 6D 21 49 20  e Asm!I
00403900  4C 6F 76 65 20 43 72 61  Love Cra
00403908  63 6B 21 49 20 4C 6F 76  ck!I Lov
00403910  65 20 4B 61 74 68 79 21  e Kathy!
00403918  4D 79 20 45 6D 61 69 6C  My Email
00403920  3A 6C 6F 76 65 61 73 6D  :loveasm
00403928  40 73 6F 68 75 2E 63 6F  @sohu.co
00403930  6D 20 51 51 3A 31 32 37  m QQ:127
00403938  30 39 35 20 2D 20 49 20  095 - I
00403940  4C 6F 76 65 20 41 73 6D  Love Asm
00403948  21 49 20 4C 6F 76 65 20  !I Love
00403950  43 72 61 63 6B 21 49 20  Crack!I
00403958  4C 6F 76 65 20 4B 61 74  Love Kat
00403960  68 79 21 4D 79 20 45 6D  hy!My Em
00403968  61 69 6C 3A 6C 6F 76 65  ail:love
00403970  78 78 78 78 78 78 78 78  xxxxxxxx
00403978  78 78 78 78 78 78 78 78  xxxxxxxx
00403980  BA D3 BF 9C 85 96 D3 B2  河硬
00403988  80 9E D2 BA D3 BF 9C 85  液0
00403990  13 51 71 08 18 01 06 4C  QqL
00403998  3D 43 18 37 19 17 6C 23  =C7l#
004039A0  16 17 1D 01 57 3E 13 54  W>T
004039A8  33 3D 57 03 03 69 5C 08  3=Wi
004039B0  22 22 58 41 37 17 35 15  ""XA75
004039B8  0A 23 5A 39 3E 5D 44 35  .#Z9>]D5
004039C0  06 0A 63 75 66 20 2D 20  .cuf -
004039C8  49 20 4C 6F 76 65 20 41  I Love A
004039D0  73 6D 21 49 20 4C 6F 76  sm!I Lov
004039D8  65 20 43 72 61 63 6B 21  e Crack!
004039E0  49 20 4C 6F 76 65 20 4B  I Love K
004039E8  61 74 68 79 21 4D 79 20  athy!My
004039F0  45 6D 61 69 6C 3A 6C 6F  Email:lo
004039F8  76 65 61 73 6D 40 73 6F  veasm@so
00403A00  68 75 2E 63 6F 6D 20 51  hu.com Q
00403A08  51 3A 31 32 37 30 39 35  Q:127095

繼續往下分析:
 
0040158F   .  8D1D F0384000 LEA EBX,DWORD PTR DS:[4038F0]<------EBX指向上面計算得到的串
00401595   .  E8 E9FAFFFF   CALL CRACKME.00401083<--------------按F7進去看看
進入CALL CRACKME.00401083後如下:
00401083  /$  B8 FFFFFFFF   MOV EAX,-1<----------------------------EAX=-1
00401088  |.  0BDB          OR EBX,EBX
0040108A  |.  74 18         JE SHORT CRACKME.004010A4<-------------EBX若為0就跳
0040108C  |>  8A13          /MOV DL,BYTE PTR DS:[EBX]<-------------DL=DS:[EBX]
0040108E  |.  0AD2          |OR DL,DL
00401090  |.  74 12         |JE SHORT CRACKME.004010A4<------------為0就跳
00401092  |.  32D0          |XOR DL,AL<----------------------------DL=AL xor DL
00401094  |.  0FB6D2        |MOVZX EDX,DL<-------------------------EDX=DL
00401097  |.  C1E8 08       |SHR EAX,8<----------------------------EAX=EAX shr 8
0040109A  |.  330495 003040>|XOR EAX,DWORD PTR DS:[EDX*4+403000]<--EAX=EAX xor DS:[EDX*4+403000]
004010A1  |.  43            |INC EBX<------------------------------EBX++
004010A2  |.^ EB E8         JMP SHORT CRACKME.0040108C<-----------跳到40108C
004010A4  |>  F7D0          NOT EAX<-------------------------------EAX=NOT EAX
004010A6  .  C3            RETN
又是一個迴圈,這個迴圈就是把剛剛生成的表和上面計算得到的串進行運算,運算規則見註釋,最後把結果儲存到EAX中。
 
0040159A   .  3D CA86B0C4   CMP EAX,C4B086CA<-------------比較EAX的值是否和C4B086CA相等
0040159F   .  75 3E         JNZ SHORT CRACKME.004015DF<---對比點,不相等就跳

透過以上的分析,我們可以知道,這個CrackMe的演算法用到了一個有著FF個元素的32位整數表,還用了一個有著FF個元素的8位整數表。演算法看起來比較複雜,但是仔細分析一下,我們知道,把JNZ SHORT CRACKME.004015DF改成JZ SHORT CRACKME.004015DF,出來的提示是"I Love Asm!..."這樣的提示,說明程式會把上面的字元變成"恭喜您!您已經成功的註冊了本軟體!",這裡為什麼沒有變呢,原因就在CALL CRACKME.004010A7裡面,這個函式的功能就是讀[403980]處開始的16個位元組的資料,然後進行運算,運算結果儲存到ES:[EDI]即記憶體[4038F0]開始的地方,若註冊成功,則對話方塊的提示字串就是從這兒取的。那麼到底是哪16個位元組經過CALL CRACKME.004010A7能得到"恭喜您!您已經成功的註冊了本軟體!"這樣正確的提示資訊呢?這裡作者幫了一個大忙,感謝Loveasm了^_^,透過跟蹤,我發現是如下的16個位元組運算後能得到正確的提示資訊:
3C 41 2A 3F 05 16 74 77 1C 5B 69 0C 0B 38 23 24

當然你可以分析CALL CRACKME.004010A7利用"恭喜您!您已經成功的註冊了本軟體!"算出這16個位元組來,這是此CrackMe的核心。這麼一分析,我們就可以看出,這個CrackMe給我們設定了一個超級陷阱,正確的註冊碼的獲得只與上面16個位元組有關,與那個一個長整數表無關,作者演算法設計得很巧妙,把這個掩蓋得很好,只是作者給了一個正確的註冊碼給了我們以可乘之機。看來以後誰釋出CrackMe時,最好先別把正確的註冊碼公佈,或者把演算法設計得更好些。

給出我的註冊碼:

使用者名稱:onlyu[FCG][DFCG]
註冊碼:B7CAA1B48E9DFFFC97D0E28780B3A8AF

用VC 6.0編寫序號產生器,單擊按鈕的程式碼如下:

void CKeygenDlg::OnOK() 
{
  // TODO: Add extra validation here
         int i;
         unsigned char num=0;
  unsigned char str[17]={0x3C,0x41,0x2A,0x3F,0x05,0x16,0x74,0x77,
                       0x1C,0x5B,0x69,0x0C,0x0B,0x38,0x23,0x24,0x0};
  char str1[33];
  str1[33]=0;
  UpdateData(TRUE);
  if(m_name=="") AfxMessageBox("請輸入使用者名稱!");
  else
  {
   for(i=0;i<m_name.GetLength();i++)
           num+=m_name[i];
          for(i=0;i<16;i++) str[i]=num^str[i];
          for(i=0;i<16;i++) sprintf(str1+2*i,"%0x",str[i]);
   m_sn=str1;
   m_sn.MakeUpper();
    }
  UpdateData(FALSE);
}

 


補充一下,對於破解中遇到的那個長度為FFh的32位整數表,好像在那裡見過,拿看雪的書一檢視,才發現是CRC32校驗的常數表,這下我對這個Crackme的整個判斷過程就清晰多了。重新總結一下,作者計算如下資料的CRC校驗值:
004038F0  B9 A7 CF B2 C4 FA A3 A1  恭喜您!
004038F8  C4 FA D2 D1 BE AD B3 C9  您已經成
00403900  B9 A6 B5 C4 D7 A2 B2 E1  功的註冊
00403908  C1 CB B1 BE C8 ED BC FE  了本軟體
00403910  A3 A1 2D 20 4C 6F 76 65  !- Love
00403918  61 73 6D 5B 59 43 47 5D  asm[YCG]
00403920  5B 44 46 43 47 5D 20 2D  [DFCG] -
00403928  20 49 20 4C 6F 76 65 20   I Love
00403930  41 73 6D 21 49 20 4C 6F  Asm!I Lo
00403938  76 65 20 43 72 61 63 6B  ve Crack
00403940  21 49 20 4C 6F 76 65 20  !I Love
00403948  4B 61 74 68 79 21 4D 79  Kathy!My
00403950  20 45 6D 61 69 6C 3A 6C   Email:l
00403958  6F 76 65 61 73 6D 40 73  oveasm@s
00403960  6F 68 75 2E 63 6F 6D 20  ohu.com
00403968  51 51 3A 31 32 37 30 39  QQ:12709
00403970  35                       5
 
若校驗值為C4B086CA,則正確,若不相等,則錯誤,而這個串的獲得是由使用者輸入的正確的註冊碼運算出來的,若輸入的註冊碼不正確,則得不到正確的提示資訊,爆破也沒有用。
一般CRC校驗演算法是把註冊名和註冊碼按某種運算之後的值進行校驗,而這個Crackme還把要顯示的正確提示資訊進行了校驗,演算法很巧妙,故題目加上CRC32演算法的妙用。真是佩服Loveasm[YCG][DFCG],能用純彙編實現這麼好的Crackme,真是厲害,再次感謝!

相關文章