攻防世界RE:CatFly

文件到手 先拖进IDA 发现可以用linux运行一下

运行效果如图,最下面指示次数,最上面有字符串,猜测Flag可能和最上面的字符串有关系。回到IDA,搜索一下Main函数

跳转到0x681A

__int64 __fastcall main(int a1, char **a2, char **a3)
{
  size_t v3; // rbx
  __int16 v5[4]; // [rsp+10h] [rbp-4B0h] BYREF
  time_t time1; // [rsp+18h] [rbp-4A8h] BYREF
  time_t timer; // [rsp+20h] [rbp-4A0h] BYREF
  int longind; // [rsp+2Ch] [rbp-494h] BYREF
  __int64 s[129]; // [rsp+30h] [rbp-490h] BYREF
  int v10; // [rsp+43Ch] [rbp-84h]
  double v11; // [rsp+440h] [rbp-80h]
  char *v12; // [rsp+448h] [rbp-78h]
  int v13; // [rsp+450h] [rbp-70h]
  unsigned int v14; // [rsp+454h] [rbp-6Ch]
  unsigned __int8 v15; // [rsp+45Ah] [rbp-66h]
  char v16; // [rsp+45Bh] [rbp-65h]
  int n; // [rsp+45Ch] [rbp-64h]
  int v18; // [rsp+460h] [rbp-60h]
  char v19; // [rsp+467h] [rbp-59h]
  int m; // [rsp+468h] [rbp-58h]
  unsigned int k; // [rsp+46Ch] [rbp-54h]
  char v22; // [rsp+473h] [rbp-4Dh]
  int v23; // [rsp+474h] [rbp-4Ch]
  unsigned __int64 v24; // [rsp+478h] [rbp-48h]
  int v25; // [rsp+484h] [rbp-3Ch]
  int v26; // [rsp+488h] [rbp-38h]
  int v27; // [rsp+48Ch] [rbp-34h]
  char v28; // [rsp+490h] [rbp-30h]
  bool v29; // [rsp+491h] [rbp-2Fh]
  unsigned __int16 v30; // [rsp+492h] [rbp-2Eh]
  int v31; // [rsp+494h] [rbp-2Ch]
  unsigned int v32; // [rsp+498h] [rbp-28h]
  unsigned int i; // [rsp+49Ch] [rbp-24h]
  int v34; // [rsp+4A0h] [rbp-20h]
  unsigned int j; // [rsp+4A4h] [rbp-1Ch]
  char *haystack; // [rsp+4A8h] [rbp-18h]

  haystack = 0LL;
  i = 0;
  v32 = 0;
  v31 = 0;
  memset(s, 0, 1024);
  v30 = 0;
  v29 = 0;
  v28 = 0;
  v27 = 90;
  while ( 1 )
  {
    v26 = getopt_long(a1, a2, "eshiItnd:f:r:R:c:C:W:H:", &longopts, &longind);
    if ( v26 == -1 )
      break;
    if ( !v26 && !*((_QWORD *)&longopts.flag + 4 * longind) )
      v26 = *(&longopts.val + 8 * longind);
    switch ( v26 )
    {
      case 'C':
        dword_E1F8 = atoi(optarg);
        break;
      case 'H':
        dword_E1EC = (64 - atoi(optarg)) / 2;
        dword_E1F0 = (atoi(optarg) + 64) / 2;
        break;
      case 'I':
        v28 = 1;
        break;
      case 'R':
        dword_E1F0 = atoi(optarg);
        break;
      case 'W':
        dword_E1F4 = (64 - atoi(optarg)) / 2;
        dword_E1F8 = (atoi(optarg) + 64) / 2;
        break;
      case 'c':
        dword_E1F4 = atoi(optarg);
        break;
      case 'd':
        if ( atoi(optarg) > 9 && atoi(optarg) <= 1000 )
          v27 = atoi(optarg);
        break;
      case 'e':
        dword_E104 = 0;
        break;
      case 'f':
        dword_104C4 = atoi(optarg);
        break;
      case 'h':
        sub_67F0(a2);
        exit(0);
      case 'i':
        v29 = 1;
        break;
      case 'r':
        dword_E1EC = atoi(optarg);
        break;
      case 's':
        dword_E108 = 0;
        break;
      case 't':
        dword_104C0 = 1;
        break;
      default:
        continue;
    }
  }
  if ( dword_104C0 )
  {
    v29 = v28 == 0;
    sub_6669();
    for ( i = 0; i <= 0xFF; ++i )
    {
      if ( *((_BYTE *)&unk_104E0 + i) )
      {
        sub_66AF(*((unsigned __int8 *)&unk_104E0 + i), i);
        fflush(stdout);
      }
    }
    for ( i = 0; i <= 0xFF; ++i )
    {
      if ( *((_BYTE *)&unk_105E0 + i) )
      {
        sub_66AF(*((unsigned __int8 *)&unk_105E0 + i), i);
        fflush(stdout);
      }
    }
    signal(14, sub_64C0);
    if ( !_setjmp(env) )
    {
      alarm(1u);
LABEL_58:
      while ( !feof(stdin) && v32 <= 1 )
      {
        v16 = getchar();
        v15 = 0;
        if ( v16 == -1 )
        {
          v16 = getchar();
          switch ( v16 )
          {
            case -16:
              v31 = 0;
              if ( LOBYTE(s[0]) == 24 )
              {
                alarm(2u);
                haystack = strndup((const char *)s + 2, 0x3FEuLL);
                ++v32;
              }
              else if ( LOBYTE(s[0]) == 31 )
              {
                alarm(2u);
                dword_E1FC = (BYTE1(s[0]) << 8) | BYTE2(s[0]);
                dword_E200 = (BYTE3(s[0]) << 8) | BYTE4(s[0]);
                ++v32;
              }
              break;
            case -15:
              sub_66AF(241LL, 0LL);
              fflush(stdout);
              break;
            case -6:
              v31 = 1;
              v30 = 0;
              memset(s, 0, 0x400uLL);
              break;
            case -5:
            case -4:
              v15 = getchar();
              if ( !*((_BYTE *)&unk_105E0 + v15) )
                *((_BYTE *)&unk_105E0 + v15) = -4;
              sub_66AF(*((unsigned __int8 *)&unk_105E0 + v15), v15);
              fflush(stdout);
              if ( v16 == -5 && v15 == 24 )
              {
                printf("%c%c%c%c%c%c", 255LL, 250LL, 24LL, 1LL, 255LL, 240LL);
                fflush(stdout);
              }
              break;
            case -3:
            case -2:
              v15 = getchar();
              if ( !*((_BYTE *)&unk_104E0 + v15) )
                *((_BYTE *)&unk_104E0 + v15) = -2;
              sub_66AF(*((unsigned __int8 *)&unk_104E0 + v15), v15);
              fflush(stdout);
              break;
            case -1:
              v32 = 2;
              break;
            default:
              goto LABEL_58;
          }
        }
        else if ( v31 && v30 <= 0x3FEu )
        {
          *((_BYTE *)s + v30++) = v16;
        }
      }
    }
    alarm(0);
  }
  else
  {
    haystack = getenv("TERM");
    ioctl(0, 0x5413uLL, v5);
    dword_E1FC = (unsigned __int16)v5[1];
    dword_E200 = (unsigned __int16)v5[0];
  }
  v34 = 2;
  if ( haystack )
  {
    for ( j = 0; ; ++j )
    {
      v3 = j;
      if ( v3 >= strlen(haystack) )
        break;
      haystack[j] = tolower(haystack[j]);
    }
    if ( strstr(haystack, "xterm") )
    {
      v34 = 1;
    }
    else if ( strstr(haystack, "toaru") )
    {
      v34 = 1;
    }
    else if ( strstr(haystack, "linux") )
    {
      v34 = 3;
    }
    else if ( strstr(haystack, "vtnt") )
    {
      v34 = 5;
    }
    else if ( strstr(haystack, "cygwin") )
    {
      v34 = 5;
    }
    else if ( strstr(haystack, "vt220") )
    {
      v34 = 6;
    }
    else if ( strstr(haystack, "fallback") )
    {
      v34 = 4;
    }
    else if ( strstr(haystack, "rxvt-256color") )
    {
      v34 = 1;
    }
    else if ( strstr(haystack, "rxvt") )
    {
      v34 = 3;
    }
    else if ( strstr(haystack, "vt100") && dword_E1FC == 40 )
    {
      v34 = 7;
    }
    else if ( !strncmp(haystack, "st", 2uLL) )
    {
      v34 = 1;
    }
  }
  v25 = 0;
  signal(2, sub_64A8);
  signal(13, sub_64E6);
  if ( !dword_104C0 )
    signal(28, handler);
  switch ( v34 )
  {
    case 1:
      qword_FE20 = (__int64)"\x1B[48;5;17m";
      qword_FE30 = (__int64)"\x1B[48;5;231m";
      qword_FDF8 = (__int64)"\x1B[48;5;16m";
      qword_FEC0 = (__int64)"\x1B[48;5;230m";
      qword_FDE0 = (__int64)"\x1B[48;5;175m";
      qword_FE28 = (__int64)"\x1B[48;5;162m";
      qword_FEB0 = (__int64)"\x1B[48;5;196m";
      qword_FDF0 = (__int64)"\x1B[48;5;214m";
      qword_FE18 = (__int64)"\x1B[48;5;226m";
      qword_FDD8 = (__int64)"\x1B[48;5;118m";
      qword_FEA8 = (__int64)"\x1B[48;5;33m";
      qword_FE98 = (__int64)"\x1B[48;5;19m";
      qword_FE10 = (__int64)"\x1B[48;5;240m";
      qword_FDE8 = (__int64)"\x1B[48;5;175m";
      break;
    case 2:
      qword_FE20 = (__int64)"\x1B[104m";
      qword_FE30 = (__int64)"\x1B[107m";
      qword_FDF8 = (__int64)"\x1B[40m";
      qword_FEC0 = (__int64)"\x1B[47m";
      qword_FDE0 = (__int64)"\x1B[105m";
      qword_FE28 = (__int64)"\x1B[101m";
      qword_FEB0 = (__int64)"\x1B[101m";
      qword_FDF0 = (__int64)"\x1B[43m";
      qword_FE18 = (__int64)"\x1B[103m";
      qword_FDD8 = (__int64)"\x1B[102m";
      qword_FEA8 = (__int64)"\x1B[104m";
      qword_FE98 = (__int64)"\x1B[44m";
      qword_FE10 = (__int64)"\x1B[100m";
      qword_FDE8 = (__int64)"\x1B[105m";
      break;
    case 3:
      qword_FE20 = (__int64)"\x1B[25;44m";
      qword_FE30 = (__int64)"\x1B[5;47m";
      qword_FDF8 = (__int64)"\x1B[25;40m";
      qword_FEC0 = (__int64)"\x1B[5;47m";
      qword_FDE0 = (__int64)"\x1B[5;45m";
      qword_FE28 = (__int64)"\x1B[5;41m";
      qword_FEB0 = (__int64)"\x1B[5;41m";
      qword_FDF0 = (__int64)"\x1B[25;43m";
      qword_FE18 = (__int64)"\x1B[5;43m";
      qword_FDD8 = (__int64)"\x1B[5;42m";
      qword_FEA8 = (__int64)"\x1B[25;44m";
      qword_FE98 = (__int64)"\x1B[5;44m";
      qword_FE10 = (__int64)"\x1B[5;40m";
      qword_FDE8 = (__int64)"\x1B[5;45m";
      break;
    case 4:
      qword_FE20 = (__int64)"\x1B[0;34;44m";
      qword_FE30 = (__int64)"\x1B[1;37;47m";
      qword_FDF8 = (__int64)"\x1B[0;30;40m";
      qword_FEC0 = (__int64)"\x1B[1;37;47m";
      qword_FDE0 = (__int64)"\x1B[1;35;45m";
      qword_FE28 = (__int64)"\x1B[1;31;41m";
      qword_FEB0 = (__int64)"\x1B[1;31;41m";
      qword_FDF0 = (__int64)"\x1B[0;33;43m";
      qword_FE18 = (__int64)"\x1B[1;33;43m";
      qword_FDD8 = (__int64)"\x1B[1;32;42m";
      qword_FEA8 = (__int64)"\x1B[1;34;44m";
      qword_FE98 = (__int64)"\x1B[0;34;44m";
      qword_FE10 = (__int64)"\x1B[1;30;40m";
      qword_FDE8 = (__int64)"\x1B[1;35;45m";
      off_FA88 = (char *)&unk_BCFF;
      break;
    case 5:
      qword_FE20 = (__int64)"\x1B[0;34;44m";
      qword_FE30 = (__int64)"\x1B[1;37;47m";
      qword_FDF8 = (__int64)"\x1B[0;30;40m";
      qword_FEC0 = (__int64)"\x1B[1;37;47m";
      qword_FDE0 = (__int64)"\x1B[1;35;45m";
      qword_FE28 = (__int64)"\x1B[1;31;41m";
      qword_FEB0 = (__int64)"\x1B[1;31;41m";
      qword_FDF0 = (__int64)"\x1B[0;33;43m";
      qword_FE18 = (__int64)"\x1B[1;33;43m";
      qword_FDD8 = (__int64)"\x1B[1;32;42m";
      qword_FEA8 = (__int64)"\x1B[1;34;44m";
      qword_FE98 = (__int64)"\x1B[0;34;44m";
      qword_FE10 = (__int64)"\x1B[1;30;40m";
      qword_FDE8 = (__int64)"\x1B[1;35;45m";
      off_FA88 = (char *)&unk_BD06;
      break;
    case 6:
      qword_FE20 = (__int64)&unk_BD09;
      qword_FE30 = (__int64)&unk_BD0C;
      qword_FDF8 = (__int64)"  ";
      qword_FEC0 = (__int64)&unk_BD0F;
      qword_FDE0 = (__int64)&unk_BD12;
      qword_FE28 = (__int64)&unk_BD15;
      qword_FEB0 = (__int64)&unk_BD0F;
      qword_FDF0 = (__int64)&unk_BD18;
      qword_FE18 = (__int64)&unk_BD1B;
      qword_FDD8 = (__int64)&unk_BD1E;
      qword_FEA8 = (__int64)&unk_BD21;
      qword_FE98 = (__int64)&unk_BD24;
      qword_FE10 = (__int64)&unk_BD27;
      qword_FDE8 = (__int64)&unk_BD2A;
      v25 = 1;
      break;
    case 7:
      qword_FE20 = (__int64)&unk_BD2D;
      qword_FE30 = (__int64)&unk_BD2F;
      qword_FDF8 = (__int64)&unk_BD31;
      qword_FEC0 = (__int64)&unk_BD33;
      qword_FDE0 = (__int64)&unk_BD35;
      qword_FE28 = (__int64)&unk_BD37;
      qword_FEB0 = (__int64)&unk_BD33;
      qword_FDF0 = (__int64)&unk_BD39;
      qword_FE18 = (__int64)&unk_BD3B;
      qword_FDD8 = (__int64)&unk_BD3D;
      qword_FEA8 = (__int64)&unk_BD3F;
      qword_FE98 = (__int64)&unk_BD41;
      qword_FE10 = (__int64)&unk_BD43;
      qword_FDE8 = (__int64)&unk_BD45;
      v25 = 1;
      dword_E1FC = 40;
      break;
    default:
      break;
  }
  if ( dword_E1F4 == dword_E1F8 )
  {
    dword_E1F4 = (dword_E1FC / -2 + 64) / 2;
    dword_E1F8 = (dword_E1FC / 2 + 64) / 2;
    byte_104CB = 1;
  }
  if ( dword_E1EC == dword_E1F0 )
  {
    dword_E1EC = (65 - dword_E200) / 2;
    dword_E1F0 = (dword_E200 + 63) / 2;
    byte_104CC = 1;
  }
  if ( dword_E108 )
  {
    printf("\x1BkNyanyanyanyanyanyanya...\x1B\\");
    printf("\x1B]1;Nyanyanyanyanyanyanya...\a");
    printf("\x1B]2;Nyanyanyanyanyanyanya...\a");
  }
  if ( dword_E104 )
    printf("\x1B[H\x1B[2J\x1B[?25l");
  else
    printf("\x1B[s");
  if ( v29 )
  {
    v14 = 5;
    for ( j = 0; j < v14; ++j )
    {
      sub_65E2(3LL);
      printf("                             \x1B[1mNyancat Telnet Server\x1B[0m");
      sub_65E2(2LL);
      printf("                   written and run by \x1B[1;32mK. Lange\x1B[1;34m @_klange\x1B[0m");
      sub_65E2(2LL);
      printf("        If things don't look right, try:");
      sub_65E2(1LL);
      printf("                TERM=fallback telnet ...");
      sub_65E2(2LL);
      printf("        Or on Windows:");
      sub_65E2(1LL);
      printf("                telnet -t vtnt ...");
      sub_65E2(2LL);
      printf("        Problems? Check the website:");
      sub_65E2(1LL);
      printf("                \x1B[1;34mhttp://nyancat.dakko.us\x1B[0m");
      sub_65E2(2LL);
      printf("        This is a telnet server, remember your escape keys!");
      sub_65E2(1LL);
      printf("                \x1B[1;31m^]quit\x1B[0m to exit");
      sub_65E2(2LL);
      printf("        Starting in %d...                \n", v14 - j);
      fflush(stdout);
      usleep(0x61A80u);
      if ( dword_E104 )
        printf("\x1B[H");
      else
        printf("\x1B[u");
    }
    if ( dword_E104 )
      printf("\x1B[H\x1B[2J\x1B[?25l");
  }
  time(&timer);
  v13 = 1;
  v24 = 0LL;
  v23 = 0;
  v22 = 0;
  v12 = off_FA88;
  while ( v13 )
  {
    if ( dword_E104 )
      printf("\x1B[H");
    else
      printf("\x1B[u");
    for ( k = dword_E1EC; (int)k < dword_E1F0; ++k )
    {
      for ( m = dword_E1F4; m < dword_E1F8; ++m )
      {
        if ( (int)k <= 23 || (int)k > 42 || m >= 0 )
        {
          if ( m >= 0 && k <= 63 && m <= 63 )
          {
            v19 = off_FA20[v24][k][m];
            off_FA88 = sub_6314((unsigned int)v24, k, m, (__int64)v12);
          }
          else
          {
            v19 = 44;
          }
        }
        else
        {
          v18 = (2 - m) % 16 / 8;
          if ( ((v24 >> 1) & 1) != 0 )
            v18 = 1 - v18;
          s[128] = (__int64)",,>>&&&+++###==;;;,,";
          v19 = asc_BFE3[v18 + k - 23];
          if ( !v19 )
            v19 = 44;
        }
        if ( v25 )
        {
          printf("%s", *((const char **)&unk_FCC0 + v19));
        }
        else if ( v19 == v22 || !*((_QWORD *)&unk_FCC0 + v19) )
        {
          printf("%s", off_FA88);
        }
        else
        {
          v22 = v19;
          printf("%s%s", *((const char **)&unk_FCC0 + v19), off_FA88);
        }
      }
      sub_65E2(1LL);
    }
    if ( dword_E100 )
    {
      time(&time1);
      v11 = difftime(time1, timer);
      v10 = sub_63FF((unsigned int)(int)v11);
      for ( n = (dword_E1FC - 29 - v10) / 2; n > 0; --n )
        putchar(32);
      dword_E1E8 += printf("\x1B[1;37mYou have nyaned for %d times!\x1B[J\x1B[0m", (unsigned int)++dword_108E0);
    }
    v22 = 0;
    ++v23;
    if ( dword_104C4 && v23 == dword_104C4 )
      sub_6471();
    if ( !off_FA20[++v24] )
      v24 = 0LL;
    usleep(1000 * v27);
  }
  return 0LL;
}

根据printf的输出来找,那么跟输出字符串相关的是off_FA88,而且注意到这里有dword_E1E8 += printf("\x1B[1;37mYou have nyaned for %d times!\x1B[J\x1B[0m", (unsigned int)++dword_108E0); 是最下面一行的输出。

我们先来看off_FA88 = sub_6314((unsigned int)v24, k, m, (__int64)v12);

跳转到sub_6314

char *__fastcall sub_6314(__int64 a1, int a2, int a3, __int64 a4)
{
  if ( a2 != 18 )
    return (char *)a4;
  if ( a3 <= 4 || a3 > 54 )
    return (char *)a4;
  byte_104C9 = 32;
  dword_E120[a3 - 5] ^= sub_62B5();
  if ( (unsigned __int8)sub_62E3(dword_E120[a3 - 5]) )
    byte_104C8 = dword_E120[a3 - 5] & 0x7F;
  else
    byte_104C8 = 32;
  return &byte_104C8;
}

注意传入的参数a4,即v12,其实就是off_FA88。所以这里只在a2=18的时候运行,下方代码在a3=0到a3=50各执行一次。相当于一个循环。

写出如下C++代码

 

 

sub6314用到了我们不知道的E120,先追过去看

直接提取出来数组 

unsigned int e120[] = { 0x27FB ,0x27A4 ,0x464E ,0x0E36 ,0x7B70 ,0x5E7A ,0x1A4A ,0x45C1 ,0x2BDF ,0x23BD ,0x3A15 ,0x5B83 ,0x1E15 ,0x5367,
0x50B8 ,0x20CA ,0x41F5 ,0x57D1 ,0x7750 ,0x2ADF ,0x11F8 ,0x9BB ,0x5724 ,0x7374 ,0x3CE6 ,0x646E ,0x10C ,0x6E10 ,0x64F4,
0x3263 ,0x3137 ,0x0B8 ,0x229C ,0x7BCD ,0x73BD ,0x480C ,0x14DB ,0x68B9 ,0x5C8A ,0x1B61 ,0x6C59 ,0x5707 ,0x9E6 ,0x1FB9,
0x2AD3 ,0x76D4 ,0x3113 ,0x7C7E ,0x11E0 ,0x6C70 };

发现在62B5里面也更改了、而且返回也用到了E1E8的值,想起来我们在main函数看到的printf。

dword_E1E8 += printf("\x1B[1;37mYou have nyaned for %d times!\x1B[J\x1B[0m", (unsigned int)++dword_108E0);

我们知道printf函数的返回值,其实就是打印出来的字符串的长度。

所以只需要在外面再套一层while(1)死循环,每一次都执行E1E8的自增。直到获得Flag后跳出。

完整代码如下:


#include<iostream>

unsigned int e120[] = { 0x27FB ,0x27A4 ,0x464E ,0x0E36 ,0x7B70 ,0x5E7A ,0x1A4A ,0x45C1 ,0x2BDF ,0x23BD ,0x3A15 ,0x5B83 ,0x1E15 ,0x5367,
0x50B8 ,0x20CA ,0x41F5 ,0x57D1 ,0x7750 ,0x2ADF ,0x11F8 ,0x9BB ,0x5724 ,0x7374 ,0x3CE6 ,0x646E ,0x10C ,0x6E10 ,0x64F4,
0x3263 ,0x3137 ,0x0B8 ,0x229C ,0x7BCD ,0x73BD ,0x480C ,0x14DB ,0x68B9 ,0x5C8A ,0x1B61 ,0x6C59 ,0x5707 ,0x9E6 ,0x1FB9,
0x2AD3 ,0x76D4 ,0x3113 ,0x7C7E ,0x11E0 ,0x6C70 };

unsigned int dword_E1E8 = 0x1106;

bool __fastcall sub_62E3(char a1)
{
    return (a1 & 0x7Fu) <= 0x7E && (a1 & 0x7Fu) > 0x20;
}
__int64 sub_62B5()
{
    dword_E1E8 = 1103515245 * dword_E1E8 + 12345;
    return (dword_E1E8 >> 10) & 0x7FFF;
}

int main() {
    unsigned int dword_108E0 = 0;
    int num = 0;
    while (1) {
        char flag[50];
        for (int i = 0; (int)i < 50; ++i) {
            e120[i] ^= sub_62B5();
            if ((unsigned __int8)sub_62E3(e120[i]))
                flag[i] = e120[i] & 0x7F;
            else
                flag[i] = 32;
        }
        if (!strncmp(flag, "CatCTF", 6)) {
            std::cout << "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n";
            puts(flag);
            std::cout << "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n";
            break;
        }
        dword_E1E8 += printf("\x1B[1;37mYou have nyaned for %d times!\x1B[J\x1B[0m", (unsigned int)++dword_108E0);
        std::cout << "\n";
    }
    system("pause");
    return 0;
}

最后应该在一亿次左右获得Flag。这种做法的问题是,由于每一次都调用printf,跑的时间太长了。既然我们知道printf的返回值是字串长度,也可以手动计算。除了\x1B这一整体算作一个字符,%d忽略,其他字符总共41个。然后再计算整数值的长度,用来进行自增,这也是可以的。

int charnum(unsigned int dword_108E0) {
    int i = 0;
    while (dword_108E0) {
        dword_108E0 = dword_108E0 / 10;
        i++;
    }
    return i;
}

dword_E1E8+=41+charnum(++dword_108E0);

这样也是可以的。

跑到一亿多次之后获得结果,用时四十分钟左右。

如果我们手动计算字符串的长度,再来跑Flag的话,几十秒就出结果了


#include<iostream>

unsigned int e120[] = { 0x27FB ,0x27A4 ,0x464E ,0x0E36 ,0x7B70 ,0x5E7A ,0x1A4A ,0x45C1 ,0x2BDF ,0x23BD ,0x3A15 ,0x5B83 ,0x1E15 ,0x5367,
0x50B8 ,0x20CA ,0x41F5 ,0x57D1 ,0x7750 ,0x2ADF ,0x11F8 ,0x9BB ,0x5724 ,0x7374 ,0x3CE6 ,0x646E ,0x10C ,0x6E10 ,0x64F4,
0x3263 ,0x3137 ,0x0B8 ,0x229C ,0x7BCD ,0x73BD ,0x480C ,0x14DB ,0x68B9 ,0x5C8A ,0x1B61 ,0x6C59 ,0x5707 ,0x9E6 ,0x1FB9,
0x2AD3 ,0x76D4 ,0x3113 ,0x7C7E ,0x11E0 ,0x6C70 };

unsigned int dword_E1E8 = 0x1106;

int charnum(int dword_108E0) {
    int i = 0;
    while (dword_108E0) {
        dword_108E0 = dword_108E0 / 10;
        i++;
    }
    return i;
}

bool __fastcall sub_62E3(char a1)
{
    return (a1 & 0x7Fu) <= 0x7E && (a1 & 0x7Fu) > 0x20;
}
__int64 sub_62B5()
{
    dword_E1E8 = 1103515245 * dword_E1E8 + 12345;
    return (dword_E1E8 >> 10) & 0x7FFF;
}

int main() {
    unsigned int dword_108E0 = 0;
    while (1) {
        char flag[50];
        for (int i = 0; (int)i < 50; ++i) {
            e120[i] ^= sub_62B5();
            if ((unsigned __int8)sub_62E3(e120[i]))
                flag[i] = e120[i] & 0x7F;
            else
                flag[i] = 32;
        }
        if (!strncmp(flag, "CatCTF", 6)) {
            std::cout << "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n";
            puts(flag);
            std::cout << "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"<< dword_108E0;
            break;
        }
        dword_108E0 += 1;
        dword_E1E8 += 41;
        dword_E1E8 += charnum(dword_108E0);

    }
    system("pause");
    return 0;
}

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值