拿到題目後是一個exe程序,首先看一下運行結果,那麼一共有兩種結果,一種是若是密碼爲空,則提示從新輸入,若是輸入錯誤,則提示加油,以下圖:python
輸入錯誤後程序會退出數組
放進IDA進行靜態分析,看下主要代碼是如何運行app
進入之後首先字符串查找 shift+F12,結果如圖:this
那麼咱們看到了pass!,並且還有兩串可疑的字符串,因此咱們去看看code
BOOL sub_401770() { HANDLE hProcess; // ST5C_4 MessageBoxA(0, "pass!", &Caption, 0); hProcess = GetCurrentProcess(); return TerminateProcess(hProcess, 0); }
這段代碼就是返回pass的,因此咱們看看誰調用了這段代碼blog
通過查找是我箭頭處調用了這段代碼,因此經過分析,咱們知道,經過字符串比較,而後決定是返回sub_401770()—>PASS!仍是sub_4017B0()—>錯了,加油!v8
BOOL __cdecl sub_4017F0(int a1) { BOOL result; // eax char Str1[28]; // [esp+D8h] [ebp-24h] int v3; // [esp+F4h] [ebp-8h] int v4; // [esp+F8h] [ebp-4h] v4 = 0; v3 = 0; while ( *(_DWORD *)(a1 + 4 * v4) < 62 && *(_DWORD *)(a1 + 4 * v4) >= 0 ) { Str1[v4] = aAbcdefghiabcde[*(_DWORD *)(a1 + 4 * v4)]; ++v4; } Str1[v4] = 0; if ( !strcmp(Str1, "KanXueCTF2019JustForhappy") ) result = sub_401770(); else result = sub_4017B0(); return result; }
因此咱們知道它應該是將Str1和"KanXueCTF2019JustForhappy"做比較,因此咱們就逆着去看看這個Str1怎麼來的,向上看是這段代碼:字符串
while ( *(_DWORD *)(a1 + 4 * v4) < 62 && *(_DWORD *)(a1 + 4 * v4) >= 0 ) { Str1[v4] = aAbcdefghiabcde[*(_DWORD *)(a1 + 4 * v4)]; ++v4; }
很容易看出,是將aAbcdefghiabcde[*(_DWORD *)(a1 + 4 * v4)]賦值給了Str1io
那麼知道複製的字符串數組了,接下來要解決的就是下標問題了,下標解決了,那麼也就知道了Str1了class
下標怎麼來的呢?
這段就是計算下標,而後進行賦值的關鍵代碼
int __thiscall sub_401890(CWnd *this) { struct CString *v1; // ST08_4 CWnd *v2; // eax int v3; // eax int v5[26]; // [esp+4Ch] [ebp-74h] int i; // [esp+B4h] [ebp-Ch] char *Str; // [esp+B8h] [ebp-8h] CWnd *v8; // [esp+BCh] [ebp-4h] v8 = this; v1 = (CWnd *)((char *)this + 100); v2 = CWnd::GetDlgItem(this, 1002); CWnd::GetWindowTextA(v2, v1); v3 = sub_401A30((char *)v8 + 100); Str = CString::GetBuffer((CWnd *)((char *)v8 + 100), v3); if ( !strlen(Str) ) return CWnd::MessageBoxA(v8, &byte_4035DC, 0, 0); for ( i = 0; Str[i]; ++i ) { if ( Str[i] > '9' || Str[i] < '0' ) { if ( Str[i] > 'z' || Str[i] < 'a' ) { if ( Str[i] > 'Z' || Str[i] < 'A' ) sub_4017B0(); else v5[i] = Str[i] - 29; } else { v5[i] = Str[i] - 87; } } else { v5[i] = Str[i] - 48; } } return sub_4017F0((int)v5); }
經過分析就是將咱們輸入的字符串進行了減法運算,而後賦值給Str1,再將Str1與"KanXueCTF2019JustForhappy"做比較,因此咱們能夠將"KanXueCTF2019JustForhappy"進行逆運算,獲得Str1,就是得到flag
下面是我編寫的腳本:
str1 = 'KanXueCTF2019JustForhappy' str2 = 'abcdefghiABCDEFGHIJKLMNjklmn0123456789opqrstuvwxyzOPQRSTUVWXYZ' flag = '' for i in range(int(len(str1))): for j in range(int(len(str2))): if str1[i] == str2[j]: if((j + 48 >= 48 ) and (j + 48 <= 57 )): flag += chr(j + 48) elif((j + 87 >= 97 ) and (j + 87 <= 122 )): flag += chr(j + 87) elif((j + 29 >= 65 ) and (j + 29 <= 90 )): flag += chr(j + 29) print(flag)
運行結果:
拿到flag