zoukankan      html  css  js  c++  java
  • BUUCTF-RE-刮开有奖

    一、查壳

    二、IDA分析

    1 int __stdcall WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
    2 {
    3   DialogBoxParamA(hInstance, (LPCSTR)0x67, 0, DialogFunc, 0);
    4   return 0;
    5 }

    关键函数为DialogFunc,进入该函数分析

     1 BOOL __stdcall DialogFunc(HWND hDlg, UINT a2, WPARAM a3, LPARAM a4)
     2 {
     3   const char *v4; // esi
     4   const char *v5; // edi
     5   int v7; // [esp+8h] [ebp-20030h]
     6   int v8; // [esp+Ch] [ebp-2002Ch]
     7   int v9; // [esp+10h] [ebp-20028h]
     8   int v10; // [esp+14h] [ebp-20024h]
     9   int v11; // [esp+18h] [ebp-20020h]
    10   int v12; // [esp+1Ch] [ebp-2001Ch]
    11   int v13; // [esp+20h] [ebp-20018h]
    12   int v14; // [esp+24h] [ebp-20014h]
    13   int v15; // [esp+28h] [ebp-20010h]
    14   int v16; // [esp+2Ch] [ebp-2000Ch]
    15   int v17; // [esp+30h] [ebp-20008h]
    16   CHAR String; // [esp+34h] [ebp-20004h]
    17   char v19; // [esp+35h] [ebp-20003h]
    18   char v20; // [esp+36h] [ebp-20002h]
    19   char v21; // [esp+37h] [ebp-20001h]
    20   char v22; // [esp+38h] [ebp-20000h]
    21   char v23; // [esp+39h] [ebp-1FFFFh]
    22   char v24; // [esp+3Ah] [ebp-1FFFEh]
    23   char v25; // [esp+3Bh] [ebp-1FFFDh]
    24   char v26; // [esp+10034h] [ebp-10004h]
    25   char v27; // [esp+10035h] [ebp-10003h]
    26   char v28; // [esp+10036h] [ebp-10002h]
    27 
    28   if ( a2 == 272 )
    29     return 1;
    30   if ( a2 != 273 )
    31     return 0;
    32   if ( (_WORD)a3 == 1001 )
    33   {
    34     memset(&String, 0, 0xFFFFu);
    35     GetDlgItemTextA(hDlg, 1000, &String, 0xFFFF);
    36     if ( strlen(&String) == 8 )
    37     {
    38       v7 = 90;
    39       v8 = 74;
    40       v9 = 83;
    41       v10 = 69;
    42       v11 = 67;
    43       v12 = 97;
    44       v13 = 78;
    45       v14 = 72;
    46       v15 = 51;
    47       v16 = 110;
    48       v17 = 103;
    49       sub_4010F0((int)&v7, 0, 10);
    50       memset(&v26, 0, 0xFFFFu);
    51       v26 = v23;
    52       v28 = v25;
    53       v27 = v24;
    54       v4 = sub_401000((int)&v26, strlen(&v26));
    55       memset(&v26, 0, 0xFFFFu);
    56       v27 = v21;
    57       v26 = v20;
    58       v28 = v22;
    59       v5 = sub_401000((int)&v26, strlen(&v26));
    60       if ( String == v7 + 34
    61         && v19 == v11
    62         && 4 * v20 - 141 == 3 * v9
    63         && v21 / 4 == 2 * (v14 / 9)
    64         && !strcmp(v4, "ak1w")
    65         && !strcmp(v5, "V1Ax") )
    66       {
    67         MessageBoxA(hDlg, "U g3t 1T!", "@_@", 0);
    68       }
    69     }
    70     return 0;
    71   }
    72   if ( (_WORD)a3 != 1 && (_WORD)a3 != 2 )
    73     return 0;
    74   EndDialog(hDlg, (unsigned __int16)a3);
    75   return 1;
    76 }

    通过第36行代码知道String是我们输入的flag,长度应该是8。

    第49行函数sub_4010F0在对v9~v19操作,进入sub_4010F0函数再次分析,把该函数的操作写成C,将数组代入后输出数值。基本上就是将该函数之间复制,再令其输出。

     1 #include <iostream>
     2 #include<stdio.h>
     3 #include<stdlib.h>
     4 
     5 using namespace std;
     6 
     7 int __cdecl sub_4010F0(char *a1, int a2, int a3)
     8 {
     9     int result; // eax
    10     int i; // esi
    11     int v5; // ecx
    12     int v6; // edx
    13 
    14     result = a3;
    15     for (i = a2; i <= a3; a2 = i)
    16     {
    17         v5 =  i;
    18         v6 = a1[i];
    19         if (a2 < result && i < result)
    20         {
    21             do
    22             {
    23                 if (v6 > a1[result])
    24                 {
    25                     if (i >= result)
    26                         break;
    27                     ++i;
    28                     a1[v5] = a1[result];
    29                     if (i >= result)
    30                         break;
    31                     while (a1[i] <= v6)
    32                     {
    33                         if (++i >= result)
    34                             goto LABEL_13;
    35                     }
    36                     if (i >= result)
    37                         break;
    38                     v5 = i;
    39                     a1[result] = a1[i];
    40                 }
    41                 --result;
    42             } while (i < result);
    43         }
    44     LABEL_13:
    45         a1[result] = v6;
    46         sub_4010F0(a1, a2, i - 1);
    47         result = a3;
    48         ++i;
    49     }
    50     return result;
    51 }
    52 int main(){
    53     char a[20] = {90, 74, 83, 69, 67, 97, 78, 72, 51, 110, 103};
    54     cout << a << endl;
    55     sub_4010F0(a, 0, 10);
    56     cout << a << endl;
    57     return 0;
    58 }

    输出为:

    第54、56行代码对v23、v25、v24      ,   v21、v20、v22的字符串进行了函数 sub_401000的操作

    v23对应的是var_1FFFF,v25是var_1FFFD,v24是var_1FFFE

    v21对应的是var_20001,v20对应的是var_20002,v22对应的是var_20000

    进入sub_401000分析  这六个字符对应的是v2-v4,v5-v7

     1 _BYTE *__cdecl sub_401000(int a1, int a2)
     2 {
     3   int v2; // eax
     4   int v3; // esi
     5   size_t v4; // ebx
     6   _BYTE *v5; // eax
     7   _BYTE *v6; // edi
     8   int v7; // eax
     9   _BYTE *v8; // ebx
    10   int v9; // edi
    11   signed int v10; // edx
    12   int v11; // edi
    13   signed int v12; // eax
    14   signed int v13; // esi
    15   _BYTE *result; // eax
    16   _BYTE *v15; // [esp+Ch] [ebp-10h]
    17   _BYTE *v16; // [esp+10h] [ebp-Ch]
    18   int v17; // [esp+14h] [ebp-8h]
    19   int v18; // [esp+18h] [ebp-4h]
    20 
    21   v2 = a2 / 3;
    22   v3 = 0;
    23   if ( a2 % 3 > 0 )
    24     ++v2;
    25   v4 = 4 * v2 + 1;
    26   v5 = malloc(v4);
    27   v6 = v5;
    28   v15 = v5;
    29   if ( !v5 )
    30     exit(0);
    31   memset(v5, 0, v4);
    32   v7 = a2;
    33   v8 = v6;
    34   v16 = v6;
    35   if ( a2 > 0 )
    36   {
    37     while ( 1 )
    38     {
    39       v9 = 0;
    40       v10 = 0;
    41       v18 = 0;
    42       do
    43       {
    44         if ( v3 >= v7 )
    45           break;
    46         ++v10;
    47         v9 = *(unsigned __int8 *)(v3++ + a1) | (v9 << 8);
    48       }
    49       while ( v10 < 3 );
    50       v11 = v9 << 8 * (3 - v10);
    51       v12 = 0;
    52       v17 = v3;
    53       v13 = 18;
    54       do
    55       {
    56         if ( v10 >= v12 )
    57         {
    58           *((_BYTE *)&v18 + v12) = (v11 >> v13) & 0x3F;
    59           v8 = v16;
    60         }
    61         else
    62         {
    63           *((_BYTE *)&v18 + v12) = 64;
    64         }
    65         *v8++ = byte_407830[*((char *)&v18 + v12)];
    66         v13 -= 6;
    67         ++v12;
    68         v16 = v8;
    69       }
    70       while ( v13 > -6 );
    71       v3 = v17;
    72       if ( v17 >= a2 )
    73         break;
    74       v7 = a2;
    75     }
    76     v6 = v15;
    77   }
    78   result = v6;
    79   *v8 = 0;
    80   return result;
    81 }

    发现有 byte_407830数组,

    .rdata:00407830 ; char byte_407830[]
    .rdata:00407830 byte_407830     db 41h                  ; DATA XREF: sub_401000+C0↑r
    .rdata:00407831 aBcdefghijklmno db 'BCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=',0

    查看该数组认定该函数是在做base64加密

    再结合正确flag的条件可知,v5,v6,v7  base64之后,等于'ak1w',v2,v3,v4加密之后等于'V1Ax'

    分析正确flag的条件

    if ( String == v7 + 34    //String == '3'+34  为'U'
    && v19 == v11    //v11为‘J’

    && 4 * v20 - 141 == 3 * v9 && v21 / 4 == 2 * (v14 / 9) //('E'*3+141)/4 为'W'
    && !strcmp(v4, "ak1w")  //'ak1w'解码为jMp

    && !strcmp(v5, "V1Ax") ) //'V1Ax'解码为WP1

    拼一下即

    三、flag

    flag{UJWP1jMp}

  • 相关阅读:
    读书笔记:C++ Primer系列(10)—— 数组与指针(2)
    读书笔记:C++ Primer系列(9)—— 数组与指针(1)
    牛人博客
    读书笔记:C++ Primer系列(8)—— 标准库类型之bitset
    读书笔记:C++ Primer系列(7)—— 标准库类型之iterator
    读书笔记:C++ Primer系列(6)—— 标准库类型之vector
    读书笔记:C++ Primer系列(5)—— 标准库类型之string
    读书笔记:C++ Primer系列(4)—— 关于const限定符
    读书笔记:C++ Primer系列(3)—— 关于变量
    黑色半透明镂空遮罩指引效果实现jQuery小插件
  • 原文地址:https://www.cnblogs.com/Nickyl07/p/12637623.html
Copyright © 2011-2022 走看看