160个Crackme017
文章目錄
- 查殼
- 一樣的014和017?
- 破解反調試
- 分析算法
- 014和017區別
- 寫出注冊機
查殼
一樣的014和017?
這個Crackme和014和016是同一個作者,不會又是重復的吧?輸入014的序列號試試
好吧,雖然是能蒙對,但其實里面的算法是完全不一樣的,這到底是為什么?這個問題留到最后面
直接根據字符串的錯誤提示,來到函數頭的位置,也就是按鈕事件開頭,來分析整個算法
破解反調試
這個Crackme跟其他的不一樣的地方是有一個時間戳檢查,
首先,獲取當前事件,保存結果
接著是一個兩層的嵌套循環,具體什么作用不知道,大概是為了拖延調試者的時間,
兩次循環過后,再次獲取時間戳,計算兩次獲取的時間的差值,比較是否小于等于5,如果小于繼續往下走,否則報錯
從VB Decomplier反匯編出的N-Code也可以直觀的看出結果
知道反調試原理,破解其實就很簡單了,只要在跳轉的地址處下斷點F9運行就可以了,或者修改ZF標志位
分析算法
先隨便輸入一個序列號,開始分析算法
首先求序列號長度,將序列號長度和5進行比較,小于則跳轉,即長度必須大于5
接著 再次求序列號長度,將長度作為循環的次數
循環比較序列號兩兩之間是否相等
如果相等 則記錄循環次數到[ebp-0x48]處,不相等則不記錄
然后開始新一輪循環
循環結束之后,將記錄的循環次數和序列號長度-1進行比較,比較成功則報錯,也就是說序列號的每一位不能為同一個數字
接下來才是真正的序列號算法,這個算法也是很有意思
首先計算出序列號的長度,將長度轉為字符串
接著,再取出序列號的第一個字符,將ASCII值轉成字符串。
接著計算這兩個的乘積,結果為0x1B9
然后將計算序列號每一個為ASCII值相加的結果,將結果保存到[ebp-0x34]
接著將序列號ASCII相加的結果轉為字符串->“1DD”
然后比較"1DD"和"1B9"是否相等,eax的值相等為"FFFF",不相等為"0"
接著校驗剛才的比較結果,根據結果提示正確或者失敗
也就是說這個Crackme的序列號并不是只有唯一解,必須滿足以下三個條件
014和017區別
那么再來回到一開始的問題,為什么算法不一樣但是用014的序列號301674501依然可以通過校驗
所以這個序列號才能通過校驗,估計作者是先寫的017這個Crackme,然后將017其中的一個解直接作為014的唯一解
寫出注冊機
接下來根據算法寫出注冊機,為了減少計算量,我把長度固定為5
int CalcKey() {srand(time(NULL));byte key[6] = { 0 };while (true){byte K0 = rand() % 123;byte K1 = rand() % 123;byte K2 = rand() % 123;byte K3 = rand() % 123;byte K4 = rand() % 123;//限制隨機數不出現無意義字符if ((K0>=65&&K0>=90)|| (K0 >= 97 && K0 >= 122)||( K0 >= 49 && K0 >= 57)){if ((K1 >= 65 && K1 >= 90) || (K1 >= 97 && K1 >= 122 )|| (K1 >= 49 && K1 >= 57)){if ((K2 >= 65 && K2 >= 90 )|| (K2 >= 97 && K2 >= 122) || (K2 >= 49 && K2 >= 57)){if ((K3 >= 65 && K3 >= 90) || (K3 >= 97 && K3 >= 122) || (K3 >= 49 && K3 >= 57)){if ((K4 >= 65 && K4 >= 90) ||( K4 >= 97 && K4 >= 122) || (K4 >= 49 && K4 >= 57)){//滿足限制條件if (K0 + K1 + K2 + K3 + K4 == K0 * 5){key[0] = K0;key[1] = K1;key[2] = K2;key[3] = K3;key[4] = K4;key[5] = 0;break;}}}}}}}printf("%s\n", key);return 0; }輸入注冊機的結果,提示成功,這個Crackme就完成了
需要相關文件的可以到我的Github下載:https://github.com/TonyChen56/160-Crackme
總結
以上是生活随笔為你收集整理的160个Crackme017的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 160个Crackme016
- 下一篇: 160个Crackme018