160个Crackme003之4C大法详解
文章目錄
- 查殼
- 去Neg
- 方法一 Timer搜索法
- 方法二 4C法
- Virtual Basic可執行程序結構研究
- Virtual Basic程序框架結構
- TVBHeader結構定義
- AGUTTable(4C的位置)結構定義
- 4C法實戰
- 破解序列號
- 第一步
- 第二步
- 第三步
- 第四步
- 驗證結果
- 編寫注冊機
之前在網上搜索了下關于這個Crackme的分析,好像并沒有看到比較詳細的分析文章,4C法的原理也沒有解釋的很清楚。所以就發出來了。
查殼
程序使用VB5.0寫的無殼
去Neg
程序打開后 會有大概7秒的彈窗
在這7秒內 什么都不能干,所以第一件事就是把這個7秒的neg給去掉
方法一 Timer搜索法
首先將內存定位到程序開始處0x401000
搜索Timer,Timer是VB程序默認的定時器變量,
我們找到Timer之后 在上面的位置可以看到一個0x1B58,這個是計時器的秒數。也就是十進制的7000,7000毫秒就是7秒。所以第一種去Neg的方法就是將0x1B58改為0x0001
但是此種方法也有一定的局限性,如果程序的作者將計時器的默認名稱改掉之后 根本無法在內存中搜索到Timer關鍵字 也就無法下手。下面介紹一種通用的解決方法
方法二 4C法
Virtual Basic可執行程序結構研究
對于Visual Basic5/6編譯生成的程序,不管自然編譯還是偽編譯,其程序入口點處的結構都是一樣的。來到OEP處:
指針0x4067D4指向的結構就是Virtual Basic程序的VBHeader結構,由此伸展開,整個VB程序的框架就在這了。
Virtual Basic程序框架結構
可能的Virtual Basic程序框架結構如圖
TVBHeader結構定義
Signature array[1..4] of char; //00H簽名,必須為VB5! Flagl WORD; //04H.未知標志 LanguageDll array[1..14] of char; //06H語言鏈接庫名,通常為”*"或者vb6chsdll BackLanguageDll array[1..14] of char; //14H.后備語言鏈接庫名 RuntimeDLLVersion WORD; //22H運行庫版本 Languageld DWORD: //24H語言標識 BackupLanguageID DWORD; //28H,未知標志 aSubMain DWORD; //2CH,不為00000000則指向Sub MainO指針 aProjectlnfo DWORD //30H.指針,指向tProjeclnfo結構 Plag2 WORD; //34H未知標志 Flag3 WORD; //36H.未知標志 Flag4 DWORD; //38H未知標志 ThreadSpace DWORD; //3CH.線程空間 Flag5 DWORD; //14H未知標志 ResCount WORD; //44H.數量,表示form與cls文件個數 ImportCount WORD; //46H.數量,引用的ocx、dll文件個數 Flag6 BYTE: //48H未知,可能代表運行時程序所占內存大小 Flag7 BYTE; //49H未知,可能與程序啟動時花費時間有關 Flag8 WORD; //4AH.未知 AGUTTable DWORD; //4CH.指針,指向Form GuI描述表 AExdCompTrble DWORD; //50H指針,指向“引入的ocx、dll文件描述表 Aproicclpescrinion DWORD; //54H,指針;指向tProjectDescriptionTable的指針 OProjectExename DWORD //58H.偏移,Offset ProjectExename OProjectTitle DWORD; //5CH,偏移,Offset Projectitle OHelpFile DWORD; //60H.偏移,Ofset Helpile OProjectName DWORD. //64H.偏移,Offset ProjectNameAGUTTable(4C的位置)結構定義
Signature DWORD //00H.必須是50000000 FomID TGUID //04,可能是以GUID方式命名的formID Index BYTE //24H 窗體的序號 Flag1 BYTE //28H 第一個窗體的啟動標志,可能是90 也可能是10 AGUIDescriptionTable DWORD //48H指針指向以“FFCC…“開始的FormGUI表 Flag3 Dword //4CH.意義不明以AfKayAs.2.Exe為例說明:
其對應每個字節的含義如下表
| 00H | VB5! |
| 04H | |
| 06H | 語言鏈接庫名 |
| 14H | |
| 22H | 04代表msvbvm50.dll版本 |
| 24H | 語言標識 |
| 28H | |
| 2CH | 00000000表示非由sub_main啟動 |
| 30H | 指向ProjectInfo結構 |
| 34H | |
| 36H | |
| 38H | |
| 3CH | |
| 40H | |
| 44H | 只有2個FROM |
| 46H | 引用的OCX DLL文件個數為0 |
| 48H | |
| 49H | |
| 4AH | |
| 4CH | Ptr 0040126C |
| 50H | 若沒有引入的ocx,dll文件,此指針無效 |
| 54H | 指向tProjectDescriptionTable的指針 |
| 58H | ProjectExename |
| 5CH | ProjectTitle |
| 60H | HelpFile |
| 64H | ProjectName |
4C法實戰
在程序載入到入口點之后的第一個push也就是VBHeader的位置,數據窗口跟隨。
然后在數據窗口輸入剛才的地址+4C,找到form GUI描述表的指針
數據窗口跟隨DWORD
接著會來到一塊有規律的數據區域,每一個小塊的數據是每一個窗體的信息,其中00和01是窗體的序號 而10是第一個窗體的啟動標志。
所以 我們只要把第一個窗體數據塊的00改成10 然后把第二個窗體的數據塊的10改成00,或者將窗體的序號調換。即可去除neg。
破解序列號
這個程序和002那個程序一模一樣 無非是換了套浮點算法而已 就算你看不懂浮點指令 也可以通過單步跟蹤 觀察FPU棧的數值猜測到序列號
首先輸入一個錯誤的用戶名和序列號
下面是驗證步驟
第一步
還是和002一樣 獲取用戶名長度 然后根據得到的結果算出來一個值 我這里這個結果為622287
第二步
第二步 首先將剛才計算的結果轉為浮點數 放入到FPU棧 然后將結果加上2.0 得到622289。逆向這個程序你并不需要看懂每一條浮點指令,只需要單步跟蹤 然后時時觀察FPU棧的情況。
第三步
還是將剛才的結果轉為浮點數并入棧 然后將622289乘以一個值再減去一個值 最后得到結果ST0=1866865
第四步
將剛才的結果1866865減去一個值 得到結果1866880 到此校驗就結束了
驗證結果
編寫注冊機
接下來使用Keymake編寫注冊機,設置如下
接著運行注冊機 出現了正確的序列號,至于為什么會出現兩次,這個我也不知道,這個軟件我用的并不熟。哈哈 就這樣吧。
需要udd文件和分析文檔的可以到我的Github下載:https://github.com/TonyChen56/160-Crackme
總結
以上是生活随笔為你收集整理的160个Crackme003之4C大法详解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 汇编之浮点数处理(CrackMe003前
- 下一篇: 160个Crackme004