天天看點

新160個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
               

算法難度:⭐⭐

爆破難度:⭐

資訊收集

運作情況:

真難得見到一次控制台程式:

查殼與脫殼:

還帶殼,ESP定律走起

調試分析:

這裡拿了一堆結構裡的東西在做計算,直接F5看吧,友善一點:

剛開始拿結構裡的東西計算了一個值,然後判斷輸入是否等于這個值,如果等于就成功

這個VersionInformation結構體變量是在上面那個call401390裡填充的:

注冊機

注冊碼生成算法:

#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");
           

}

效果:

  1. 047-surre
               

算法難度:⭐⭐

爆破難度:⭐

資訊收集

運作情況:

點選按鈕會彈出打開檔案的框

查殼與脫殼:

調試分析

驗證邏輯很簡潔,就兩件事:讀取檔案周遊每一個字元累加起來,判斷累加和是否是20A9,是的話,表示驗證成功,否則是失敗

注冊機

注冊碼生成算法:

#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;

}

效果:

  1. 048-monkeycrackme1
        算法難度:⭐⭐⭐
    
        爆破難度:⭐
               

資訊收集

運作情況:

查殼與脫殼:

調試分析

程式驗證邏輯很簡單:

首先以寫死0xce6d和0x58bf建立了一個對象結構,然後讀取Name,計算一個字元串,然後讀取Serial字元串,進行比對,一樣則表示成功,否則表示失敗

這裡要注意,delphi使用的是32位的fastcall,傳參順序是eax,edx,ecx,棧,最後調用計算字元串的函數的時候,有一個棧中的參數
           

計算邏輯也很簡單:

首先儲存變量,初始化輸出緩沖區

然後計算Name長度,周遊每一個字元

對于每一個字元,和兩位元組變量右移8位後的結果異或一下,然後轉換成十六進制(大寫)拼接到輸出緩沖區裡

然後中間處理了一下兩位元組值,初值是4DE1是參數傳入的,修改方式是使用異或後的一位元組,加上原本的兩位元組值,然後乘以安全對象的第一個成員,最後加上安全對象的第二個成員的值(第一個成員的值和第二個成員的值可以通過動态調試得知,是固定值)

注冊機

注冊碼生成算法:

#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;
           

}

效果:

  1. 049-THraw-crackme8
        算法難度:⭐⭐
    
        爆破難度:⭐
    
         資訊收集
         運作情況:
               

查殼與脫殼:

UPX殼,ESP定律即可

調試分析

邏輯很簡單,首先擷取Name,然後處理一下

處理方式就是把每個字元的ascii轉換成大寫十六進制,然後拼接起來

然後接下來使用一個全局變量,轉換成字元串,然後再這個字元串之後拼接剛剛name轉換的字元串,就是真碼了

最後讀取Serial,進行對比是否是真碼,進行跳轉

注冊機

注冊碼生成算法:

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);

效果:

  1. 050-daxxor
               

算法難度:⭐⭐⭐

爆破難度:⭐⭐

資訊收集

運作情況:

查殼與脫殼:

無殼:

調試分析

IDA打開程式分析,是個C++程式

搜尋字元串發現提示資訊:You solve it

然後根據提示資訊定位到反彙編,F5一下偷個懶:

這裡就是根據Name生成一個字元串,然後和Serial進行對比,隻要按照生成順序生成一個字元串,即是Serial

注冊機

注冊碼生成算法:

#include
           
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;