「百度杯」CTF比賽 十一月場--CrackMe01

測試文件:https://static2.ichunqiu.com/icq/resources/fileupload/CTF/BSRC/BSRC-11-3/CrackMe01_97D2BF0DBD2EC13065E7104F24CAAED9.zip測試

 

1.準備

獲取信息ui

  • 32位文件

 

2.IDA打開

熟悉Windows API的話,通常組成的就是MessageBox,ShowWindow...這裏測試錯誤答案時,沒有窗口提示,也就排除了MessageBox,並且要處理消息事件的話,直接查找默認消息處理DefWindowProc。spa

在import裏面搜索DefWindowProc3d

 

點擊進入以後,Ctrl+X查找用到的地方code

一個一個進入,F5分析就行。(實際上就是第一個)blog

 

找到這麼一段代碼事件

 1 LRESULT __stdcall sub_4027F0(int a1, UINT Msg, WPARAM wParam, LPARAM lParam)
 2 {
 3   UINT v4; // eax
 4   LPARAM v5; // edx
 5   __int16 v6; // bx
 6   void *v7; // edi
 7   HDC v9; // esi
 8   unsigned int v10; // ecx
 9   __int16 v11; // ax
10   unsigned int v12; // eax
11   int v13; // edi
12   int v14; // eax
13   struct tagRECT v15; // [esp+18h] [ebp-68h]
14   struct tagRECT Rect; // [esp+28h] [ebp-58h]
15   struct tagPAINTSTRUCT Paint; // [esp+38h] [ebp-48h]
16 
17   v4 = Msg;
18   v5 = lParam;
19   v6 = 0;
20   v7 = (void *)wParam;
21   if ( Msg > 0xF )
22   {
23     if ( Msg != 4097 )
24       return DefWindowProcW((HWND)a1, v4, (WPARAM)v7, v5);
25     v10 = 0;
26     do
27     {
28       v11 = *(_WORD *)(wParam + 2 * v10++);
29       v6 += v11;
30     }
31     while ( v10 <= lParam );
32     v12 = 0;
33     do
34     {
35       *(const WCHAR *)((char *)&chText + v12) ^= v6;
36       v12 += 2;
37     }
38     while ( v12 < 0x2C );
39     GetWindowRect((HWND)a1, &v15);
40     v13 = (v15.left - v15.right + GetSystemMetrics(16)) / 2;
41     v14 = GetSystemMetrics(17);
42     SetWindowPos((HWND)a1, HWND_MESSAGE|0x2, v13, (v15.top - v15.bottom + v14) / 2, -1, -1, 5u);
43     SetWindowPos((HWND)a1, (HWND)0xFFFFFFFE, 0, 0, 0, 0, 3u);
44     if ( (v6 & 0xF00) == 0x400 && (v6 & 0xF0) == 0xB0u && (v6 & 6) == 6 )
45     {
46       ShowWindow((HWND)a1, 5);
47       UpdateWindow((HWND)a1);
48     }
49     v7 = (void *)wParam;
50 LABEL_18:
51     if ( v7 )
52       free(v7);
53     v5 = lParam;
54     v4 = Msg;
55     return DefWindowProcW((HWND)a1, v4, (WPARAM)v7, v5);
56   }
57   switch ( Msg )
58   {
59     case 0xFu:
60       v9 = BeginPaint((HWND)a1, &Paint);
61       GetClientRect((HWND)a1, &Rect);
62       DrawTextW(v9, &chText, -1, &Rect, 0x25u);
63       EndPaint((HWND)a1, &Paint);
64       goto LABEL_18;
65     case 1u:
66       return 0;
67     case 2u:
68       PostQuitMessage(0);
69       return 0;
70   }
71   return DefWindowProcW((HWND)a1, v4, (WPARAM)v7, v5);
72 }

 

3.代碼分析

去除掉代碼中對窗口消息,建立,咱們須要的代碼就是ip

    do
    {
      *(const WCHAR *)((char *)&chText + v12) ^= v6;
      v12 += 2;
    }
    while ( v12 < 0x2C );

這裏實際上就是對chText的前0x2c個進行了異或處理,代碼中兩個字節爲一組,總共22組。get

chTextit

F0 04 DA 04 D7 04 D1 04  8C 04 FF 04 F5 04 FE 04 
E3 04 F8 04 E7 04 FF 04  E3 04 E9 04 F0 04 F3 04 
85 04 80 04 84 04 F2 04  F4 04 F3 04

 

所以chText爲

chText[]={0x4F0, 0x4DA, 0x4D7, 0x4D1, 0x48C, 0x4FF, 0x4F5, 0x4FE,  0x4E3, 0x4F8, 0x4E7, 0x4FF, 0x4E3,  0x4E9, 0x4F0, 0x4F3, 0x485, 0x480, 0x484, 0x4F2, 0x4F4, 0x4F3}

 

v6的值咱們能夠經過第44行代碼

if ( (v6 & 0xF00) == 0x400 && (v6 & 0xF0) == 0xB0u && (v6 & 6) == 6 )
{
  ShowWindow((HWND)a1, 5);
  UpdateWindow((HWND)a1);
}

獲得v6=0x4b6

 

4.腳本獲取

chText = [0x4F0, 0x4DA, 0x4D7, 0x4D1, 0x48C, 0x4FF, 0x4F5, 0x4FE, 0x4E3, 0x4F8, 0x4E7, 0x4FF, 0x4E3, 0x4E9, 0x4F0,
          0x4F3, 0x485, 0x480, 0x484, 0x4F2, 0x4F4, 0x4F3]
flag = ''

for i in range(22):
    chText[i] ^= 0x4b6
    flag += chr(chText[i])

print(flag)

 

5.get flag!

Flag:ICHUNQIU_FE362DBE

相關文章
相關標籤/搜索