re学习(29)攻防世界-CatFly(复原反汇编)

因为这是一个.dll文件,在Linux上运行一下:

找到主要函数:(以及由上面三部分对应的代码部分)
 

__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 <= 0x3F && m <= 63 )
          {
            v19 = off_FA20[v24][k][m];
            off_FA88 = (char *)sub_6314((unsigned int)v24, k, (unsigned int)m, 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);
      e8 += 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;
}

 发现关键代码如下:(用‘N’键进行了相关的名称修改)

char *__fastcall sub_6314(__int64 a1, int a2, int a3, __int64 a4)
{
  if ( a2 != 18 )
    return (char *)a4;
  if ( a3 <= 4 || a3 > 54 )                     // 5 6 ...54
                                                // 54-5+1=50
    return (char *)a4;
  byte_104C9 = 32;
  e12[a3 - 5] ^= ee();
  if ( (unsigned __int8)pan1(e12[a3 - 5]) )
    flag = e12[a3 - 5] & 0x7F;
  else
    flag = 32;
  return &flag;
}

然后就是编写脚本求出flag:(可以用记事本的替换功能实现)

进行代码复现:
 

#include<stdio.h>
#include<string.h>
#include<stdbool.h>
unsigned int e8=0x1106;
bool pan1(char a1)
{
  return (a1 & 0x7Fu) <= 0x7E && (a1 & 0x7Fu) > 0x20;
}

int get_num(int num){
	int i=0;
	while(num){
		num=num/10;
		i++;
	}
	return i;
}
unsigned int  ee()
{
  e8 = 1103515245 * e8 + 12345;
  return (e8 >> 10) & 0x7FFF;                   // 向右位移10位后与0x7FFF进行运算
}

unsigned int e12[50]={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};
int main(){
	int num=0; 
	while(1){
		char flag[50];
		
		for(int i=0;i<50;i++){
			e12[i]^=ee();
			if (pan1(e12[i]) )
    			flag[i]=e12[i]&0x7F;
  			else
    			flag[i]=32;
		}
		if(!strncmp(flag,"CatCTF",6)){
			puts(flag);
		}
	    num+=1;
	    e8+=41;
	    e8+=get_num(num);
} }
#CatCTF{Fly1NG_NyAnC4t_Cha5eS_the_FL4G_in_The_Sky}

CatCTF{Fly1NG_NyAnC4t_Cha5eS_the_FL4G_in_The_Sky}

总结:
一. .dll文件

什么是dll文件?

DLL(Dynamic Link Library)文件,即动态链接库,也有人称作应用程序拓展。

DLL是一个包含可由多个程序,同时使用的代码和数据的库。

DLL文件是一种可执行文件,它允许程序共享执行特殊任务所必需的代码和其他资源。Windows提供的DLL文件中包含了允许基于 Windows 的程序在 Windows 环境下操作的许多函数和资源。

二.IDA数组   

    数据提取 数据类型改变(道生一,一生二,二生三.....)

三.C语言编写代码能力的提高,还有那跑了两分钟的代码(第一次见跑这么长时间的,还以为写错了.....)

猜你喜欢

转载自blog.csdn.net/m0_66039322/article/details/132137019