SuperCleaner演算法分析----菜鳥級 (12千字)

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

軟體名稱:SuperCleaner
最新版本:2.42
檔案大小:276KB
軟體簡介:
  是幫助使用者清洗他們的計算機硬碟內不必要的檔案的程式。它能掃描你的系統讓你選擇不再需要的檔案進行刪除。並能備份檔案已避免你誤刪除有用的檔案,此備份功能將不必要的檔案扔進再迴圈箱,這樣可以讓你再必要的時候恢復資訊。

下載地址:http://gwbn.onlinedown.net/down/cleansetup.exe
軟體資訊:VC,無殼,30天使用限制.保護簡單,明碼比較.最適合我等菜鳥了
破解工具llyDbg,pw32dasmgold(在此篇破文中只用它來抓程式碼)
破解者:wolflh2002


破解過程:

以前在看雪老師的論壇上發表過一次,並有幸被看雪老師收入精華.但那次是在WIN98下,用TRW(我喜歡用這個工具了)可以很容易的跟出,註冊碼是用明碼比較,且沒有分析出演算法.這次因為機器升級了,摒棄了WIN98.而WIN2K下TRW的"萬能斷點"(HMEMCPY)無用.所以只好藉助OllyDbg了.

根據各種教程、破文的教導,用w32dasm反彙編.可找來找去,也找不著註冊成功的標誌;出錯的資訊倒有一個,不過多次雙擊卻有多個結果,而我這個菜鳥也看不出哪一個對我有用的.
破罐子破摔了,用OllyDbg載入RUN,選擇"Enter Registration"項,出現註冊對話方塊.輸入
使用者名稱:wolflh2002
註冊碼:5378378(當然是假的,有真的我還用這麼辛苦?)
回到OllyDbg介面,按CTRL+N或單擊滑鼠右鍵選擇"Search for"->"Name(label) in current module"
.按明碼比較的慣例選擇"KERNEL32.lstrcmpA",回車.在第一項(00402005)上按F2設定斷點.再回到註冊介面,點選"OK".YEAH,被OllyDbg斷下了.

* Possible Reference to Dialog: DialogID_0065, CONTROL_ID:03FC, ""
|
:00411DD3 68FC030000 push 000003FC
:00411DD8 56 push esi
:00411DD9 FFD7 call edi
:00411DDB 8D442408 lea eax, dword ptr [esp+08]
:00411DDF 8D8C2408010000 lea ecx, dword ptr [esp+00000108]
:00411DE6 50 push eax ----壓入假註冊碼
:00411DE7 51 push ecx ----壓入真使用者名稱crazywolf(這就是用英文的好處,不然暫存器不可能顯示中文的)
:00411DE8 E8B3050000 call 004123A0 ----停在這裡,可疑!!!F7進入(在OllyDbg裡相當於TRW的F8)
:00411DED 83C408 add esp, 00000008
:00411DF0 85C0 test eax, eax
:00411DF2 5F pop edi
:00411DF3 7443 je 00411E38 -----這裡彈出出錯對話方塊
:00411DF5 8D542404 lea edx, dword ptr [esp+04]
:00411DF9 8D842404010000 lea eax, dword ptr [esp+00000104]
:00411E00 52 push edx
:00411E01 50 push eax

.
.
.
.
(此處略去XXXXX個位元組)

進入此CALL後:

* Referenced by a CALL at Addresses:
|:00411DE8 , :004122CE
|
:004123A0 81EC00010000 sub esp, 00000100
:004123A6 A080964200 mov al, byte ptr [00429680]
:004123AB 56 push esi
:004123AC 57 push edi
:004123AD 88442408 mov byte ptr [esp+08], al

* Possible Reference to String Resource ID=00063: "The location you specified does not contain a Netscape 4 pro"
|
:004123B1 B93F000000 mov ecx, 0000003F
:004123B6 33C0 xor eax, eax
:004123B8 8D7C2409 lea edi, dword ptr [esp+09]
:004123BC 8B94240C010000 mov edx, dword ptr [esp+0000010C]
:004123C3 F3 repz
:004123C4 AB stosd
:004123C5 66AB stosw
:004123C7 8D4C2408 lea ecx, dword ptr [esp+08]
:004123CB 33F6 xor esi, esi
:004123CD 51 push ecx
:004123CE 52 push edx
:004123CF AA stosb
:004123D0 E8AB000000 call 00412480 ----過了這裡就出現我們所需要的註冊碼了.(雖然我不懂演算法,進入看看總可以吧??)
:004123D5 8B8C2418010000 mov ecx, dword ptr [esp+00000118]
:004123DC 8D442410 lea eax, dword ptr [esp+10]
:004123E0 50 push eax ----真碼
:004123E1 51 push ecx ----假碼
:004123E2 E869FFFFFF call 00412350
:004123E7 83C410 add esp, 00000010
:004123EA 85C0 test eax, eax

* Possible Reference to String Resource ID=00001: "Registered to: %s"
|
:004123EC B801000000 mov eax, 00000001
:004123F1 7502 jne 004123F5
:004123F3 8BC6 mov eax, esi

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004123F1(C)
|
:004123F5 5F pop edi
:004123F6 5E pop esi
:004123F7 81C400010000 add esp, 00000100
:004123FD C3 ret
.
.
.
.
(繼續略去XXXXX個位元組)
.
.
.
.以下是完整的演算法過程:

:00412480 81EC00010000 sub esp, 00000100
:00412486 A080964200 mov al, byte ptr [00429680]
:0041248B 53 push ebx
:0041248C 55 push ebp
:0041248D 56 push esi
:0041248E 57 push edi
:0041248F 88442410 mov byte ptr [esp+10], al

* Possible Reference to String Resource ID=00063: "The location you specified does not contain a Netscape 4 pro"
|
:00412493 B93F000000 mov ecx, 0000003F
:00412498 33C0 xor eax, eax
:0041249A 8D7C2411 lea edi, dword ptr [esp+11]
:0041249E F3 repz
:0041249F AB stosd
:004124A0 66AB stosw
:004124A2 AA stosb
:004124A3 8BBC2414010000 mov edi, dword ptr [esp+00000114] ----使用者名稱送edi
:004124AA 57 push edi ----壓入使用者名稱

* Reference To: KERNEL32.lstrlenA, Ord:03AEh
|
:004124AB FF1538024200 Call dword ptr [00420238]    ----計算使用者名稱長度
:004124B1 8BF0 mov esi, eax            ----使用者名稱長度送esi
:004124B3 33C9 xor ecx, ecx ----ecx清零
:004124B5 33C0 xor eax, eax ----eax清零
:004124B7 85F6 test esi, esi
:004124B9 7E13 jle 004124CE
:004124BB 8B1508664200 mov edx, dword ptr [00426608] ----註冊名送入edx

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004124CC(C)
|
:004124C1 0FBE1C38 movsx ebx, byte ptr [eax+edi] ----依次將使用者名稱位元組轉換為ascii送ebx
:004124C5 03DA add ebx, edx ----ebx+edx的值送ebx (edx=26)
:004124C7 03CB add ecx, ebx            ----ecx+ebx的值送ecx   
:004124C9 40 inc eax ----eax加1
:004124CA 3BC6 cmp eax, esi ----是否計算完畢
:004124CC 7CF3 jl 004124C1 ----迴圈

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004124B9(C)
|
:004124CE 8B9C2418010000 mov ebx, dword ptr [esp+00000118] ----顯示註冊碼的第一部分(這裡是我自己猜的)
:004124D5 51 push ecx ----壓入累加的值(十六進位制)

* Possible StringData Ref from Data Obj ->"%ld-" ----加入分隔符"-"
|
:004124D6 681C664200 push 0042661C
:004124DB 53 push ebx

* Reference To: USER32.wsprintfA, Ord:02D6h
|
:004124DC FF1520034200 Call dword ptr [00420320]
:004124E2 83C40C add esp, 0000000C
:004124E5 33C9 xor ecx, ecx
:004124E7 33C0 xor eax, eax
:004124E9 85F6 test esi, esi
:004124EB 7E14 jle 00412501
:004124ED 8B150C664200 mov edx, dword ptr [0042660C]

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004124FF(C)
|
:004124F3 0FBE2C38 movsx ebp, byte ptr [eax+edi] ----依次將使用者名稱位元組轉換為ascii送ebp
:004124F7 0FAFEA imul ebp, edx ----ebp*edx的值送ebp (edx=34)
:004124FA 03CD add ecx, ebp ----ecx+ebp的值送ecx
:004124FC 40 inc eax ----eax加1
:004124FD 3BC6 cmp eax, esi ----是否計算完畢
:004124FF 7CF2 jl 004124F3 ----迴圈

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004124EB(C)
|
:00412501 51 push ecx
:00412502 8D4C2414 lea ecx, dword ptr [esp+14]

* Possible StringData Ref from Data Obj ->"%ld-" ----加入分隔符"-"
|
:00412506 681C664200 push 0042661C
:0041250B 51 push ecx

* Reference To: USER32.wsprintfA, Ord:02D6h
|
:0041250C FF1520034200 Call dword ptr [00420320]
:00412512 83C40C add esp, 0000000C
:00412515 8D542410 lea edx, dword ptr [esp+10]
:00412519 52 push edx
:0041251A 53 push ebx

* Reference To: KERNEL32.lstrcatA, Ord:039Fh
|
:0041251B FF1520024200 Call dword ptr [00420220]
:00412521 33C9 xor ecx, ecx
:00412523 33C0 xor eax, eax
:00412525 85F6 test esi, esi
:00412527 7E13 jle 0041253C
:00412529 8B1510664200 mov edx, dword ptr [00426610]

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041253A(C)
|
:0041252F 0FBE2C38 movsx ebp, byte ptr [eax+edi] ----依次將使用者名稱位元組轉換為ascii送
:00412533 03EA add ebp, edx            ----ebp+edx的值送ebp (edx=0C)
:00412535 03CD add ecx, ebp        ----ecx+ebp的值送ecx
:00412537 40 inc eax            ----eax加1
:00412538 3BC6 cmp eax, esi            ----是否計算完畢
:0041253A 7CF3 jl 0041252F ----迴圈

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00412527(C)
|
:0041253C 51 push ecx
:0041253D 8D442414 lea eax, dword ptr [esp+14]

* Possible StringData Ref from Data Obj ->"%ld-"    ----加入分隔符"-"
|
:00412541 681C664200 push 0042661C
:00412546 50 push eax

* Reference To: USER32.wsprintfA, Ord:02D6h
|
:00412547 FF1520034200 Call dword ptr [00420320]
:0041254D 83C40C add esp, 0000000C
:00412550 8D4C2410 lea ecx, dword ptr [esp+10]
:00412554 51 push ecx
:00412555 53 push ebx

* Reference To: KERNEL32.lstrcatA, Ord:039Fh
|
:00412556 FF1520024200 Call dword ptr [00420220]
:0041255C 33C9 xor ecx, ecx
:0041255E 33C0 xor eax, eax
:00412560 85F6 test esi, esi
:00412562 7E14 jle 00412578
:00412564 8B1514664200 mov edx, dword ptr [00426614]

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00412576(C)
|
:0041256A 0FBE2C38 movsx ebp, byte ptr [eax+edi]
:0041256E 0FAFEA imul ebp, edx            ----ebp*edx的值送ebp (edx=0E)
:00412571 03CD add ecx, ebp        ----ecx+ebp的值送ecx
:00412573 40 inc eax            ----eax加1
:00412574 3BC6 cmp eax, esi            ----是否計算完畢
:00412576 7CF2 jl 0041256A            ----迴圈

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00412562(C)
|
:00412578 51 push ecx
:00412579 8D542414 lea edx, dword ptr [esp+14]

* Possible StringData Ref from Data Obj ->"%ld"        ----加入分隔符"-"
|
:0041257D 6818664200 push 00426618
:00412582 52 push edx

* Reference To: USER32.wsprintfA, Ord:02D6h
|
:00412583 FF1520034200 Call dword ptr [00420320]
:00412589 83C40C add esp, 0000000C
:0041258C 8D442410 lea eax, dword ptr [esp+10]
:00412590 50 push eax
:00412591 53 push ebx

* Reference To: KERNEL32.lstrcatA, Ord:039Fh
|
:00412592 FF1520024200 Call dword ptr [00420220]
:00412598 5F pop edi
:00412599 5E pop esi
:0041259A 5D pop ebp
:0041259B 5B pop ebx
:0041259C 81C400010000 add esp, 00000100
:004125A2 C3 ret
.
.
.
恕我剛加入"風飄雪",彙編知識不太豐富,所以大部分演算法都是自己亂猜的.分析如有錯誤,歡迎指出.

#############################################################################################################################


因為對OllyDbg的使用還不熟悉,所以在對選擇"KERNEL32.lstrcmpA"時使用了滑鼠雙擊命令(沒有使用回車),致使無法彈出"References in 'xxsoftwarename'"介面.一廂情願的認為該命令無效,而採取了另外一種斷點:

"Search for"->"All referenced text strings"查詢出錯提示資訊,找不到!!!!(吐血)
從彈出出錯的對話方塊入手,CTRL+N選擇"USER32.GetDlgItemTextA",回車,選擇最後一項(00411DAE)F2設斷.因為總共有三項,估計前兩項是檢查是否輸入使用者名稱和註冊碼用的,所以不設.


* Reference To: USER32.GetDlgItemTextA, Ord:0113h
|
:00411DAE 8B3D9C024200 mov edi, dword ptr [0042029C] ----停在此處
:00411DB4 8D8C2408010000 lea ecx, dword ptr [esp+00000108]
:00411DBB 6800010000 push 00000100
:00411DC0 51 push ecx

* Possible Reference to Dialog: DialogID_0065, CONTROL_ID:0417, ""
|
:00411DC1 6817040000 push 00000417
:00411DC6 56 push esi
:00411DC7 FFD7 call edi
:00411DC9 8D542408 lea edx, dword ptr [esp+08]
:00411DCD 6800010000 push 00000100
:00411DD2 52 push edx

* Possible Reference to Dialog: DialogID_0065, CONTROL_ID:03FC, ""
|
:00411DD3 68FC030000 push 000003FC
:00411DD8 56 push esi
:00411DD9 FFD7 call edi
:00411DDB 8D442408 lea eax, dword ptr [esp+08] ----假註冊碼
:00411DDF 8D8C2408010000 lea ecx, dword ptr [esp+00000108] ----真使用者名稱(呵呵)
:00411DE6 50 push eax ----壓入假註冊碼
:00411DE7 51 push ecx ----壓入使用者名稱
:00411DE8 E8B3050000 call 004123A0 ----所以這裡可疑F7進入,剩下的分析同上
:00411DED 83C408 add esp, 00000008
:00411DF0 85C0 test eax, eax
:00411DF2 5F pop edi
:00411DF3 7443 je 00411E38
:00411DF5 8D542404 lea edx, dword ptr [esp+04]
:00411DF9 8D842404010000 lea eax, dword ptr [esp+00000104]
:00411E00 52 push edx
:00411E01 50 push eax


總結:演算法分析:
註冊碼演算法由四個部分組成:

第一部分演算法:依次取使用者名稱各位元組的ascii碼,轉換成十六進位制,然後和26(十六進位制)乘以使用者名稱長度(十六進位制)的積相加
(A1+A2+An)+(26*使用者名稱長度),再轉換為十進位制.
第二部分演算法:依次取使用者名稱各位元組的ascii碼,轉換成十六進位制,相加之後的和乘以34(十六進位制)
(A1+A2+An)*34
第三部分演算法:依次取使用者名稱各位元組的ascii碼,轉換成十六進位制,然後和0C(十六進位制)乘以使用者名稱長度(十六進位制)的積相加
(A1+A2+An)+(0C*使用者名稱長度),再轉換為十進位制.
第四部分演算法:依次取使用者名稱各位元組的ascii碼,轉換成十六進位制,相加之後的和乘以0E(十六進位制)
(A1+A2+An)*0E
將四個部分的註冊碼使用分隔符"-"連線


將這個軟體翻來覆去搞了一個下午.
突然發現用英文名註冊才會出現以上破文所寫的註冊碼,
但是中文卻需要新增兩個分隔符"--",而且註冊碼的首個位元組也是"-"
黔驢技窮了!
這是我第一次寫演算法分析,每個演算法部分都是靠多次使用OllyDbg演練猜測得出的結果,遺憾的是隻能適合英文使用者名稱註冊.

後記:使用了OllyDbg,越發感覺它的強大和方便易用.真希望風飄雪老師能多寫幾篇OllyDbg的教程.

相關文章