FolderView 1.7 註冊演算法分析 (14千字)
FolderView 1.7 註冊演算法分析
破解目標:FolderView 1.7
官方主頁:http://www.southbaypc.com/
軟體簡介:這是一個簡單易用的小工具,可以將資料夾當中的每個檔案,依照大小(byte)、日期、名稱作詳細列表,並匯出成TXT純文字檔案或者將檔案資料打列出來。
下載地址:http://hn-down.skycn.net/down/fvsetup.exe
使用工具:W32Dasm、Ollydbg、Windows
自帶的計算器
作者:炎之川
時間:2003.3.3
主頁:http://skipli.yeah.net/
宣告: 此文僅用於學習及交流,若要轉載請保持文章完整。
我的第三篇演算法分析,前兩篇都是crackme,而這篇文章的分析目標是共享軟體,不過演算法不算難。分析沒有花太多時間,而寫文章卻花費了很長的時間...
用 PEiD 0.8 檢查可知檔案未加殼。用 W32Dasm 反彙編並初步分析,先在串式參考中找到註冊碼錯誤的提示:“Sorry,
you have entered an incorrect registration code.”,雙擊來到下面的程式碼段:
* Referenced
by a (U)nconditional or (C)onditional Jump at Address:
|:00407424(C)
//呼叫之處,右鍵雙擊之...
|
:00407469 6A00
push 00000000
* Possible StringData Ref
from Data Obj ->"FolderView"
|
:0040746B
6874354100 push 00413574
* Possible StringData Ref from Data Obj ->"Sorry, you have entered an incorrect
"
->"registration
code."
|
:00407470 68083A4100
push 00413A08
:00407475 56
push esi
來到這裡:
* Reference To: USER32.GetDlgItemTextA, Ord:0113h
|
:004073EC 8B3D1C124100
mov edi, dword ptr [0041121C]
:004073F2 68EF030000
push 000003EF
:004073F7 56
push esi
:004073F8 FFD7
call edi
:004073FA 8D542408
lea edx, dword ptr [esp+08]
:004073FE 6800010000
push 00000100
:00407403 52
push edx
:00407404
68ED030000 push 000003ED
:00407409 56
push esi
:0040740A FFD7
call edi
:0040740C 8D442408
lea eax, dword ptr [esp+08]
:00407410 8D8C2408010000
lea ecx, dword ptr [esp+00000108]
:00407417 50
push eax
:00407418 51
push ecx
:00407419 E882030000
call 004077A0 //我們在這裡下斷點
:0040741E 83C408
add esp, 00000008
:00407421
85C0 test
eax, eax
:00407423 5F
pop edi
:00407424 7443
je 00407469 //光棒停在這裡
:00407426 8D542404
lea edx, dword ptr [esp+04]
:0040742A 8D842404010000 lea eax, dword ptr
[esp+00000104]
:00407431 52
push edx
:00407432 50
push eax
可知程式使用 GetDlgItemTextA
來取輸入的字元,且我們可以在 407419 處下斷點。
Ollydbg 載入檔案,在 407419 處按 F2 下斷點,然後 ctrl+F2
重新開始,F9 執行程式,填入註冊名和假註冊碼,我填入:
Name: lovefire
S/N: 78787878
按 Check,被 Ollydbg 斷下,
(; 後是 Ollydbg 所分析的內容,// 後是我加的註釋)
004073FE
. 68 00010000 PUSH 100
; /Count
= 100 (256.)
00407403 . 52
PUSH EDX
; |Buffer
00407404
. 68 ED030000 PUSH 3ED
; |ControlID
= 3ED (1005.)
00407409 . 56
PUSH ESI
; |hWnd
0040740A .
FFD7 CALL EDI
; \GetDlgItemTextA
0040740C . 8D4424 08 LEA
EAX, DWORD PTR SS:[ESP+8] //取假碼到 EAX
00407410 .
8D8C24 080100>LEA ECX, DWORD PTR SS:[ESP+108] //取註冊名到 ECX
00407417 . 50 PUSH
EAX //假碼入棧,保留到最後比較
00407418 . 51
PUSH ECX //註冊名入棧
00407419 .
E8 82030000 CALL FolderVi.004077A0 //F7 跟進
0040741E
. 83C4 08 ADD ESP, 8
00407421
. 85C0 TEST EAX, EAX
00407423 . 5F POP
EDI
00407424 . 74 43 JE
SHORT FolderVi.00407469
----------------------------------------------------------------
進入 407419 的call
004077A0 /$ 8B4C24 04
MOV ECX, DWORD PTR SS:[ESP+4]
004077A4 |. 81EC 00010000
SUB ESP, 100
004077AA |. 8D4424 00
LEA EAX, DWORD PTR SS:[ESP]
004077AE |. 50
PUSH EAX
004077AF |.
51 PUSH ECX
004077B0
|. E8 AB000000 CALL FolderVi.00407860
004077B5
|. 8B8424 100100>MOV EAX, DWORD PTR SS:[ESP+110]
004077BC
|. 8D5424 08 LEA EDX, DWORD PTR SS:[ESP+8]
004077C0 |. 52 PUSH
EDX
004077C1 |. 50
PUSH EAX
004077C2 |. E8 89FFFFFF CALL
FolderVi.00407750 //關鍵call,F7 跟進
004077C7 |. F7D8
NEG EAX
004077C9 |.
1BC0 SBB EAX, EAX
004077CB
|. F7D8 NEG EAX
004077CD
|. 81C4 10010000 ADD ESP, 110
004077D3 \.
C3 RETN
----------------------------------------------------------------
進入 4077C2 的call,演算法開始
00407860 /$ 81EC 00010000 SUB
ESP, 100
00407866 |. A0 7C684100 MOV
AL, BYTE PTR DS:[41687C]
0040786B |. 53
PUSH EBX
0040786C |. 55
PUSH EBP
0040786D |.
56 PUSH ESI
0040786E
|. 57 PUSH EDI
0040786F |. 884424 10 MOV BYTE PTR SS:[ESP+10],
AL
00407873 |. B9 3F000000 MOV ECX, 3F
00407878 |. 33C0 XOR
EAX, EAX
0040787A |. 8D7C24 11 LEA
EDI, DWORD PTR SS:[ESP+11]
0040787E |. F3:AB
REP STOS DWORD PTR ES:[EDI]
00407880 |. 66:AB
STOS WORD PTR ES:[EDI]
00407882 |.
AA STOS BYTE PTR ES:[EDI]
00407883 |. 8BBC24 140100>MOV EDI, DWORD PTR SS:[ESP+114]
//取輸入的註冊使用者名稱,放到 edi
0040788A |. 57
PUSH EDI
; /String //edi
入棧
0040788B |. FF15 68114100 CALL DWORD PTR DS:[<&KERNEL32.lstrlen>;
\lstrlenA //取輸入的註冊名長度,然後放到eax(可以透過經過此call後,eax值的變化看出)
00407891
|. 8BF0 MOV ESI, EAX
//註冊名長度送到 esi
00407893 |. 33C9
XOR ECX, ECX //清零
00407895 |. 33C0
XOR EAX, EAX //清零,做計數器
00407897
|. 85F6 TEST ESI, ESI
//比較esi是否為0,即是否已輸入註冊名
00407899 |. 76 13
JBE SHORT FolderVi.004078AE //如果沒有輸入,後果很明顯...;)
//下面開始的第一個迴圈
0040789B |. 8B15 F8394100 MOV EDX, DWORD PTR DS:[4139F8]
//給edx賦值,發現這裡固定是賦值32
004078A1 |> 0FBE1C38
/MOVSX EBX, BYTE PTR DS:[EAX+EDI] //逐位取註冊名的字元,第一次取“l”,即6C
004078A5
|. 03DA |ADD EBX, EDX
//ebx = ebx+edx = 6C+32 = 9E
004078A7 |. 03CB
|ADD ECX, EBX //ecx = ecx+ebx = 0+9E = 9E
004078A9 |. 40 |INC
EAX //eax+1,計數器+1
004078AA |. 3BC6
|CMP EAX, ESI //比較eax與esi,esi 中是整個註冊名長度值,所以這裡比較是否已取完註冊名
004078AC |.^ 72 F3 \JB
SHORT FolderVi.004078A1 //沒有取完就繼續迴圈
//第一個迴圈結束
第一次迴圈完成後得到的ebx的值,放入第二次迴圈繼續計算,每次迴圈最終值放入ecx中。
這個部分的註冊演算法為:
設 ecx 的值從初始到所有迴圈完成,分別為N(0),N(1),N(2),N(3),N(4)...則:
ecx = ((註冊名字元的ASCII值)+32)+N(n-1)
以我填入的註冊名“lovefire”為例:
N(0)
= 0 (初始的 ecx=0)
N(1) = 6C+32+0 = 9E //第一次迴圈,所以N(1-1)=N(0)=0
N(2)
= 6F+32+9E = 13F //第二次迴圈,所以 N(2-1)=N(1)=9E
N(3) = 76+32+13F = 1E7
//以下類推
N(4) = 65+32+1E7 = 27E
N(5) = 66+32+27E = 316
N(6) = 69+32+316
= 3B1
N(7) = 72+32+3B1 = 455
N(8) = 65+32+455 = 4EC = 1260(十進位制)
接下來一段是對這個算出來的數做一些處理:
004078AE |> 8B9C24 180100>MOV
EBX, DWORD PTR SS:[ESP+118]
004078B5 |. 51
PUSH ECX
; /<%u>
//ecx 入棧
004078B6 |. 68 503A4100 PUSH FolderVi.00413A50
; |Format = "%u-" //格式
004078BB |. 53 PUSH
EBX
; |s
004078BC |. FF15 0C124100
CALL DWORD PTR DS:[<&USER32.wsprintfA>; \wsprintfA //給ecx的數值後加上“-”符號
到此處得到一個值“1260-”。
然後開始進行第二個迴圈,先是一些準備事項:
004078C2
|. 83C4 0C ADD ESP, 0C
004078C5
|. 33C9 XOR ECX, ECX
//清零
004078C7 |. 33C0 XOR
EAX, EAX //清零
004078C9 |. 85F6
TEST ESI, ESI //比較esi是否為0,即是否已輸入註冊名
004078CB
|. 76 14 JBE SHORT FolderVi.004078E1
//如果沒有輸入,後果很明顯...;)
//下面開始第二個迴圈
004078CD |. 8B15 FC394100
MOV EDX, DWORD PTR DS:[4139FC] //給 edx 賦值,這個值是固定的,為 28
004078D3 |> 0FBE2C38 /MOVSX EBP, BYTE PTR
DS:[EAX+EDI] //逐位取註冊名的字元,第一次取“l”,即6C,放到 ebp
004078D7 |.
0FAFEA |IMUL EBP, EDX //ebp = ebp*edx
004078DA |. 03CD |ADD
ECX, EBP //ecx = ecx+ebp
004078DC |. 40
|INC EAX //eax+1,計數器+1
004078DD
|. 3BC6 |CMP EAX, ESI
//是否已取完註冊名?
004078DF |.^ 72 F2 \JB
SHORT FolderVi.004078D3 //沒有取完就繼續迴圈
//迴圈完成
這個部分的註冊演算法為:
設 ecx 的值從初始到所有迴圈完成,分別為N(0),N(1),N(2),N(3),N(4)...則:
ecx=(註冊名字元的ASCII值)*28+N(n-1)
以我填入的註冊名“lovefire”為例:
N(0) = 0 (初始的 ecx=0)
N(1) = 6C*28+0
= 10E0 //第一次迴圈,所以N(1-1)=N(0)=0
N(2) = 6F*28+ 10E0 = 2238 //第二次迴圈,所以
N(2-1)=N(1)=10E0
N(3) = 76*28+ 2238 = 34A8 //以下類推
N(4) = 65*28+
34A8 = 4470
N(5)= 66*28+ 4470 = 5460
N(6) = 69*28+ 5460 = 64C8
N(7) = 72*28+ 64C8 = 7698
N(8) = 65*28+ 7698 = 8660 = 34400(十進位制)
接下來繼續對得到的數進行一些處理:
004078E1 |> 51
PUSH ECX
; /<%u> = 8660 (34400.)
004078E2 |. 8D4C24 14 LEA ECX, DWORD
PTR SS:[ESP+14] ; |
004078E6 |. 68 503A4100
PUSH FolderVi.00413A50
; |Format = "%u-"
004078EB |. 51
PUSH ECX
; |s
004078EC
|. FF15 0C124100 CALL DWORD PTR DS:[<&USER32.wsprintfA>;
\wsprintfA
//將得到的 34400 加上“-”,得到註冊碼的第二部分 34400-,並放入ecx
004078F2
|. 83C4 0C ADD ESP, 0C
004078F5
|. 8D5424 10 LEA EDX, DWORD PTR SS:[ESP+10]
004078F9 |. 52 PUSH
EDX
; /StringToAdd
004078FA |.
53 PUSH EBX
; |ConcatString
004078FB |. FF15 94114100 CALL
DWORD PTR DS:[<&KERNEL32.lstrcat>; \lstrcatA //和第一次算出的碼合併為“1260-34400-”
至此得到一個新的字串“1260-34400-”。
第三次迴圈:
00407901
|. 33C9 XOR ECX, ECX
00407903 |. 33C0 XOR
EAX, EAX
00407905 |. 85F6 TEST
ESI, ESI
00407907 |. 76 13
JBE SHORT FolderVi.0040791C
//對迴圈3進行一些初始設定,與迴圈1、2類似,不再多做解釋
00407909 |. 8B15 003A4100 MOV EDX, DWORD PTR DS:[413A00]
//給edx賦初始值 1E(固定值)
//下面開始的三次迴圈
0040790F |> 0FBE2C38
/MOVSX EBP, BYTE PTR DS:[EAX+EDI] //逐位取註冊名的字元的ASCII值,放到
ebp
00407913 |. 03EA |ADD
EBP, EDX //ebp = ebp+edx
00407915 |. 03CD
|ADD ECX, EBP //ecx = ecx+ebp
00407917 |. 40 |INC
EAX //計數器+1
00407918 |. 3BC6
|CMP EAX, ESI //比較是否已取完註冊名
0040791A
|.^ 72 F3 \JB SHORT FolderVi.0040790F
//沒有則繼續迴圈
//迴圈結束
這個部分的註冊演算法為:
設 ecx 的值從初始到所有迴圈完成,分別為N(0),N(1),N(2),N(3),N(4)...則:
ecx=(註冊名字元的ASCII值)+1E+N(n-1)
可知,輸入的註冊名“lovefire”,經過迴圈計算後得到一個數“44C”,轉換為十進位制則為“1100”
接下來……
0040791C |> 51
PUSH ECX
; /<%u> = 44C (1100.)
0040791D |. 8D4424 14 LEA EAX, DWORD PTR
SS:[ESP+14] ; |
00407921 |. 68 503A4100
PUSH FolderVi.00413A50
; |Format = "%u-"
00407926 |. 50
PUSH EAX
; |s
00407927
|. FF15 0C124100 CALL DWORD PTR DS:[<&USER32.wsprintfA>;
\wsprintfA
0040792D |. 83C4 0C ADD
ESP, 0C
00407930 |. 8D4C24 10 LEA
ECX, DWORD PTR SS:[ESP+10]
00407934 |. 51
PUSH ECX
; /StringToAdd
00407935 |. 53 PUSH
EBX
; |ConcatString
00407936 |.
FF15 94114100 CALL DWORD PTR DS:[<&KERNEL32.lstrcat>; \lstrcatA
以上分別程式碼先給算出的“1100”加上“-”,得到“1100-”,在和前面的字串合併,得到“1260-34400-1100”
第四次迴圈:
0040793C |. 33C9
XOR ECX, ECX
0040793E |. 33C0
XOR EAX, EAX
00407940 |. 85F6
TEST ESI, ESI
00407942 |.
76 14 JBE SHORT FolderVi.00407958
00407944 |. 8B15 043A4100 MOV EDX, DWORD PTR DS:[413A04]
//給edx賦初始值 0B(固定值)
//迴圈開始
0040794A |> 0FBE2C38
/MOVSX EBP, BYTE PTR DS:[EAX+EDI] //逐位取註冊名的字元的ASCII值,放到 ebp
0040794E |. 0FAFEA |IMUL
EBP, EDX //ebp = ebp*edx
00407951 |. 03CD
|ADD ECX, EBP //ecx = ecx+ebp
00407953
|. 40 |INC EAX
//計數器+1
00407954 |. 3BC6 |CMP
EAX, ESI //比較是否已取完註冊名?
00407956 |.^ 72 F2
\JB SHORT FolderVi.0040794A //沒有則繼續迴圈
//迴圈結束
這個部分的註冊演算法為:
設 ecx 的值從初始到所有迴圈完成,分別為N(0),N(1),N(2),N(3),N(4)...則:
ecx=(註冊名字元的ASCII值)*0B+N(n-1)
可知,輸入的註冊名“lovefire”,經過迴圈計算後得到一個數“24F4”,轉換為十進位制則為“9460”。
00407958 |> 51
PUSH ECX
; /<%u>
00407959 |.
8D5424 14 LEA EDX, DWORD PTR SS:[ESP+14]
; |
0040795D |. 68 6C384100 PUSH FolderVi.0041386C
; |Format = "%u"
00407962
|. 52 PUSH EDX
; |s
00407963 |. FF15 0C124100 CALL
DWORD PTR DS:[<&USER32.wsprintfA>; \wsprintfA
00407969 |.
83C4 0C ADD ESP, 0C
0040796C |.
8D4424 10 LEA EAX, DWORD PTR SS:[ESP+10]
00407970
|. 50 PUSH EAX
; /StringToAdd
00407971 |. 53
PUSH EBX
; |ConcatString
00407972 |. FF15 94114100 CALL DWORD PTR DS:[<&KERNEL32.lstrcat>;
\lstrcatA
以上程式碼將前後算出的數值合併為“1260-34400-1100-9460”,這就是真正的註冊碼。
再繼續往下走,是對比假碼與真碼,先對比真假註冊碼長度,如果相等,則逐位比較,如果輸入的註冊名與計算出的註冊碼相同,則註冊成功,將註冊資訊寫入“HKEY_CURRENT_USER\Software\FolderView\Registration”,分別是"Name"和"Code"兩個子鍵。因為與演算法關係不大,且很容易看懂,所以比較註冊碼這部分的程式碼就不復製出來了;)
至此,FolderView 1.7 註冊演算法分析完成。
一組可用的註冊碼:Name: lovefire
S/N: 1260-34400-1100-9460
;by 炎之川 2003.3.3
相關文章
- FolderView註冊部分的計算 (13千字)2001-05-27View
- CoolClock V1.02註冊演算法分析 ---OCG (14千字)2015-11-15演算法
- S-DEMO2 註冊分析 (14千字)2002-06-25
- EZ MP3 Recorder 1.15 註冊演算法分析 (14千字)2015-11-15演算法
- Personal Antispy 1.14 註冊演算法分析2015-11-15演算法
- Active Ebook Compiler的註冊演算法 (14千字)2001-05-09Compile演算法
- 重新貼過註冊演算法分析 (16千字)2001-10-23演算法
- EffeTech HTTP Sniffer 3.2註冊演算法分析 (5千字)2002-06-24HTTP演算法
- Green Tea 2.60註冊碼演算法分析 (3千字)2000-07-17演算法
- SuperCleaner 2.31註冊碼演算法分析 - OCG (13千字)2002-04-02演算法
- Registry Crawler 4.0註冊碼演算法分析 - OCG
(20千字)2002-04-07演算法
- UltraEdit-32
10註冊碼演算法分析 (19千字)2003-05-17演算法
- 完美解除安裝6.0註冊演算法分析 (2千字)2002-02-27演算法
- Directory Scanner v1.5 註冊演算法分析 (6千字)2015-11-15演算法
- MouseStar V3.01註冊演算法分析 (18千字)2015-11-15演算法
- **********.exe註冊碼演算法分析--高手莫笑 (31千字)2015-11-15演算法
- Cleaner 3.2註冊分析 (18千字)2001-12-09
- 註冊碼演算法 (2千字)2001-01-14演算法
- 給TAE!的小禮物---對DISKdata v3.3.2註冊演算法的分析 (14千字)2001-07-13演算法
- supercleaner註冊演算法分析2015-11-15演算法
- Screen Demo Maker
V3.0註冊演算法分析 (8千字)2002-09-10演算法
- Konvertor 3.03的註冊碼演算法模組的分析
(7千字)2015-11-15演算法
- Magic convertor 2.8註冊碼演算法分析
- OCG (9千字)2015-11-15演算法
- 飄雪動畫秀3.02註冊演算法分析!
(11千字)2015-11-15動畫演算法
- 註冊PSXVIDEO Ver1.12詳細演算法 (14千字)2001-04-11IDE演算法
- ClockWise 3.22e註冊碼演算法分析 - OCG (17千字)2002-04-10演算法
- 〖網際營銷〗V2.4 註冊演算法分析 (11千字)2001-11-03演算法
- GSview V4.12 for Windows註冊演算法分析 -
OCG (8千字)2015-11-15ViewWindows演算法
- 一個區域網工具的註冊演算法分析
(5千字)2015-11-15演算法
- SpeedFlash註冊演算法分析(VB)2015-11-15演算法
- 財智老闆通3.04註冊版---註冊演算法分析2003-03-16演算法
- Instant Source 註冊演算法分析+註冊器原始碼2015-11-15演算法原始碼
- DreamWaver3.0註冊流程分析 (17千字)2001-09-10
- CDSpace Power+註冊演算法 (7千字)2001-07-27演算法
- 《棋隱》的註冊演算法 (19千字)2001-08-26演算法
- Search32-PRO
v6.05註冊演算法分析 - OCG (46千字)2002-04-07演算法
- 五筆輸入通1.x註冊演算法分析
(10千字)2015-11-15演算法
- CPUCOOL 5.1000註冊碼分析 (6千字)2001-01-19