BUUCTF_Re_[ACTF新生赛2020]rome

main函数:

int func()
{
  int result; // eax
  int v1[4]; // [esp+14h] [ebp-44h]
  unsigned __int8 v2; // [esp+24h] [ebp-34h] BYREF
  unsigned __int8 v3; // [esp+25h] [ebp-33h]
  unsigned __int8 v4; // [esp+26h] [ebp-32h]
  unsigned __int8 v5; // [esp+27h] [ebp-31h]
  unsigned __int8 v6; // [esp+28h] [ebp-30h]
  int v7; // [esp+29h] [ebp-2Fh]
  int v8; // [esp+2Dh] [ebp-2Bh]
  int v9; // [esp+31h] [ebp-27h]
  int v10; // [esp+35h] [ebp-23h]
  unsigned __int8 v11; // [esp+39h] [ebp-1Fh]
  char v12[29]; // [esp+3Bh] [ebp-1Dh] BYREF

  strcpy(v12, "Qsw3sj_lz4_Ujw@l");
  printf("Please input:");
  scanf("%s", &v2);
  result = v2;
  if ( v2 == 'A' )
  {
    result = v3;
    if ( v3 == 'C' )
    {
      result = v4;
      if ( v4 == 'T' )
      {
        result = v5;
        if ( v5 == 'F' )
        {
          result = v6;
          if ( v6 == '{' )
          {
            result = v11;
            if ( v11 == '}' )
            {
              v1[0] = v7;
              v1[1] = v8;
              v1[2] = v9;
              v1[3] = v10;
              *&v12[17] = 0;
              while ( *&v12[17] <= 15 )
              {
                if ( *(v1 + *&v12[17]) > 64 && *(v1 + *&v12[17]) <= 90 )
                  *(v1 + *&v12[17]) = (*(v1 + *&v12[17]) - 51) % 26 + 65;
                if ( *(v1 + *&v12[17]) > 96 && *(v1 + *&v12[17]) <= 122 )
                  *(v1 + *&v12[17]) = (*(v1 + *&v12[17]) - 79) % 26 + 97;
                ++*&v12[17];
              }
              *&v12[17] = 0;
              while ( *&v12[17] <= 15 )
              {
                result = v12[*&v12[17]];
                if ( *(v1 + *&v12[17]) != result )
                  return result;
                ++*&v12[17];
              }
              result = printf("You are correct!");
            }
          }
        }
      }
    }
  }
  return result;
}

核心在中间两个while函数加密:

第一个while分析可以知道是对flag花括号里的字符进行大小写判断并加密

第二个while就是判断加密后的flag是否和前面的v12相等,如果相等就printf

这里加一个别人ida分析出来的main函数代码,和我的完全不一样,所以我就纠结了好久:

int func()
{
  int result; // eax
  int v1; // [esp+14h] [ebp-44h]
  int v2; // [esp+18h] [ebp-40h]
  int v3; // [esp+1Ch] [ebp-3Ch]
  int v4; // [esp+20h] [ebp-38h]
  unsigned __int8 v5; // [esp+24h] [ebp-34h]
  unsigned __int8 v6; // [esp+25h] [ebp-33h]
  unsigned __int8 v7; // [esp+26h] [ebp-32h]
  unsigned __int8 v8; // [esp+27h] [ebp-31h]
  unsigned __int8 v9; // [esp+28h] [ebp-30h]
  int v10; // [esp+29h] [ebp-2Fh]
  int v11; // [esp+2Dh] [ebp-2Bh]
  int v12; // [esp+31h] [ebp-27h]
  int v13; // [esp+35h] [ebp-23h]
  unsigned __int8 v14; // [esp+39h] [ebp-1Fh]
  char v15; // [esp+3Bh] [ebp-1Dh]
  char v16; // [esp+3Ch] [ebp-1Ch]
  char v17; // [esp+3Dh] [ebp-1Bh]
  char v18; // [esp+3Eh] [ebp-1Ah]
  char v19; // [esp+3Fh] [ebp-19h]
  char v20; // [esp+40h] [ebp-18h]
  char v21; // [esp+41h] [ebp-17h]
  char v22; // [esp+42h] [ebp-16h]
  char v23; // [esp+43h] [ebp-15h]
  char v24; // [esp+44h] [ebp-14h]
  char v25; // [esp+45h] [ebp-13h]
  char v26; // [esp+46h] [ebp-12h]
  char v27; // [esp+47h] [ebp-11h]
  char v28; // [esp+48h] [ebp-10h]
  char v29; // [esp+49h] [ebp-Fh]
  char v30; // [esp+4Ah] [ebp-Eh]
  char v31; // [esp+4Bh] [ebp-Dh]
  int i; // [esp+4Ch] [ebp-Ch]

  v15 = 'Q';
  v16 = 's';
  v17 = 'w';
  v18 = '3';
  v19 = 's';
  v20 = 'j';
  v21 = '_';
  v22 = 'l';
  v23 = 'z';
  v24 = '4';
  v25 = '_';
  v26 = 'U';
  v27 = 'j';
  v28 = 'w';
  v29 = '@';
  v30 = 'l';
  v31 = 0;
  printf("Please input:");
  scanf("%s", &v5);
  result = v5;
  if ( v5 == 'A' )
  {
    result = v6;
    if ( v6 == 'C' )
    {
      result = v7;
      if ( v7 == 'T' )
      {
        result = v8;
        if ( v8 == 'F' )
        {
          result = v9;
          if ( v9 == '{' )
          {
            result = v14;
            if ( v14 == '}' )
            {
              v1 = v10;
              v2 = v11;
              v3 = v12;
              v4 = v13;
              for ( i = 0; i <= 15; ++i )
              {
                if ( *((_BYTE *)&v1 + i) > 64 && *((_BYTE *)&v1 + i) <= 90 )//如果是大写字母
                  *((_BYTE *)&v1 + i) = (*((char *)&v1 + i) - 51) % 26 + 65;
                if ( *((_BYTE *)&v1 + i) > 96 && *((_BYTE *)&v1 + i) <= 122 )//如果是小写字母
                  *((_BYTE *)&v1 + i) = (*((char *)&v1 + i) - 79) % 26 + 97;
              }
              for ( i = 0; i <= 15; ++i )
              {
                result = (unsigned __int8)*(&v15 + i);
                if ( *((_BYTE *)&v1 + i) != (_BYTE)result )
                  return result;
              }
              result = printf("You are correct!");
            }
          }
        }
      }
    }
  }
  return result;
}

发现第一个循环开始前定义的单独变量,我的定义的就是一个数组,我一直想不明白数组怎么加减,

脚本逻辑就是在可见字符里遍历找到某个字符加密后和v12的值相等:

flag=''
v12='Qsw3sj_lz4_Ujw@l'
for i in range(16):
    for k in range(32,127):
        z=k
        if k>64 and k<=90:
            k=(k-51)%26+65
        if k>96 and k<=122:
            k=(k-79)%26+97
        if chr(k)==v12[i]:
            flag+=chr(z)
print(flag)

得到flag:

flag{Cae3ar_th4_Gre@t}

posted @ 2022-01-26 16:00  Luccky  阅读(92)  评论(0编辑  收藏  举报