160个Crackme032用ProcessMonitor拆解KeyFile保护
文章目錄
- 查殼
- 添加簽名 導入符號
- KeyFile前置知識
- 原理
- 如何防止被破解
- 相關API函數
- 拆解KeyFile保護
- 實戰破解KeyFile
- 校驗結果
- 破解Name/Serial
- 用Darkde4確定響應事件
- 算法分析
- 算法總結
- 寫出注冊機
- 校驗結果
這個Crackme有兩種保護方式 一種是KeyFile,一種是Name/Serial。這個是160個Crackme里面第一個文件校驗的保護方式了。難度系數為問號,自我感覺就值一顆星吧。
查殼
加了個UPX殼,直接用通用脫殼工具秒脫,另外鏈接器版本是2.25,說明是Delphi寫的程序,Delphi寫的程序有一個特點,調用約定是fastcall,而字符串大多是以一個指針的方式存放。
添加簽名 導入符號
脫殼完成之后,把程序拖入到IDA,添加上所有的Delphi簽名
然后導出為map文件
再導入到OD
把IDA的符號導入到OD,方便后面的調試
KeyFile前置知識
在破解這個KeyFile保護之前,先來了解一下相關的前置知識,出自《加密解密4》
原理
KeyFile是一種利用文件來注冊軟件的保護方式。KeyFile一般是一個小文件,可以是純文本文件,也可以是包含不可顯示字符的二進制文件。其內容是一些加密或未加密的數據,其中可能有用戶名、注冊碼等信息,文件格式則由軟件作者自己定義。試用版軟件沒有注冊文件。當用戶向作者付費注冊之后,會收到作者提供的注冊文件,其中可能包含用戶的個人信息。用戶只要將該文件放人指定的目錄,就可以讓軟件成為正式版了。該文件一般放在軟件的安裝目錄或系統目錄下。軟件每次啟動時,從該文件中讀取數據,然后利用某種算法進行處理,根據處理的結果判斷是否為正確的注冊文件。如果正確,則以注冊版模式運行。
如何防止被破解
在實現這種保護的時候,建議軟件作者采用稍大一些的文件作為KeyFile(一般在幾KB左右),其中可以加入一些垃圾信息以干擾解密者。對注冊文件的合法性檢查可以分成幾部分,分散在軟件的不同模塊中進行判斷。注冊文件內的數據處理也要盡可能采用復雜的運算,而不要使用簡單的異或運算。這些措施都可以增加解密的難度。和注冊碼一樣,也可以讓注冊文件中的部分數據和軟件中的關鍵代碼或數據發生關系,使軟件無法被暴力破解。
相關API函數
FindFirstFileA //確定注冊文件是否存在 CreateFileA、_lopen //確定文件是否存在;打開文件以獲得其句柄 GetFileSize、GetFileSizeEx //獲得注冊文件的大小 GetFileAttributesA、GetFileAtributesExA //獲得注冊文件的屬性 SetFilePointer、SetFilePointerEx //移動文件指針 ReadFile //讀取文件內容拆解KeyFile保護
當然,上述只是大致步驟,有的程序在判斷KeyFile時會先判斷文件大小和屬性、移動文件指針等。總之,對KeyFile的分析深入與否,取決于分析者對Win32File I/OAPI的熟悉程度,也就是API編程的水平。
實戰破解KeyFile
在程序運行之后會彈出這么一個對話框,大致意思是說缺少了一個叫Reg.dat的文件。
實際上這個KeyFile的破解思路有兩種,第一就是在MessageBox下斷點,分析附近代碼。另外一種就是直接用Process Monitor等工具監視軟件對文件的操作,以找到KeyFile的文件名。
我們直接用第二種方式,打開ProcessMonitor,過濾一下進程名,開始監控
監控結果如下:
除了常規的加載模塊的操作之外,還有這樣一個行為,它打開了一個叫Reg.dat的文件,前面的路徑名是我放這個程序的完整路徑名。
那么可以知道,這個KeyFile的校驗的必須在同名路徑下有一個叫Reg.dat的文件才能夠校驗成功。
校驗結果
新建一個Reg.dat文件在同名路徑下
打開目標程序
彈框消失,證明KeyFile破解完成。這是一個最簡單的沒有要求文件內容的KeyFile。
破解Name/Serial
接下來再來到驗證的部分,可以看到這個是由用戶名和序列號組成,但是不管序列號怎么輸,那個OK按鈕始終是灰色了。這種情況在之前的Crackme里也遇到過很多次,要么是用定時器校驗,要么是通過鍵盤擊鍵事件,這個程序有可能通過是序列號的Edit框的change事件來校驗的。
用Darkde4確定響應事件
首先用Darkde4來確定這個程序的響應事件,打開窗體對話框
可以看到右邊有四個Edit編輯框,對應四個輸入序號的部分,再來到過程窗口
這里正好有四個EditChange事件,以及對應的RVA,我們直接復制下Edit4的RVA,去到OD響應的位置
可以看到成功的提示就在下面,旁邊的注釋顯示這是Button1的Click,說明只有當序列號輸入正確的時候,OK按鈕才會被啟用
在往上看,發現四個Edit編輯框的響應事件都是同一個函數sub_437D1C,那么接下來就開始分析這個函數的算法了
算法分析
隨便輸入一個用戶名和序列號,下斷點,分析sub_437D1C這個函數,整個函數邏輯如下:
不要看這么長就慌了,真正有用的是 sub_437BD8這個函數,繼續跟進去
首先獲取用戶名長度,跟5進行比較,小于則跳轉
然后會取出用戶名第零位的ASCII值,除以0xA之后保存結果
之后分別取第二位,第三位,第四位,除以0xA之后保存結果
這個過程在IDA中一目了然
然后開始循環四次,首先把用戶名的ASCII值除以10之后的結果的十進制數轉為字符串,如果長度大于1的話就再除以10,保存這個結果,如果長度為1,則結果不變。為什么要再除一次10,因為四個序列號最大只能是9
最后,開始循環比較計算出的結果和輸入的序列號,7181是用戶名ASCII兩輪除以10之后計算后的結果,1234是我輸入的序列號
算法總結
這個程序的校驗算法總結如下:
寫出注冊機
算法出來了,序列號還會遠嗎?這個算法口算也能算出序列號,但是我們還是寫出注冊機,代碼如下:
int CalcKey() {char username[20] = { 0 };char result[20] = { 0 };char serial[5] = { 0 };printf("請輸入用戶名:");scanf_s("%s", username, 20);if (strlen(username)<5){printf("用戶名長度不能小于5\n");return 0;}for (int i = 0; i < strlen(username); i++){result[i] = username[i] / 0xA;if (result[i]>9){result[i] /= 0xA;}}serial[0] = result[0];serial[1] = result[2];serial[2] = result[3];serial[3] = result[4];serial[4] = 0;for (int i = 0; i < 4; i++){printf("%d", serial[i]);}printf("\n");return 0; }校驗結果
輸入用戶名和計算的序列號 破解完成
需要相關文件的可以到我的Github下載:https://github.com/TonyChen56/160-Crackme
總結
以上是生活随笔為你收集整理的160个Crackme032用ProcessMonitor拆解KeyFile保护的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 160个Crackme031之一元二次方
- 下一篇: 160个Crackme033