首页
社区
课程
招聘
[原创]KCTF2020秋季赛 第七题 鱼目混珠
发表于: 2020-12-5 00:36 5674

[原创]KCTF2020秋季赛 第七题 鱼目混珠

2020-12-5 00:36
5674

程序有很多花指令,不过都有特征,写个OD脚本去掉就行。
去掉以后dump下来丢给IDA F5,配合下动态调试分析

逻辑很清晰,除了最后那个溢出覆盖len比较坑了点
解开方程,再把结果按hexdecode的方法转回字符串就可以了

按hexdecode的方法转回字符串得到flag
10C7F30833B9C4563BF035C32D8C7709E040FCA64E211F34CD3FE773

int __cdecl main(int argc, const char **argv, const char **envp)
{
  char *v3; // edx
  int v4; // ecx
  unsigned int v5; // eax
  char *v6; // edx
  int v7; // ecx
  unsigned int v8; // eax
  char *v9; // kr00_4
  int v10; // esi
  int v11; // ecx
  int v12; // edi
  int v13; // ebx
  int v14; // esi
  int v16; // edx
  unsigned int v17; // eax
  int v18; // edx
  unsigned int v19; // eax
  int v20; // edx
  unsigned int v21; // eax
  unsigned int v22; // eax
  int v23; // [esp+1Ch] [ebp-A0h]
  unsigned int v24; // [esp+20h] [ebp-9Ch]
  int v25; // [esp+24h] [ebp-98h]
  int v26; // [esp+28h] [ebp-94h]
  char v27; // [esp+2Ch] [ebp-90h]
  _DWORD antidebug[9]; // [esp+3Ch] [ebp-80h]
  int (*v29)(void); // [esp+60h] [ebp-5Ch]
  int (*v30)(void); // [esp+64h] [ebp-58h]
  _DWORD v31[2]; // [esp+68h] [ebp-54h] BYREF
  char v32[76]; // [esp+70h] [ebp-4Ch] BYREF
 
  sub_40CA20();
  antidebug[0] = sub_401700;                    // 一大堆反调试
  antidebug[1] = sub_401740;
  antidebug[2] = sub_4017B0;
  antidebug[3] = sub_401890;
  antidebug[4] = sub_4018F0;
  antidebug[5] = sub_401570;
  dword_4C5028 = 0;
  antidebug[6] = sub_401820;
  antidebug[7] = sub_401950;
  antidebug[8] = sub_401AB0;
  v29 = sub_402F20;
  v30 = sub_402F90;
  dword_4C5024 = 0;
  v31[0] = sub_401620;
  v3 = a104010010e4b4c;
  do
  {
    v4 = *(_DWORD *)v3;
    v3 += 4;
    v5 = ~v4 & (v4 - 16843009) & 0x80808080;
  }
  while ( !v5 );
  if ( (~v4 & (v4 - 16843009) & 0x8080) == 0 )
    v5 >>= 16;
  if ( (~v4 & (v4 - 16843009) & 0x8080) == 0 )
    v3 += 2;
  hexdecode((int *)&result, (int)a104010010e4b4c, (int)&v3[-__CFADD__((_BYTE)v5, (_BYTE)v5) - 0x4B9083]);// 解码两个大数 每字节的高位和低位互换
  v6 = a1e9705f8d92146;
  do
  {
    v7 = *(_DWORD *)v6;
    v6 += 4;
    v8 = ~v7 & (v7 - 16843009) & 0x80808080;
  }
  while ( !v8 );
  if ( (~v7 & (v7 - 16843009) & 0x8080) == 0 )
    v8 >>= 16;
  if ( (~v7 & (v7 - 16843009) & 0x8080) == 0 )
    v6 += 2;
  hexdecode((int *)&big_c2, (int)a1e9705f8d92146, (int)&v6[-__CFADD__((_BYTE)v8, (_BYTE)v8) - 4952147]);
  v23 = *(_DWORD *)&result.buf[8];
  v24 = *(_DWORD *)&result.buf[4];
  print(*(_DWORD *)&result.buf[12]);
  memset(v32, 0, 0x40u);
  scan((int)&dword_4BA660, v32);
  v9 = &v32[strlen(v32)];
  if ( (unsigned int)(v9 - v32 - 13) > 0x32 )
    goto LABEL_22;
  v10 = sub_4030E0(v32, 7);
  v12 = sub_4030E0((_BYTE *)v31 + v9 - v32 + 1, 7);
  v13 = 0;
  v26 = 0;
  v25 = 0;
  do
  {
    v27 = 15 - v13;
    if ( (v13 & 1) == ((int (__fastcall *)(int))antidebug[v13])(v11) )// 执行反调试
    {
      ++v25;
      v10 = v29() ^ __ROR4__(v10, v13);         // 两个crc防patch
      v12 = v30() ^ __ROR4__(v12, v27);
    }
    else
    {
      ++v26;
      v10 = v30() ^ __ROR4__(v10, v27);
      v12 = ((int (__fastcall *)(int))v29)(v13) ^ __ROR4__(v12, v13);
    }
    ++v13;
  }
  while ( v13 != 9 );
  if ( !v25 )
    goto LABEL_22;
  if ( !v26 )
    goto LABEL_22;
  v14 = dword_4B904C ^ v10;
  if ( v14 != v23 || (v12 ^ dword_4B9048) != v24 || hexdecode((int *)&input, (int)v32, strlen(v32)) < 0 )// 比较crc是否与预设值一样 动态调试时patch掉
    goto LABEL_22;
  big_r.buf[4] = 0;
  *(_DWORD *)big_r.buf = *(_DWORD *)result.buf;
  v16 = 4;
  while ( 1 )
  {
    v17 = v16 - 1;
    if ( big_r.buf[v16 - 1] )
      break;
    --v16;
    if ( !v17 )
      goto LABEL_29;
  }
  v17 = v16;
LABEL_29:
  big_r.len = v17;
  big_mul(&big_n, &input, &big_r);
  input.buf[4] = 0;
  *(_DWORD *)input.buf = 0xE053D0F;
  v18 = 4;
  while ( 1 )
  {
    v19 = v18 - 1;
    if ( input.buf[v18 - 1] )
      break;
    --v18;
    if ( !v19 )
      goto LABEL_32;
  }
  v19 = v18;
  input.len = v19;
  big_div(&big_n, &big_n, &input);              // *0xE053D0F
  big_add(&big_n, &big_n, &result);
  big_add(&big_n, &big_n, &big_c2);             // +0xfea1bd9e6964129d8f5079e1
  big_mul(&big_c, &result, &big_c2);
  big_sub(&big_r, &big_n, &big_c);              // -0x3f58d70f55459ad75491a4c3ea858c4961226c27f5a1f8a95b18fde1
  if ( (int)big_r.len > 16 )
    goto LABEL_22;
LABEL_32:
  big_mul(&big_n, &big_n, &input);              // *0xE053D0F
  input.buf[4] = 0;
  *(_DWORD *)input.buf = 37;
  v20 = 4;
  while ( 1 )
  {
    v21 = v20 - 1;
    if ( input.buf[v20 - 1] )
      break;
    --v20;
    if ( !v21 )
      goto LABEL_36;
  }
  v21 = v20;
LABEL_36:
  input.len = v21;
  big_mul(&big_c, &big_n, &input);              // *37
  big_add(&big_c, &big_c, &big_c);              // 此处溢出,最高位为1,刚好覆盖了result的长度
  v22 = big_r.len;
  if ( big_r.len == result.len )
  {
    while ( (--v22 & 0x80000000) == 0 )
    {
      if ( big_r.buf[v22] != result.buf[v22] )  // 表面上跟0x3faffa2b01b6ba9744c4b4e010010401比较 实际上是1
        goto LABEL_22;
    }
    print(v14);                                 // GOOD
  }
  else
  {
LABEL_22:
    print(v24);                                 // ERROR
  }
  return 0;
}
int __cdecl main(int argc, const char **argv, const char **envp)
{
  char *v3; // edx
  int v4; // ecx
  unsigned int v5; // eax
  char *v6; // edx
  int v7; // ecx
  unsigned int v8; // eax
  char *v9; // kr00_4
  int v10; // esi
  int v11; // ecx
  int v12; // edi
  int v13; // ebx
  int v14; // esi
  int v16; // edx
  unsigned int v17; // eax
  int v18; // edx
  unsigned int v19; // eax
  int v20; // edx
  unsigned int v21; // eax
  unsigned int v22; // eax
  int v23; // [esp+1Ch] [ebp-A0h]
  unsigned int v24; // [esp+20h] [ebp-9Ch]
  int v25; // [esp+24h] [ebp-98h]
  int v26; // [esp+28h] [ebp-94h]
  char v27; // [esp+2Ch] [ebp-90h]
  _DWORD antidebug[9]; // [esp+3Ch] [ebp-80h]
  int (*v29)(void); // [esp+60h] [ebp-5Ch]
  int (*v30)(void); // [esp+64h] [ebp-58h]
  _DWORD v31[2]; // [esp+68h] [ebp-54h] BYREF
  char v32[76]; // [esp+70h] [ebp-4Ch] BYREF
 
  sub_40CA20();
  antidebug[0] = sub_401700;                    // 一大堆反调试
  antidebug[1] = sub_401740;
  antidebug[2] = sub_4017B0;
  antidebug[3] = sub_401890;
  antidebug[4] = sub_4018F0;
  antidebug[5] = sub_401570;
  dword_4C5028 = 0;
  antidebug[6] = sub_401820;
  antidebug[7] = sub_401950;
  antidebug[8] = sub_401AB0;
  v29 = sub_402F20;
  v30 = sub_402F90;
  dword_4C5024 = 0;
  v31[0] = sub_401620;
  v3 = a104010010e4b4c;
  do
  {
    v4 = *(_DWORD *)v3;
    v3 += 4;
    v5 = ~v4 & (v4 - 16843009) & 0x80808080;
  }
  while ( !v5 );
  if ( (~v4 & (v4 - 16843009) & 0x8080) == 0 )
    v5 >>= 16;
  if ( (~v4 & (v4 - 16843009) & 0x8080) == 0 )
    v3 += 2;
  hexdecode((int *)&result, (int)a104010010e4b4c, (int)&v3[-__CFADD__((_BYTE)v5, (_BYTE)v5) - 0x4B9083]);// 解码两个大数 每字节的高位和低位互换
  v6 = a1e9705f8d92146;
  do
  {
    v7 = *(_DWORD *)v6;
    v6 += 4;
    v8 = ~v7 & (v7 - 16843009) & 0x80808080;
  }
  while ( !v8 );
  if ( (~v7 & (v7 - 16843009) & 0x8080) == 0 )
    v8 >>= 16;
  if ( (~v7 & (v7 - 16843009) & 0x8080) == 0 )
    v6 += 2;
  hexdecode((int *)&big_c2, (int)a1e9705f8d92146, (int)&v6[-__CFADD__((_BYTE)v8, (_BYTE)v8) - 4952147]);
  v23 = *(_DWORD *)&result.buf[8];
  v24 = *(_DWORD *)&result.buf[4];
  print(*(_DWORD *)&result.buf[12]);
  memset(v32, 0, 0x40u);
  scan((int)&dword_4BA660, v32);
  v9 = &v32[strlen(v32)];
  if ( (unsigned int)(v9 - v32 - 13) > 0x32 )
    goto LABEL_22;
  v10 = sub_4030E0(v32, 7);
  v12 = sub_4030E0((_BYTE *)v31 + v9 - v32 + 1, 7);
  v13 = 0;
  v26 = 0;
  v25 = 0;
  do
  {
    v27 = 15 - v13;
    if ( (v13 & 1) == ((int (__fastcall *)(int))antidebug[v13])(v11) )// 执行反调试
    {
      ++v25;
      v10 = v29() ^ __ROR4__(v10, v13);         // 两个crc防patch

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 2
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//