題目:ios
經過題目咱們能夠知道,咱們能成功輸入的值就是咱們的flag編程
下載附件後,發現是一個可執行的文件,執行一下,發現:網絡
輸入值後,直接閃退啦!查殼發現無殼後拖入IDA(32bit)內,f5反編譯進入主函數,發現函數
DialogBoxParamA函數裏的DialogFunc參數就很像網絡編程中基於消息的WSAAsyncSelect模型裏的消息處理函數,點進去後發現編碼
if ( (_WORD)a3 == 1001 ) { memset(&String, 0, 0xFFFFu); GetDlgItemTextA(hDlg, 1000, &String, 0xFFFF);#這裏要輸入字符串 if ( strlen(&String) == 8 )#長度爲八 { v7 = 90; v8 = 74; v9 = 83; v10 = 69; v11 = 67; v12 = 97; v13 = 78; v14 = 72; v15 = 51; v16 = 110; v17 = 103; sub_4010F0(&v7, 0, 10);#這裏對v7字符串進行了處理 memset(&v26, 0, 0xFFFFu); v26 = v23; v28 = v25; v27 = v24; v4 = (const char *)sub_401000(&v26, strlen(&v26));#這裏能夠推出以v23爲首地址的字符串(長度爲3) memset(&v26, 0, 0xFFFFu); v27 = v21; v26 = v20; v28 = v22; v5 = (const char *)sub_401000(&v26, strlen(&v26));#這裏能夠推出以v20爲首地址的字符串(長度爲3) if ( String == v7 + 34 && v19 == v11 && 4 * v20 - 141 == 3 * v9 && v21 / 4 == 2 * (v14 / 9) && !strcmp(v4, "ak1w") && !strcmp(v5, "V1Ax") ) { MessageBoxA(hDlg, "U g3t 1T!", "@_@", 0); } } return 0; } if ( (_WORD)a3 != 1 && (_WORD)a3 != 2 ) return 0; EndDialog(hDlg, (unsigned __int16)a3);
經過大概的分析程序,咱們能夠發現,咱們輸入的字符串的長度爲8字節,經過點進去v1九、v20,發現v18處地址對應的就是咱們輸入字符串的首地址,v1九、v20、...v25處地址就分別是字符串每一個字符的地址spa
因此,咱們只需把每一個對應的字符逆推出來,那麼也就獲得了咱們的flag啦。3d
開始逆推:code
首先咱們知道從v7至v17這11個變量的值,日後碰到 sub_4010F0(&v7, 0, 10)函數,點進去發現有對以v7爲首地址的字符進行了處理,直接粘貼,用C語言解出處理後對應的值blog
#include<stdio.h> #include<iostream> using namespace std; int sub(char a1[], int a2, int a3) { int result; // eax int i; // esi int v5; // ecx int v6; // edx result = a3; for ( i = a2; i <= a3; a2 = i ) { v5 = i; //v6 = *(DWORD *)(4 * i + a1); v6 = a1[i]; if ( a2 < result && i < result ) { do { //if ( v6 > *(DWORD *)(a1 + 4 * result) ) if ( v6 > a1[result] ) { if ( i >= result ) break; ++i; //*(DWORD *)(v5 + a1) = *(DWORD *)(a1 + 4 * result); a1[v5] = a1[result]; if ( i >= result ) break; //while ( *(DWORD *)(a1 + 4 * i) <= v6 ) while ( a1[i] <= v6 ) { if ( ++i >= result ) goto LABEL_13; } if ( i >= result ) break; v5 = i; //*(DWORD *)(a1 + 4 * result) = *(DWORD *)(4 * i + a1); a1[result] = a1[i]; } --result; } while ( i < result ); } LABEL_13: //*(DWORD *)(a1 + 4 * result) = v6; a1[result]= v6; sub(a1, a2, i - 1); result = a3; ++i; } return result; } int main() { char a[11]={90,74,83,69,67,97,78,72,51,110,103}; cout<<">>>>sub"<<endl; sub(a,0,10); for (int i=0;i<11;i++) { cout<<"a["<<i+7<<"]"<<a[i]<<" "<<int(a[i])<<endl; //cout<<a[i]<<" "; } }
運行結果爲:v8
繼續往下推,發現有 v4 = (const char *)sub_401000(&v26, strlen(&v26));和v5 = (const char *)sub_401000(&v26, strlen(&v26));點進去sub_401000發現(圖沒截全)
點進去byte_407830發現
可知,結果是通過base64編碼獲得的。
而後,咱們繼續日後推
if ( String == v7 + 34 && v19 == v11 && 4 * v20 - 141 == 3 * v9 && v21 / 4 == 2 * (v14 / 9) && !strcmp(v4, "ak1w") && !strcmp(v5, "V1Ax") ) { MessageBoxA(hDlg, "U g3t 1T!", "@_@", 0); }
經過這裏,咱們知道
string(v18)=v7+34=51+34=86='U'
V19='J'
v20='W'
v21='P'
又由於v4='ak1w',v5='V1Ax',經過base64解碼分別得,v4='jMp',v5='WP1',所以可知,v20='W',v21='P',v22='1'(v5);v23='j',v24='M',v25='p'(v4)
這樣咱們就獲得咱們的flag啦!!!即flag{UJWP1jMp}