獲取信息app
int __cdecl main(int argc, const char **argv, const char **envp) { std::string *v4; // [esp-18h] [ebp-1B8h] int (*v5)[9]; // [esp-14h] [ebp-1B4h] struct _Unwind_Exception *lpuexcpt; // [esp+0h] [ebp-1A0h] struct SjLj_Function_Context fctx; // [esp+4h] [ebp-19Ch] void *v8; // [esp+28h] [ebp-178h] std::string **v9; // [esp+2Ch] [ebp-174h] char v10; // [esp+40h] [ebp-160h] int v11; // [esp+184h] [ebp-1Ch] char v12; // [esp+188h] [ebp-18h] int *v13; // [esp+190h] [ebp-10h] v13 = &argc; fctx.personality = (_Unwind_Personality_Fn)__gxx_personality_sj0; fctx.lsda = dword_47CAB8; fctx.jbuf[0] = &v12; v8 = &loc_4015A5; v9 = &v4; _Unwind_SjLj_Register(&fctx); __main(); Sudu::Sudu(&v10); // v10中填充324個0 Sudu::set_data((int)&v10, (Sudu *)&_data_start__, v5);// 初始化數據,進入函數知道_data_start__應該是兩字爲一組,即4字節爲一組。 fctx.call_site = -1; std::string::string(&v11); fctx.call_site = 1; std::operator>><char,std::char_traits<char>,std::allocator<char>>((std::istream::sentry *)&std::cin, &v11); if ( (unsigned __int8)set_sudu((Sudu *)&v10, (const std::string *)&v11) ^ 1 )// 須要函數返回1 { std::operator<<<std::char_traits<char>>((std::ostream::sentry *)&std::cout, "fail"); std::ostream::operator<<(std::endl<char,std::char_traits<char>>); lpuexcpt = 0; } else { if ( Sudu::check((Sudu *)&v10) ) // 須要函數返回1 { fctx.call_site = 1; std::operator<<<std::char_traits<char>>((std::ostream::sentry *)&std::cout, "success"); } else { fctx.call_site = 1; std::operator<<<std::char_traits<char>>((std::ostream::sentry *)&std::cout, "fail"); } std::ostream::operator<<(std::endl<char,std::char_traits<char>>); lpuexcpt = 0; } std::string::~string(v4); _Unwind_SjLj_Unregister(&fctx); return (int)lpuexcpt; }
Sudu::set_data((int)&v10, (Sudu *)&_data_start__, v5);函數ide
int __userpurge Sudu::set_data@<eax>(int a1@<ecx>, Sudu *this, int (*a3)[9]) { int result; // eax signed int j; // [esp+Ch] [ebp-Ch] signed int i; // [esp+10h] [ebp-8h] for ( i = 0; i <= 8; ++i ) // 9行9列數據 { for ( j = 0; j <= 8; ++j ) { result = j + 9 * i; // i+1行j+1列的座標 *(_DWORD *)(a1 + 4 * result) = *((_DWORD *)this + 9 * i + j);// 能夠計算獲得al } } return result; }
使用腳本計算v10矩陣函數
origin = [ 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 6, 0, 0, 0, 7, 0, 0, 0, 8, 0, 0, 0, 9, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 6, 0, 0, 0, 7, 0, 0, 0, 8, 0, 0, 0, 9, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 7, 0, 0, 0, 8, 0, 0, 0, 9, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 6, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 6, 0, 0, 0, 7, 0, 0, 0, 8, 0, 0, 0, 9, 0, 0, 0, 1, 0, 0, 0, 5, 0, 0, 0, 6, 0, 0, 0, 7, 0, 0, 0, 8, 0, 0, 0, 9, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 9, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 6, 0, 0, 0, 7, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 6, 0, 0, 0, 7, 0, 0, 0, 8, 0, 0, 0, 9, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 6, 0, 0, 0, 7, 0, 0, 0, 8, 0, 0, 0, 9, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 9, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 6, 0, 0, 0, 7, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] key = [] for i in range(len(origin)//4): key.append(origin[i*4]) for i in range(9): for j in range(9): print(key[j+i*9], end=' ') print('')
0 0 7 5 0 0 0 6 0 0 2 0 0 1 0 0 0 7 9 0 0 0 3 0 4 0 0 2 0 1 0 0 0 0 0 0 0 3 0 1 0 0 0 0 5 0 0 0 0 0 0 7 1 0 4 0 0 0 0 8 2 0 0 0 0 5 9 0 0 0 8 0 0 8 0 0 0 1 0 0 3
第一處判斷條件測試
if ( (unsigned __int8)set_sudu((Sudu *)&v10, (const std::string *)&v11) ^ 1 )// 須要函數返回1
打開函數this
signed int __cdecl set_sudu(Sudu *a1, const std::string *a2) { std::string *v2; // ST00_4 std::string *v4; // [esp+0h] [ebp-38h] int v5; // [esp+Ch] [ebp-2Ch] int v6; // [esp+1Ch] [ebp-1Ch] int v7; // [esp+20h] [ebp-18h] char v8; // [esp+27h] [ebp-11h] const std::string *v9; // [esp+28h] [ebp-10h] int v10; // [esp+2Ch] [ebp-Ch] v10 = 0; v9 = a2; v7 = std::string::begin(v4); // 輸入字符串的起始字符 v6 = std::string::end(v2); // 輸入字符串的結束符 while ( __gnu_cxx::operator!=<char const*,std::string>((int)&v7, (int)&v6) )// 遍歷整個字符串 { v8 = *(_BYTE *)__gnu_cxx::__normal_iterator<char const*,std::string>::operator*(&v7);// v8=*v7,即遍歷指針v7指向的值 if ( (unsigned __int8)Sudu::set_number((int)a1, (Sudu *)(v10 / 9), v10 % 9, v8 - 48, v5) ^ 1 )// 第一個參數a1爲v10矩陣 // 第二個參數表示v10的行座標 // 第三個參數表示v10的列座標 // 第四個參數表示將輸入的字符數字轉爲整型數字 // 第五個參數表示? return 0; ++v10; __gnu_cxx::__normal_iterator<char const*,std::string>::operator++(&v7); } return 1; }
查看(unsigned __int8)Sudu::set_number((int)a1, (Sudu *)(v10 / 9), v10 % 9, v8 - 48, v5)spa
signed int __userpurge Sudu::set_number@<eax>(int a1@<ecx>, Sudu *this, int a3, int a4, int a5) { if ( !a4 ) return 1; if ( (signed int)this < 0 || (signed int)this > 8 || a3 < 0 || a3 > 8 || *(_DWORD *)(a1 + 4 * (a3 + 9 * (_DWORD)this))// 判斷a1[*this][a3]是否爲0 || a4 <= 0 || a4 > 9 ) // 須要這裏的條件不成立 { return 0; } *(_DWORD *)(a1 + 4 * (9 * (_DWORD)this + a3)) = a4;// a1[*this][a3]=a4,將輸入的非0數字寫入到矩陣中 return 1; }
返回主函數指針
if ( Sudu::check((Sudu *)&v10) ) // 須要函數返回1 { fctx.call_site = 1; std::operator<<<std::char_traits<char>>((std::ostream::sentry *)&std::cout, "success"); }
查看Sudu::check((Sudu *)&v10)code
bool __fastcall Sudu::check(Sudu *a1) { Sudu *v2; // [esp+0h] [ebp-4h] v2 = a1; return (unsigned __int8)Sudu::check_block((int)a1) && (unsigned __int8)Sudu::check_col((int)v2) && (unsigned __int8)Sudu::check_row((int)v2); }
打開(unsigned __int8)Sudu::check_block((int)a1)orm
signed int __fastcall Sudu::check_block(int a1) { char v2[10]; // [esp+12h] [ebp-26h] int v3; // [esp+1Ch] [ebp-1Ch] int v4; // [esp+20h] [ebp-18h] int l; // [esp+24h] [ebp-14h] int k; // [esp+28h] [ebp-10h] int j; // [esp+2Ch] [ebp-Ch] int i; // [esp+30h] [ebp-8h] for ( i = 0; i <= 8; ++i ) { for ( j = 1; j <= 9; ++j ) v2[j] = 1; for ( k = 0; k <= 8; ++k ) { v4 = 3 * (i / 3) + k / 3; v3 = 3 * (i % 3) + k % 3; // 觀察一組v4,v3的取值(v4表示矩陣橫座標,v3表示縱座標) // 0 0 (0,0) // 0 1 (0,1) // 0 2 (0,2) // 0 3 (1,0) // 0 4 (1,1) // 0 5 (1,2) // 0 6 (2,0) // 0 7 (2,1) // 0 8 (2,2) // 這是9x9矩陣中,左上的3x3矩陣 v2[*(_DWORD *)(a1 + 4 * (v3 + 9 * v4))] = 0;// 將矩陣9個值,分別將v2數組的9個值賦值爲0,若是3x3矩陣有重複數字,則必有v2[l]=1 } for ( l = 1; l <= 9; ++l ) { if ( v2[l] ) // 要返回1,所以須要v2[1]=0。則每一個3x3的矩陣中分佈着1~9的數字,且沒有重複。 // 這是數獨!!! return 0; } } return 1; }
總結:實際上這就是一個解v10矩陣的數獨遊戲,直接網上在線解9x9矩陣的數獨就行。(仔細看一下函數前面帶的Sudu::就是數獨(雖然正確是Shudu,哈哈哈~~~))
將填入的數字寫出來,已有的數字用0表示,在代碼檢測中將跳過0.
flag{340089102508406930016207058060875349709064820854392006093650071170023604602740590}