buuctf-刮開有獎

題目: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}

相關文章
相關標籤/搜索