新160個(gè)CrackMe分析-第3組:21-30(下)

作者:selph
目錄:
??021-DIS-Serialme1
??022-CM_22
??023-TraceMe3
??024-reverseMe4
??025-CRC32crackme5
??026-KeygenMe6
??027-MexeliteCRK17
??028-ArturDents-CrackMe38
??029-figugegl19
??030-AcidBytes410
前半篇請(qǐng)看上集
1.??????026-KeygenMe
算法難度:???
爆破難度:?
信息收集
運(yùn)行情況:
??????????
查殼與脫殼:
識(shí)別的是UPX殼,實(shí)際上則無(wú)殼,識(shí)別錯(cuò)誤應(yīng)該是
??????????
調(diào)試分析
通過(guò)MessageBox函數(shù)交叉引用定位校驗(yàn)的位置,就分析主要邏輯吧,前面那些初始化無(wú)關(guān)緊要
前面省略了給Name和Serial賦值的API調(diào)用,直接從校驗(yàn)邏輯開始看
這里獲取Name字符串長(zhǎng)度遍歷計(jì)算使用
然后一個(gè)循環(huán),計(jì)算一個(gè)累加值到esi
每一輪取一個(gè)字符到ebx,累加ebx平方,累加ebx右移一位后+3后乘以ebx再減去ebx,然后esi乘以2(這樣描述不清楚,具體看下文反匯編注釋和注冊(cè)機(jī)代碼)
最后算出一個(gè)累加值和序列號(hào)字符串進(jìn)行對(duì)比,沒看錯(cuò),是直接和字符串對(duì)比,輸入的字符串會(huì)直接當(dāng)成數(shù)字對(duì)待
??????????
輸入的字符,這里esi是計(jì)算出來(lái)的累加和,下面那一行是輸入的序列號(hào),直接用ascii當(dāng)數(shù)字來(lái)對(duì)比了?。?!
??????????
注冊(cè)機(jī)
注冊(cè)碼生成算法:因?yàn)閷?duì)輸入的用戶名有要求,太長(zhǎng)太短都不行,還得是能滿足要求的字符,所以這里就使用隨機(jī)字符串來(lái)生成滿足要求的Name:
?????#define _CRT_SECURE_NO_WARNINGS
#include
#include
#include
#define Random(x)(rand()%x) //?生成x以內(nèi)的隨機(jī)數(shù)
//?參數(shù):生成隨機(jī)字符串長(zhǎng)度
void GetRandomString(LPSTR str,SIZE_T nLength) {
??? srand((int)time(NULL)); //?隨機(jī)數(shù)種子
??? for (size_t i = 0; i < nLength; i++) {
??????? switch (Random(2)){
??????? case 0: str[i] = 'a' + Random(26); break;
??????? case 1: str[i] = 'A' + Random(26); break;
??????? default: break;
??????? }
??? }
}
bool SerialCheck(char* serial) {
??? bool res = true;
??? for (int i = 0; i < 3; i++) {
??????? char tmp = serial[i];
??????? if (0x21 <= tmp && tmp <= 0x7E) continue;
??????? res = false;
??????? break;
??? }
??? return res;
}
int main()
{
??? int esi = 0;
??? char name[20] = { 0 };
??? char serial[20] = { 0 };
??? bool flag = false;
??? while (!flag) {
? ??????memset(name, 0, sizeof(name));
??????? GetRandomString(name, 7);
??????? esi = 0;
??????? for (int i = 0; name[i]; i++)
??????? {
??????????? int ebx = name[i];
??????????? esi += ebx * ebx;
??????????? esi += ebx * ((ebx >> 1) + 2);
??????????? esi += esi;
??????? }
??????? *(int*)&serial = esi;
??????? if (SerialCheck(serial)) {
??????????? std::cout << name << std::endl;
??????????? std::cout << serial;
??????????? break;
??????? }
??? }
}
效果:
??????????
總結(jié)
算法不難,但寫注冊(cè)機(jī)還是有些麻煩的
2.??????027-MexeliteCRK1
算法難度:?
爆破難度:?
信息收集
運(yùn)行情況:
輸入序列號(hào),下面那個(gè)框顯示狀態(tài)
??????????
查殼與脫殼:
無(wú)殼,是Delphi程序
??????????
調(diào)試分析
硬編碼序列號(hào)驗(yàn)證
??????????
效果:
??????????
3.??????028-ArturDents-CrackMe3
算法難度:??
爆破難度:?
信息收集
運(yùn)行情況:
??????????
查殼與脫殼:
一個(gè)沒見過(guò)的殼出現(xiàn)了,Petite殼,老樣子,依然是ESP定律可以解決
??????????
調(diào)試分析
Delphi程序,通過(guò)IDR反匯編找到按鈕控件事件,然后復(fù)制出來(lái)分析
首先是獲取輸入,Name長(zhǎng)度和Serial長(zhǎng)度不能為0
??????????
接下來(lái)緊接著是序列號(hào)生成:根據(jù)Name生成一個(gè)字符串
??????????
最后是比對(duì)環(huán)節(jié):
??????????
注冊(cè)機(jī)
注冊(cè)碼生成算法:
?????#define _CRT_SECURE_NO_WARNINGS
#include
int main()
{
??? char name[100] = { 0 };
??? char num[100] = { 0 };
??? std::cin >> name;
??? for (int i = 0; i < strlen(name); i++)
??? {
??????? char tmp_str[100] = { 0 };
??????? _itoa(name[i] / 3, tmp_str, 10);
??????? strcat(num, tmp_str);
??? }
??? std::cout << "ADCM3-" << num << std::endl;
??? return 0;
}
效果:
??????????
4.??????029-figugegl1
?算法難度:??
爆破難度:?
信息收集
運(yùn)行情況:
??????????
查殼與脫殼:
無(wú)殼
??????????
字符串:
存在提示信息:
??????????
調(diào)試分析
從字符串提示入手,找到校驗(yàn)點(diǎn)開始分析
首先是獲取輸入,用戶名需要長(zhǎng)度大于等于5
??????????
然后是校驗(yàn)和對(duì)比了:
校驗(yàn)算法:Serial == Name[i]-i
??????????
簡(jiǎn)單到可以口算的序列號(hào)生成:12345:11111
效果:
??????????
注冊(cè)機(jī)
注冊(cè)碼生成算法:
?????#include
int main()
{
??? char serial[100] = { 0 };
??? char name[100] = { 0 };
??? std::cin >> name;
??? for (int i = 0; name[i]; i++)
??? {
??????? serial[i] = name[i] - i;
??? }
??? std::cout << serial;
}
5.??????030-AcidBytes4
算法難度:???
爆破難度:?
信息收集
運(yùn)行情況:
??????????
查殼與脫殼:
UPX,無(wú)腦ESP定律即可
??????????
調(diào)試分析
Delphi程序,IDR走起
首先是獲取Name和Serial校驗(yàn)長(zhǎng)度
??????????
然后是進(jìn)行一個(gè)計(jì)算,根據(jù)Name計(jì)算Serial:
相同的操作會(huì)進(jìn)行6次:取一個(gè)字節(jié),乘以2,然后累加起來(lái),會(huì)操作的就是Name的前6個(gè)字符
??????????
最后把這個(gè)累加值保存起來(lái),給這個(gè)累加值加上個(gè)Name長(zhǎng)度的兩倍,轉(zhuǎn)字符串(十進(jìn)制,就是真碼了
??????????
注冊(cè)機(jī)
注冊(cè)碼生成算法:
?????#include
int main()
{
??? char name[100] = { 0 };
??? int sum = 0;
??? std::cin >> name;
??? for (int i = 0; i < 6; i++) sum += name[i] * 2;
??? sum += strlen(name)*2;
??? if (sum >> 0x1f == 0)std::cout << sum;
}
結(jié)果:
??????????
總結(jié)
又是這種,把能寫進(jìn)循環(huán)的東西寫了超級(jí)多段落,不難,只要有Delphi的符號(hào),分析起來(lái)還是挺快的