• buuctf-刮开有奖


    题目:

     通过题目我们可以知道,我们能成功输入的值就是我们的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字节,通过点进去v19、v20,发现v18处地址对应的就是我们输入字符串的首地址,v19、v20、...v25处地址就分别是字符串每个字符的地址

     所以,我们只需把每个对应的字符逆推出来,那么也就得到了我们的flag啦。

    开始逆推:

    首先我们知道从v7至v17这11个变量的值,往后碰到 sub_4010F0(&v7, 0, 10)函数,点进去发现有对以v7为首地址的字符进行了处理,直接粘贴,用C语言解出处理后对应的值

    #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]<<" ";
        }
    }

    运行结果为:

    继续往下推,发现有 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}

  • 相关阅读:
    rem单位
    JS_高程5.引用类型(5)Array类型的操作方法
    JS_理解函数参数按值传递
    JS_高程5.引用类型(4)Array类型的各类方法
    JS_高程5.引用类型(3)Array类型-检测数组
    JS_高程5.引用类型(2)Array类型
    JS_高程5.引用类型(1)Object类型
    JS_高程4.变量,作用域和内存问题(3)垃圾收集
    JS_高程4.变量,作用域和内存问题(2)执行环境及作用域
    JS_高程4.变量,作用域和内存问题(1)
  • 原文地址:https://www.cnblogs.com/jane315/p/12913848.html
Copyright © 2020-2023  润新知