破解FlashGet1.65的過程

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

一、首先是瞭解flashget 1.65的註冊原理

flashget(以下簡稱fg)是先填寫註冊碼,
填寫好了以後fg會把註冊碼儲存在登錄檔裡面,
例如:

[HKEY_CURRENT_USER\Software\JetCar\JetCar\General]
"RegPass"="aabbccdd"

然後在下次啟動的時候檢查註冊碼是否正確來確定是否顯示廣告條。

二、破解原理

在除錯工具中(我用的是ollydbg v1.10 http://home.t-online.de/home/Ollydbg/)
找到有關注冊的那部分,然後進行跟蹤,分析fg是如何判斷是否註冊的

三、ollydbg(以下簡稱odbg)使用簡單介紹

開啟odbg,open一個程式,odbg會自動會程式進行反彙編,
反彙編結束以後,你會看到整個視窗被分成了四個部分
左上角的用於顯示反編譯的程式碼
右上角的用於顯示暫存器資料
左下角顯示當前所載入的軟體資料在記憶體中的位置
右下角顯示被各種函式所使用的記憶體

四、破解

1、先用ollydbg開啟flashget.exe,odbg自動對fg反彙編,
然後就能看到flashget.exe的彙編程式碼
下面要找到註冊相關的部分,我們就來查詢RegPass這個欄位

在反彙編出來的程式碼視窗中點右鍵,選擇“Search for->All referencd text strings”
彈出一個視窗,都是referencd text strings,點右鍵,選擇“search for text”。
這裡注意他只會往下找,所以要把游標移動到最上面再查詢
填入RegPass,注意大小寫。
一共找到兩個,現在要排除一個。
都設定成斷點(f2)
然後run(f9),發現到0041dce6的那個斷點停下了,說明是fg啟動時候呼叫的
取消這個斷點,restart,run,發現fg介面出來了,說明另外一個斷點應該是存入用的
而前面一個斷點應該就是關鍵了

我們可以把這個地方加入bookmark,以後就可以方便的使用alt+數字轉到這裡

2、分析附近程式碼
觀察附近的程式碼(空指令nop),以及左邊的大括號(一個子程式)
發現以下程式碼,先不要仔細看:

0041DC80  /$ 6A FF          PUSH -1
0041DC82  |. 68 20334F00    PUSH flashget.004F3320                   ;  SE handler installation
0041DC87  |. 64:A1 00000000 MOV EAX,DWORD PTR FS:[0]
0041DC8D  |. 50             PUSH EAX
0041DC8E  |. 64:8925 000000>MOV DWORD PTR FS:[0],ESP
0041DC95  |. 83EC 20        SUB ESP,20
0041DC98  |. 53             PUSH EBX
0041DC99  |. 55             PUSH EBP
0041DC9A  |. 56             PUSH ESI
0041DC9B  |. 57             PUSH EDI
0041DC9C  |. 68 E8B85300    PUSH flashget.0053B8E8
0041DCA1  |. 68 A0E55200    PUSH flashget.0052E5A0                   ;  ASCII "RegName"
0041DCA6  |. 8D4424 18      LEA EAX,DWORD PTR SS:[ESP+18]
0041DCAA  |. 8BE9           MOV EBP,ECX
0041DCAC  |. 68 A0C15200    PUSH flashget.0052C1A0                   ;  ASCII "General"
0041DCB1  |. 50             PUSH EAX
0041DCB2  |. 896C24 28      MOV DWORD PTR SS:[ESP+28],EBP
0041DCB6  |. E8 95C70C00    CALL flashget.004EA450
0041DCBB  |. 8DB5 60030000  LEA ESI,DWORD PTR SS:[EBP+360]
0041DCC1  |. 50             PUSH EAX
0041DCC2  |. 8BCE           MOV ECX,ESI
0041DCC4  |. C74424 3C 0000>MOV DWORD PTR SS:[ESP+3C],0
0041DCCC  |. E8 83660B00    CALL flashget.004D4354
0041DCD1  |. 83CF FF        OR EDI,FFFFFFFF
0041DCD4  |. 8D4C24 10      LEA ECX,DWORD PTR SS:[ESP+10]
0041DCD8  |. 897C24 38      MOV DWORD PTR SS:[ESP+38],EDI
0041DCDC  |. E8 3A650B00    CALL flashget.004D421B
0041DCE1  |. 68 E8B85300    PUSH flashget.0053B8E8
0041DCE6  |. 68 98E55200    PUSH flashget.0052E598                   ;  ASCII "RegPass"
0041DCEB  |. 8D4C24 1C      LEA ECX,DWORD PTR SS:[ESP+1C]
0041DCEF  |. 68 A0C15200    PUSH flashget.0052C1A0                   ;  ASCII "General"
0041DCF4  |. 51             PUSH ECX
0041DCF5  |. 8BCD           MOV ECX,EBP
0041DCF7  |. E8 54C70C00    CALL flashget.004EA450
0041DCFC  |. 81C5 64030000  ADD EBP,364
0041DD02  |. BB 01000000    MOV EBX,1
0041DD07  |. 50             PUSH EAX
0041DD08  |. 8BCD           MOV ECX,EBP
0041DD0A  |. 895C24 3C      MOV DWORD PTR SS:[ESP+3C],EBX
0041DD0E  |. E8 41660B00    CALL flashget.004D4354
0041DD13  |. 8D4C24 14      LEA ECX,DWORD PTR SS:[ESP+14]
0041DD17  |. 897C24 38      MOV DWORD PTR SS:[ESP+38],EDI
0041DD1B  |. E8 FB640B00    CALL flashget.004D421B
0041DD20  |. 8B16           MOV EDX,DWORD PTR DS:[ESI]
0041DD22  |. 8B42 F8        MOV EAX,DWORD PTR DS:[EDX-8]
0041DD25  |. 85C0           TEST EAX,EAX
0041DD27  |. 0F84 4E010000  JE flashget.0041DE7B
0041DD2D  |. 8B45 00        MOV EAX,DWORD PTR SS:[EBP]
0041DD30  |. 8B48 F8        MOV ECX,DWORD PTR DS:[EAX-8]
0041DD33  |. 85C9           TEST ECX,ECX
0041DD35  |. 0F84 40010000  JE flashget.0041DE7B
0041DD3B  |. 8BCE           MOV ECX,ESI
0041DD3D  |. E8 89210B00    CALL flashget.004CFECB
0041DD42  |. 8BCE           MOV ECX,ESI
0041DD44  |. E8 36210B00    CALL flashget.004CFE7F
0041DD49  |. 8B0E           MOV ECX,DWORD PTR DS:[ESI]
0041DD4B  |. 8379 F8 05     CMP DWORD PTR DS:[ECX-8],5
0041DD4F  |. 0F8E 26010000  JLE flashget.0041DE7B
0041DD55  |. 68 BCE55200    PUSH flashget.0052E5BC
0041DD5A  |. 8BCE           MOV ECX,ESI
0041DD5C  |. E8 851D0B00    CALL flashget.004CFAE6
0041DD61  |. 85C0           TEST EAX,EAX
0041DD63  |. 0F8C 12010000  JL flashget.0041DE7B
0041DD69  |. 68 B8E55200    PUSH flashget.0052E5B8
0041DD6E  |. 8BCE           MOV ECX,ESI
0041DD70  |. E8 711D0B00    CALL flashget.004CFAE6
0041DD75  |. 85C0           TEST EAX,EAX
0041DD77  |. 0F8C FE000000  JL flashget.0041DE7B
0041DD7D  |. 8BCD           MOV ECX,EBP
0041DD7F  |. E8 47210B00    CALL flashget.004CFECB
0041DD84  |. 8BCD           MOV ECX,EBP
0041DD86  |. E8 F4200B00    CALL flashget.004CFE7F
0041DD8B  |. 8B55 00        MOV EDX,DWORD PTR SS:[EBP]
0041DD8E  |. 8B42 F8        MOV EAX,DWORD PTR DS:[EDX-8]
0041DD91  |. 83F8 2C        CMP EAX,2C
0041DD94  |. 0F85 E1000000  JNZ flashget.0041DE7B
0041DD9A  |. 68 B0E55200    PUSH flashget.0052E5B0                   ;  ASCII "fgc-"
0041DD9F  |. 8BCD           MOV ECX,EBP
0041DDA1  |. E8 401D0B00    CALL flashget.004CFAE6
0041DDA6  |. 85C0           TEST EAX,EAX
0041DDA8  |. 75 06          JNZ SHORT flashget.0041DDB0
0041DDAA  |. 895C24 10      MOV DWORD PTR SS:[ESP+10],EBX
0041DDAE  |. EB 18          JMP SHORT flashget.0041DDC8
0041DDB0  |> 68 A8E55200    PUSH flashget.0052E5A8                   ;  ASCII "fgf-"
0041DDB5  |. 8BCD           MOV ECX,EBP
0041DDB7  |. E8 2A1D0B00    CALL flashget.004CFAE6
0041DDBC  |. 85C0           TEST EAX,EAX
0041DDBE  |. 0F85 B7000000  JNZ flashget.0041DE7B
0041DDC4  |. 894424 10      MOV DWORD PTR SS:[ESP+10],EAX
0041DDC8  |> 6A 2C          PUSH 2C
0041DDCA  |. 8BCD           MOV ECX,EBP
0041DDCC  |. E8 7A680B00    CALL flashget.004D464B
0041DDD1  |. 8BF8           MOV EDI,EAX
0041DDD3  |. 33C9           XOR ECX,ECX
0041DDD5  |. 83C7 04        ADD EDI,4
0041DDD8  |. 33F6           XOR ESI,ESI
0041DDDA  |> 8B07           /MOV EAX,DWORD PTR DS:[EDI]
0041DDDC  |. 8BD6           |MOV EDX,ESI
0041DDDE  |. 83C7 04        |ADD EDI,4
0041DDE1  |. 83EA 00        |SUB EDX,0                               ;  Switch (cases 0..2)
0041DDE4  |. 894424 1C      |MOV DWORD PTR SS:[ESP+1C],EAX
0041DDE8  |. 74 26          |JE SHORT flashget.0041DE10
0041DDEA  |. 4A             |DEC EDX
0041DDEB  |. 74 17          |JE SHORT flashget.0041DE04
0041DDED  |. 4A             |DEC EDX
0041DDEE  |. 75 38          |JNZ SHORT flashget.0041DE28
0041DDF0  |. 0FBE4C24 1E    |MOVSX ECX,BYTE PTR SS:[ESP+1E]          ;  Case 2 of switch 0041DDE1
0041DDF5  |. 0FBED4         |MOVSX EDX,AH
0041DDF8  |. 0FAFCA         |IMUL ECX,EDX
0041DDFB  |. 0FBE5424 1F    |MOVSX EDX,BYTE PTR SS:[ESP+1F]
0041DE00  |. 03CA           |ADD ECX,EDX
0041DE02  |. EB 1F          |JMP SHORT flashget.0041DE23
0041DE04  |> 0FBE4C24 1E    |MOVSX ECX,BYTE PTR SS:[ESP+1E]          ;  Case 1 of switch 0041DDE1
0041DE09  |. 0FBED4         |MOVSX EDX,AH
0041DE0C  |. 23CA           |AND ECX,EDX
0041DE0E  |. EB 0B          |JMP SHORT flashget.0041DE1B
0041DE10  |> 8A4C24 1E      |MOV CL,BYTE PTR SS:[ESP+1E]             ;  Case 0 of switch 0041DDE1
0041DE14  |. 8AD4           |MOV DL,AH
0041DE16  |. 33CA           |XOR ECX,EDX
0041DE18  |. 83E1 7F        |AND ECX,7F
0041DE1B  |> 0FBE5424 1F    |MOVSX EDX,BYTE PTR SS:[ESP+1F]
0041DE20  |. 0FAFCA         |IMUL ECX,EDX
0041DE23  |> 0FBEC0         |MOVSX EAX,AL
0041DE26  |. 03C8           |ADD ECX,EAX
0041DE28  |> 8B4424 10      |MOV EAX,DWORD PTR SS:[ESP+10]           ;  Default case of switch 0041DDE1
0041DE2C  |. 85C0           |TEST EAX,EAX
0041DE2E  |. 74 0C          |JE SHORT flashget.0041DE3C
0041DE30  |. 0FBE1D 2BC7520>|MOVSX EBX,BYTE PTR DS:[52C72B]
0041DE37  |. 83FE 02        |CMP ESI,2
0041DE3A  |. 74 07          |JE SHORT flashget.0041DE43
0041DE3C  |> 0FBE9E 28C7520>|MOVSX EBX,BYTE PTR DS:[ESI+52C728]
0041DE43  |> 8BC1           |MOV EAX,ECX
0041DE45  |. 33D2           |XOR EDX,EDX
0041DE47  |. F7F3           |DIV EBX
0041DE49  |. 8BC6           |MOV EAX,ESI
0041DE4B  |. 83E8 00        |SUB EAX,0                               ;  Switch (cases 0..2)
0041DE4E  |. 74 13          |JE SHORT flashget.0041DE63
0041DE50  |. 48             |DEC EAX
0041DE51  |. 74 09          |JE SHORT flashget.0041DE5C
0041DE53  |. 48             |DEC EAX
0041DE54  |. 75 11          |JNZ SHORT flashget.0041DE67
0041DE56  |. 85D2           |TEST EDX,EDX                            ;  Case 2 of switch 0041DE4B
0041DE58  |. 75 18          |JNZ SHORT flashget.0041DE72
0041DE5A  |. EB 0B          |JMP SHORT flashget.0041DE67
0041DE5C  |> 83FA 08        |CMP EDX,8                               ;  Case 1 of switch 0041DE4B
0041DE5F  |. 75 11          |JNZ SHORT flashget.0041DE72
0041DE61  |. EB 04          |JMP SHORT flashget.0041DE67
0041DE63  |> 85D2           |TEST EDX,EDX                            ;  Case 0 of switch 0041DE4B
0041DE65  |. 75 0B          |JNZ SHORT flashget.0041DE72
0041DE67  |> 46             |INC ESI                                 ;  Default case of switch 0041DE4B
0041DE68  |. 83FE 03        |CMP ESI,3
0041DE6B  |. 7D 23          |JGE SHORT flashget.0041DE90
0041DE6D  |.^E9 68FFFFFF    \JMP flashget.0041DDDA
0041DE72  |> 6A FF          PUSH -1
0041DE74  |. 8BCD           MOV ECX,EBP
0041DE76  |. E8 1F680B00    CALL flashget.004D469A
0041DE7B  |> 5F             POP EDI
0041DE7C  |. 5E             POP ESI
0041DE7D  |. 5D             POP EBP
0041DE7E  |. 33C0           XOR EAX,EAX
0041DE80  |. 5B             POP EBX
0041DE81  |. 8B4C24 20      MOV ECX,DWORD PTR SS:[ESP+20]
0041DE85  |. 64:890D 000000>MOV DWORD PTR FS:[0],ECX
0041DE8C  |. 83C4 2C        ADD ESP,2C
0041DE8F  |. C3             RETN
0041DE90  |> 6A FF          PUSH -1
0041DE92  |. 8BCD           MOV ECX,EBP
0041DE94  |. E8 01680B00    CALL flashget.004D469A
0041DE99  |. 8B45 00        MOV EAX,DWORD PTR SS:[EBP]
0041DE9C  |. 8B4C24 18      MOV ECX,DWORD PTR SS:[ESP+18]
0041DEA0  |. 6A 01          PUSH 1
0041DEA2  |. 50             PUSH EAX
0041DEA3  |. 68 A0C15200    PUSH flashget.0052C1A0                   ;  ASCII "General"
0041DEA8  |. E8 37C50C00    CALL flashget.004EA3E4
0041DEAD  |. 8B4C24 30      MOV ECX,DWORD PTR SS:[ESP+30]
0041DEB1  |. 5F             POP EDI
0041DEB2  |. F7D8           NEG EAX
0041DEB4  |. 1BC0           SBB EAX,EAX
0041DEB6  |. 5E             POP ESI
0041DEB7  |. 5D             POP EBP
0041DEB8  |. 5B             POP EBX
0041DEB9  |. F7D8           NEG EAX
0041DEBB  |. 64:890D 000000>MOV DWORD PTR FS:[0],ECX
0041DEC2  |. 83C4 2C        ADD ESP,2C
0041DEC5  \. C3             RETN

以上的程式碼就是判斷RegPass是否正確的子程式了
我們再精簡一下,只留下跳轉語句、返回語句和跳轉到的語句:

0041DC80  /$ 6A FF          PUSH -1
0041DD27  |. 0F84 4E010000  JE flashget.0041DE7B                     ;沒有regpass的話在這裡就跳了
0041DD35  |. 0F84 40010000  JE flashget.0041DE7B
0041DD4F  |. 0F8E 26010000  JLE flashget.0041DE7B
0041DD63  |. 0F8C 12010000  JL flashget.0041DE7B
0041DD77  |. 0F8C FE000000  JL flashget.0041DE7B
0041DD94  |. 0F85 E1000000  JNZ flashget.0041DE7B                    ;如果有個隨便寫的註冊碼的話在這裡跳
0041DDA8  |. 75 06          JNZ SHORT flashget.0041DDB0
0041DDAE  |. EB 18          JMP SHORT flashget.0041DDC8
0041DDB0  |> 68 A8E55200    PUSH flashget.0052E5A8                   ;  ASCII "fgf-"
0041DDBE  |. 0F85 B7000000  JNZ flashget.0041DE7B
0041DDC8  |> 6A 2C          PUSH 2C
0041DDDA  |> 8B07           /MOV EAX,DWORD PTR DS:[EDI]
0041DDE8  |. 74 26          |JE SHORT flashget.0041DE10
0041DDEB  |. 74 17          |JE SHORT flashget.0041DE04
0041DDEE  |. 75 38          |JNZ SHORT flashget.0041DE28
0041DE02  |. EB 1F          |JMP SHORT flashget.0041DE23
0041DE04  |> 0FBE4C24 1E    |MOVSX ECX,BYTE PTR SS:[ESP+1E]          ;  Case 1 of switch 0041DDE1
0041DE0E  |. EB 0B          |JMP SHORT flashget.0041DE1B
0041DE10  |> 8A4C24 1E      |MOV CL,BYTE PTR SS:[ESP+1E]             ;  Case 0 of switch 0041DDE1
0041DE1B  |> 0FBE5424 1F    |MOVSX EDX,BYTE PTR SS:[ESP+1F]
0041DE23  |> 0FBEC0         |MOVSX EAX,AL
0041DE28  |> 8B4424 10      |MOV EAX,DWORD PTR SS:[ESP+10]           ;  Default case of switch 0041DDE1
0041DE2E  |. 74 0C          |JE SHORT flashget.0041DE3C
0041DE3A  |. 74 07          |JE SHORT flashget.0041DE43
0041DE3C  |> 0FBE9E 28C7520>|MOVSX EBX,BYTE PTR DS:[ESI+52C728]
0041DE43  |> 8BC1           |MOV EAX,ECX
0041DE4E  |. 74 13          |JE SHORT flashget.0041DE63
0041DE51  |. 74 09          |JE SHORT flashget.0041DE5C
0041DE54  |. 75 11          |JNZ SHORT flashget.0041DE67
0041DE58  |. 75 18          |JNZ SHORT flashget.0041DE72
0041DE5A  |. EB 0B          |JMP SHORT flashget.0041DE67
0041DE5C  |> 83FA 08        |CMP EDX,8                               ;  Case 1 of switch 0041DE4B
0041DE5F  |. 75 11          |JNZ SHORT flashget.0041DE72
0041DE61  |. EB 04          |JMP SHORT flashget.0041DE67
0041DE63  |> 85D2           |TEST EDX,EDX                            ;  Case 0 of switch 0041DE4B
0041DE65  |. 75 0B          |JNZ SHORT flashget.0041DE72
0041DE67  |> 46             |INC ESI                                 ;  Default case of switch 0041DE4B
0041DE6B  |. 7D 23          |JGE SHORT flashget.0041DE90
0041DE6D  |.^E9 68FFFFFF    \JMP flashget.0041DDDA
0041DE72  |> 6A FF          PUSH -1
0041DE7B  |> 5F             POP EDI                                  ;這裡已經判斷是沒註冊的了
0041DE8F  |. C3             RETN                                     ;這裡返回,跳出了檢查註冊碼的子函式,返回到了004128EB
0041DE90  |> 6A FF          PUSH -1
0041DEC5  \. C3             RETN

分析一下,可以發現:
a、很多跳轉是到的0041DE7B。跳到0041DE7B以後,就是一個retn,返回了。
而這裡返回就是被發現是未註冊的了。
b、其他跳轉都是在內部跳的,都是迴圈,不會跳出去,除了一個:
0041DE6B JGE SHORT flashget.0041DE90
他跳到了0041DE90,然後就是一個返回,所以說只可能這個是註冊的返回。

現在,我們可以對上面的這個子程式做一個總體分析,
0041DC80-0041DDD8是初始判斷
而0041DDDA-0041DE6D是進階判斷
0041DE7B-0041DE8F是註冊碼錯誤時的返回
0041DE90-0041DEC5是註冊碼正確時的返回

所以我們只要在一開始就跳到0041DE90就可以了
我的方法是在0041DD27把JE 0041DE7B修改成jmp 0041DE90
在odbg裡面修改以後,記錄二進位制程式碼為E96401000090

五、修改檔案

用WinHex或者UltraEdit修改
找到0001DD27(0041DD27)
把0F844E010000修改成E96401000090
OK,成功!

說明:

fg1.65和網上說的前面幾個版本不同,不能直接從暫存器裡面得到註冊碼的
而是透過對你提供的註冊碼的一步步迴圈的計算來判斷是否正確
所以這裡只是修改檔案,並沒有找出註冊碼的計算方法。
以前使用算號器,過了一段時候以後又會出現廣告
據lucian說,是fg會上網驗證的
所以還是直接修改檔案保險、簡單。

後記:

後來看了一下呼叫這個子程式的程式碼004128EB附近的程式碼
發現這個子程式的作用就是當註冊碼錯誤時,使EAX為0;
當註冊碼正確時(經上述5步破解),使EAX為1,然後
004128f2 MOV DWORD PTR SS:[EBP+284],EAX
只要令DWORD PTR SS:[EBP+284](0053bb74)不為0就去了廣告
修改MOV DWORD PTR SS:[EBP+284],EAX為MOV DWORD PTR SS:[EBP+284],ECX
更或者004128EB CALL 0041DC80改成nop或者CALL 00425790(mov eax,1)
這樣也少執行一段程式碼。

一開始我用的是w32dasm反編譯的,
因為發現它比較容易上手,但是除錯不太方便,太佔cpu,反彙編太慢;
而odbg介面比較複雜,除錯比較方便,所以開始我是兩種工具結合使用的,
而後來隨著對odbg的熟悉,全部使用odbg完成。

相關文章