160个Crackme024之Opcode加密
文章目錄
- 查殼
- 分析程序
- 分析算法
- 第一部分 計算用戶名和序列號
- 第二部分 根據用戶名和序列號的結果改寫Opcode
- 第三部分 關鍵校驗
- 揣摩作者意圖
- 程序算法總結
- 寫出注冊機
- 校驗結果
查殼
024這個Crackme跟023是同一個作者,難度兩顆星,程序設計的很巧妙,非常有意思
分析程序
首先根據字符串的錯誤提示找到錯誤跳轉到這個地址的位置,總共有兩處,兩處校驗的地方,地址相差不遠,隨便找一個跟過去
兩處校驗分別是校驗序列號和用戶名是否有效,校驗完了之后就是程序的核心算法
分析算法
這個程序的算法分為三個部分,每個部分之間都相互關聯,環環相扣,首先來看第一部分
第一部分 計算用戶名和序列號
先輸入用戶名和序列號,然后下斷點,這個程序的校驗算法部分檢測的是鍵盤事件,而不是定時器,所以打完斷點之后隨便按一個鍵程序就能斷下來
這個就是第一部分的算法,過程如下:
第二部分 根據用戶名和序列號的結果改寫Opcode
首先將eax的值,也就是第一部分計算出的結果跟[0x4012D9]這個地址進行異或,
[0x4012D9]這個地址的值在算法一開始就被賦值了,所以這個值是固定的。
然后將eax右移0x10位,然后用[0x4012D9]的值減去ax,這兩部分的操作都會改變[0x4012D9]處的代碼,那么這么做到底是為了什么呢?現在還不知道,需要接著往下看
第三部分 關鍵校驗
從內存地址[4011EC]開始,讀入四個字節與EBX異或,結果保存在ebx,一直至內存地址[4012E4],這段正好是關鍵算法部分,循環結束之后比較ebx是否等于0xAFFCCFFB,如果不相等則報錯,如果相等的話就跳轉0x4012D9處。
這里有一個坑,就算不能在這個校驗的范圍內下F2斷點,如果下了的話會改變最后的值
揣摩作者意圖
按照正常情況下來說,有一個提示錯誤的分支,另外一個就一定是提示正確的分支,而這個提示正確的分支卻是指向一段動態改變的代碼,那就是說,我們只能通過0x4012D9處的代碼讓程序提示注冊成功,否則這個程序就會陷入無限的死循環或者是直接奔潰。
也就是說,0x4012D9這個位置必須帶我們到正確的提示,也就是說這個地址的OpCode必須為EB 26
程序算法總結
寫出注冊機
過程分析清楚了,但是想寫出注冊機的話還是得費點勁的,這種逆推算法的事情我不太擅長,看見就腦闊疼,索性直接從看雪上面拷了一個,代碼如下:
雖然這個注冊機效率有點慢,但好歹能編譯通過,而且計算正確,之前找了好幾個要么編譯不過,要么算的不對,我也是服了
#include <iostream> #include <windows.h> using namespace std;int main(void) {CHAR szName[20] = { 0 };cout << "Name:";cin >> szName;DWORD dwNum = 0x58455443;//程序實現填入的全局變量for (int i = 0; i < strlen(szName); i++)//用戶名循環相加DWORD{void *p = &szName[i];_asm{mov edi, p;mov eax, dword ptr[edi];add dwNum, eax;}}//DWORD dwPass = 0;while (1){DWORD temp = (dwNum + dwPass) ^ 0x584554;temp -= (WORD)((dwNum + dwPass) >> 0x10);if (dwPass % 0x100000 == 0) //這里if語句可以不要只是用來看看它在跑密碼還是死機了cout << dwPass << endl;if (temp == 0x585426EB)//這就是上一個算法得到的正確的opcodebreak;dwPass++;}cout << "Pass:" << dwPass << endl;system("pause"); }校驗結果
輸入用戶名和計算出來的序列號,提示成功 破解完成
需要相關文件的可以到我的Github下載:https://github.com/TonyChen56/160-Crackme
總結
以上是生活随笔為你收集整理的160个Crackme024之Opcode加密的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Windbg新手入坑指南
- 下一篇: 160个Crackme025之巧去Neg