[SWPU2019]ReverseMe.zip

这道题先 放到 IDA 分析

int __thiscall sub_402810(void *this)
{
  int v1; // eax
  int v2; // ecx
  int v3; // eax
  int v4; // esi
  signed int idx; // edi
  unsigned int len_buf1; // kr00_4
  int *v7; // ecx
  int *v8; // ecx
  int *arr_; // ecx
  __int128 *v10; // edx
  unsigned int v11; // edi
  int v12; // eax
  int v13; // eax
  bool flag; // cf
  unsigned __int8 v15; // al
  unsigned __int8 v16; // al
  unsigned __int8 v17; // al
  const char *v18; // edx
  int v19; // eax
  int v20; // eax
  int v22; // [esp-14h] [ebp-D8h]
  int v23; // [esp-10h] [ebp-D4h]
  int *input; // [esp+24h] [ebp-A0h]
  int v25; // [esp+34h] [ebp-90h]
  unsigned int v26; // [esp+38h] [ebp-8Ch]
  __int128 v27; // [esp+3Ch] [ebp-88h]
  __int128 v28; // [esp+4Ch] [ebp-78h]
  int v29; // [esp+5Ch] [ebp-68h]
  __int128 input__; // [esp+60h] [ebp-64h]
  __int128 v31; // [esp+70h] [ebp-54h]
  int v32; // [esp+80h] [ebp-44h]
  __int64 buf1; // [esp+84h] [ebp-40h]
  int v34; // [esp+8Ch] [ebp-38h]
  __int16 v35; // [esp+90h] [ebp-34h]
  int arr[8]; // [esp+94h] [ebp-30h]
  int v37; // [esp+C0h] [ebp-4h]

  v25 = 0;
  v26 = 0xF;
  LOBYTE(input) = 0;
  v37 = 0;
  LOBYTE(v37) = 1;
  v1 = copy(this, "Please input your flag: ");
  print(v1);
  read_input(&dword_430068, &input);
  v34 = 'TC_9';
  buf1 = str1;                                  // SWPU_2019_CTF
  v35 = 'F';
  if ( v25 == 32 )
  {
    arr[4] = 0xBA143D17;
    arr[5] = 0x1D730350;
    arr[6] = 0x9404607A;
    arr[7] = 0x290AF070;
    idx = 0;
    input__ = 0i64;
    v32 = 0;
    v31 = 0i64;
    len_buf1 = strlen(&buf1);
    do
    {
      v7 = &input;
      if ( v26 >= 0x10 )
        v7 = input;
      *(v7 + idx) ^= *(&buf1 + idx % len_buf1); // 异或 "SWPU_2019_CTF"
      ++idx;
    }
    while ( idx < 32 );
    v8 = &input;
    v4 = input;
    if ( v26 >= 0x10 )
      v8 = input;
    v29 = 0;
    v27 = 0i64;
    v28 = 0i64;
    *&input__ = *v8;
    *(&input__ + 1) = *(v8 + 1);
    *&v31 = *(v8 + 2);
    *(&v31 + 1) = *(v8 + 3);                    // 将 flag 异或后的 值 放到 input__ 对应的地址去
    func(v22, v23, 0x100, &input__, &v27);     // input 于一个 数组进行 异或 返回保存在 v27中 再与 arr 数组进行比较
    arr[0] = 0xF80F37B3;
    arr[1] = 0x5DAEBCBC;
    arr_ = arr;
    arr[2] = 0x864D5ABA;
    v10 = &v27;
    arr[3] = 0xD3629744;
    v11 = 28;
    arr[4] = 0x1624BA4F;
    arr[5] = 0x1A729F0B;
    arr[6] = 0x266D6865;
    arr[7] = 0x67C86BBA;
    while ( 1 )
    {
      v12 = *arr_;
      if ( *arr_ != *v10 )                      // v27 = arr
        break;
      ++arr_;
      v10 = (v10 + 4);
      flag = v11 < 4;
      v11 -= 4;
      if ( flag )                               // flag = 1
      {
        v13 = 0;
        goto LABEL_19;
      }
    }
    flag = v12 < *v10;
    if ( v12 != *v10
      || (v15 = *(arr_ + 1), flag = v15 < *(v10 + 1), v15 != *(v10 + 1))
      || (v16 = *(arr_ + 2), flag = v16 < *(v10 + 2), v16 != *(v10 + 2))
      || (v17 = *(arr_ + 3), flag = v17 < *(v10 + 3), v17 != *(v10 + 3)) )
    {
      v13 = -flag | 1;
    }
    else
    {
      v13 = 0;
    }
LABEL_19:
    if ( v13 )
      v18 = "Try again!\\r\\n";
    else
      v18 = "Congratulations! I always knew you could do it.";
    v19 = copy(arr_, v18);
    print(v19);
    system("pause");
  }
  else
  {
    v3 = copy(v2, "Try again!\\r\\n");
    print(v3);
    system("pause");
    v4 = input;
  }
  if ( v26 >= 0x10 )
  {
    v20 = v4;
    if ( v26 + 1 >= 0x1000 )
    {
      v4 = *(v4 - 4);
      if ( (v20 - v4 - 4) > 0x1F )
        sub_40AFF7(v26 + 36);
    }
    sub_4064DE(v4);
  }
  return 0;
}

思路

  1. 发现 我们输入的 长度应该为 32 位。

  2. 第一层加密: 我们的输入 按位 和 字符串 "SWPU_2019_CTF" 进行异或

  3. 然后进入 func 函数。

    1. 进入 func 函数后 发现 最后 我们输入 会与 程序生成的 一个 buf 进行异或 异或 后返回。
    2. buf 的得到 是程序自己 运行时产生的。 可以通过动态调试得到这个buf 的值。

  4. 我们经过 func 处理后 与 数组 进行 比较。

程序的 整体 逻辑是。

input ^ "SWPU_2019_CTF" ^ buf == arr

可以推出

input = arr ^ buf ^ "SWPU_2019_CTF"

我们 动态调试dump buf 和 arr

arr=[0xB3,0x37,0x0F,0xF8,0xBC,0xBC,0xAE,0x5D,
0xBA,0x5A,0x4D,0x86,0x44,0x97,0x62,0xD3,
0x4F,0xBA,0x24,0x16,0x0B,0x9F,0x72,0x1A,
0x65,0x68,0x6D,0x26,0xBA,0x6B,0xC8,0x67
]
str="SWPU_2019_CTF"

buf=[0x86,0x0C,0x3E,0xCA,0x98,0xD7,0xAE,0x19,0xE2,0x77,0x6B,0xA6,0x6A,0xA1,0x77,0xB0,0x69,0x91,0x37,0x05,0x7A,0xF9,0x7B,0x30,0x43,0x5A,0x4B,0x10,0x86,0x7D,0xD4,0x28]

flag = ""
for i in range(len(buf)):
    flag += chr(ord(str[i%len(str)])^buf[i]^arr[i])
print flag

# flag{Y0uaretheB3st!#@_VirtualCC}