新160個(gè)CrackMe分析-第5組:41-50(下)

作者:selph
目錄:
??041-genocidel1
??042-crackme2
??043-riijj_cm_200411213
??044-tsrh-crackme4
??045-CyTom-crackme5
??046-keyme16
??047-surre7
??048-monkeycrackme18
??049-THraw-crackme89
??050-daxxor10
參考資料
–?[1]?WM_INITDIALOG消息?(Winuser.h) - Win32 apps | Microsoft Docs
1.??????046-keyme1
算法難度:??
爆破難度:?
信息收集
運(yùn)行情況:
真難得見到一次控制臺(tái)程序:
??????????
查殼與脫殼:
還帶殼,ESP定律走起
調(diào)試分析:? ? ? ? ??
這里拿了一堆結(jié)構(gòu)里的東西在做計(jì)算,直接F5看吧,方便一點(diǎn):
剛開始拿結(jié)構(gòu)里的東西計(jì)算了一個(gè)值,然后判斷輸入是否等于這個(gè)值,如果等于就成功
??????????
這個(gè)VersionInformation結(jié)構(gòu)體變量是在上面那個(gè)call401390里填充的:
??????????
注冊(cè)機(jī)
注冊(cè)碼生成算法:
?????#define _CRT_SECURE_NO_WARNINGS
#include
#include
#pragma warning(disable: 4996)
int main()
{
??? OSVERSIONINFOA VersionInformation={0};
??? VersionInformation.dwOSVersionInfoSize = 148;
??? GetVersionExA(&VersionInformation);
??? int key = VersionInformation.dwBuildNumber
??????? + VersionInformation.dwBuildNumber
??????? + VersionInformation.dwMajorVersion * VersionInformation.dwMinorVersion
??????? - VersionInformation.dwMinorVersion
??????? + 3293 * VersionInformation.dwBuildNumber;
??? printf("%d",key);
??? system("pause");
}
效果:
2.??????047-surre
算法難度:??
爆破難度:?
信息收集
運(yùn)行情況:
點(diǎn)擊按鈕會(huì)彈出打開文件的框
??????????
查殼與脫殼:
調(diào)試分析
驗(yàn)證邏輯很簡(jiǎn)潔,就兩件事:讀取文件遍歷每一個(gè)字符累加起來,判斷累加和是否是20A9,是的話,表示驗(yàn)證成功,否則是失敗
??????????
注冊(cè)機(jī)
注冊(cè)碼生成算法:
?????#include
int main()
{
??? char serial[200] = { 0 };
??? const int key = 0x20A9;
??? for (int i = 0; i < key / 0x30; i++) serial[i] = '0';
??? for (int i = 0; i < key % 0x30; i++) serial[i] += 1;
??? std::cout << serial;
}
效果:
??????????
3.??????048-monkeycrackme1
???????????算法難度:???
???????????爆破難度:?
信息收集
運(yùn)行情況:
??????????
查殼與脫殼:
??????????
調(diào)試分析
程序驗(yàn)證邏輯很簡(jiǎn)單:
首先以硬編碼0xce6d和0x58bf創(chuàng)建了一個(gè)對(duì)象結(jié)構(gòu),然后讀取Name,計(jì)算一個(gè)字符串,然后讀取Serial字符串,進(jìn)行比對(duì),一樣則表示成功,否則表示失敗
???????????這里要注意,delphi使用的是32位的fastcall,傳參順序是eax,edx,ecx,棧,最后調(diào)用計(jì)算字符串的函數(shù)的時(shí)候,有一個(gè)棧中的參數(shù)
??????????
計(jì)算邏輯也很簡(jiǎn)單:
首先保存變量,初始化輸出緩沖區(qū)
然后計(jì)算Name長度,遍歷每一個(gè)字符
對(duì)于每一個(gè)字符,和兩字節(jié)變量右移8位后的結(jié)果異或一下,然后轉(zhuǎn)換成十六進(jìn)制(大寫)拼接到輸出緩沖區(qū)里
然后中間處理了一下兩字節(jié)值,初值是4DE1是參數(shù)傳入的,修改方式是使用異或后的一字節(jié),加上原本的兩字節(jié)值,然后乘以安全對(duì)象的第一個(gè)成員,最后加上安全對(duì)象的第二個(gè)成員的值(第一個(gè)成員的值和第二個(gè)成員的值可以通過動(dòng)態(tài)調(diào)試得知,是固定值)
??????????
注冊(cè)機(jī)
注冊(cè)碼生成算法:
?????#define? _CRT_SECURE_NO_WARNINGS
#include
typedef struct _TSecurity
{
??? _TSecurity(uint16_t a, uint16_t b) :vul1(a), vul2(b) {}
??? uint16_t vul1;
??? uint16_t vul2;
}TSecurity,*PTSecurity;
int main()
{
??? TSecurity obj(0xce6d,0x58bf);
??? char name[100] = { 0 };
??? short num = 0x4de1;
??? char serial[100] = { 0 };
??? char tmp[100] = { 0 };
??? std::cin >> name;
??? int len = strlen(name);
??? for (int i = 0; i < len; i++)
??? {
??????? uint8_t c = name[i] ^ (num >> 8);
??????? num = (c + num) * obj.vul1 + obj.vul2;
??????? sprintf(tmp, "%02X", c);
??????? strcat(serial, tmp);
??? }
??? std::cout << serial;
}
效果:
??????????
4.??????049-THraw-crackme8
???????????算法難度:??
???????????爆破難度:?
????????????信息收集
????????????運(yùn)行情況:
??
????????
查殼與脫殼:
UPX殼,ESP定律即可
??????????
調(diào)試分析
邏輯很簡(jiǎn)單,首先獲取Name,然后處理一下
處理方式就是把每個(gè)字符的ascii轉(zhuǎn)換成大寫十六進(jìn)制,然后拼接起來
然后接下來使用一個(gè)全局變量,轉(zhuǎn)換成字符串,然后再這個(gè)字符串之后拼接剛剛name轉(zhuǎn)換的字符串,就是真碼了
最后讀取Serial,進(jìn)行對(duì)比是否是真碼,進(jìn)行跳轉(zhuǎn)
??????????
注冊(cè)機(jī)
注冊(cè)碼生成算法:
?????var Serial = "1007689728";
var Name = Console.ReadLine();
for (int i = 0; i < Name.Length; i++)
??? Serial += string.Format("{0:X2}", (int)Name[i]);
Console.WriteLine(Serial);
效果:
??????????
5.??????050-daxxor
算法難度:???
爆破難度:??
信息收集
運(yùn)行情況:
??????????
查殼與脫殼:
無殼:
??????????
調(diào)試分析
?IDA打開程序分析,是個(gè)C++程序
搜索字符串發(fā)現(xiàn)提示信息:You solve it
然后根據(jù)提示信息定位到反匯編,F(xiàn)5一下偷個(gè)懶:
這里就是根據(jù)Name生成一個(gè)字符串,然后和Serial進(jìn)行對(duì)比,只要按照生成順序生成一個(gè)字符串,即是Serial
?? ? ? ??
注冊(cè)機(jī)
注冊(cè)碼生成算法:
?????#include
#include
int main()
{
??? std::string name;
??? std::cin >> name;
??? for (int i = 0; i < name.length(); i++) name[i] -= 4;
??? name.insert(3, "-");
??? name.insert(5, "-");
??? name.insert(6, "axd");
??? std::cout << name;
}
效果: