首页
社区
课程
招聘
[原创]第六题 追凶者也
发表于: 2018-12-11 18:27 2914

[原创]第六题 追凶者也

2018-12-11 18:27
2914

s7:与前三位的7置换

首先找到注册码判断点
  strcpy(Text, "try again!");
  strcpy(Caption, "fail");
  String = 0;
  v6 = 0;
  v7 = 0;
  v8 = 0;
  v9 = 0;
  v10 = 0;
  v11 = 0;
  GetDlgItemTextA(hDlg, 1001, &String, 20);
  v4 = 0;
  for ( i = 0; i < 20; ++i )
    v4 += *(&String + i);
  if ( v4 > 0 && v4 < 4132 )
  {
    v1 = malloc(v4);
    sub_401020();
    j___free_base(v1);
  }
  return MessageBoxA(0, Text, Caption, 0);
但奇怪的是几乎什么都没做就直接弹出失败信息
  strcpy(Text, "try again!");
  strcpy(Caption, "fail");
  String = 0;
  v6 = 0;
  v7 = 0;
  v8 = 0;
  v9 = 0;
  v10 = 0;
  v11 = 0;
  GetDlgItemTextA(hDlg, 1001, &String, 20);
  v4 = 0;
  for ( i = 0; i < 20; ++i )
    v4 += *(&String + i);
  if ( v4 > 0 && v4 < 4132 )
  {
    v1 = malloc(v4);
    sub_401020();
    j___free_base(v1);
  }
  return MessageBoxA(0, Text, Caption, 0);
但奇怪的是几乎什么都没做就直接弹出失败信息
仔细分析发现原来在GetDlgItemTextA内有一处HOOK,在GetWindowTextA后直接跳转到了别的地方对注册码进行判断(程序启动时创建了一个线程对这里进行HOOK)
74F56B36 >  8BFF            MOV EDI,EDI
74F56B38    55              PUSH EBP
74F56B39    8BEC            MOV EBP,ESP
74F56B3B    FF75 0C         PUSH DWORD PTR SS:[EBP+C]
74F56B3E    FF75 08         PUSH DWORD PTR SS:[EBP+8]
74F56B41    E8 7486FCFF     CALL GetDlgItem
74F56B46    85C0            TEST EAX,EAX
74F56B48    74 0E           JE SHORT 74F56B58
74F56B4A    FF75 14         PUSH DWORD PTR SS:[EBP+14]
74F56B4D    FF75 10         PUSH DWORD PTR SS:[EBP+10]
74F56B50    50              PUSH EAX
74F56B51    E8 D394FAFF     CALL GetWindowTextA
74F56B56  - E9 B5AEBA8B     JMP 穿甲葡萄.00B01A10
74F56B5B    007406 8B       ADD BYTE PTR DS:[ESI+EAX-75],DH
74F56B5F    45              INC EBP
74F56B60    10C6            ADC DH,AL
74F56B62    0000            ADD BYTE PTR DS:[EAX],AL
74F56B64    33C0            XOR EAX,EAX
74F56B66    5D              POP EBP
74F56B67    C2 1000         RETN 10
之后走到核心判断位置
bool __cdecl sub_401290(int a1, int a2)
{
  byte_4147D0[0] = 4;
  byte_4147D0[1] = 1;
  byte_4147D0[2] = 3;
  byte_4147D0[3] = 7;
  byte_4147D0[4] = 2;
  byte_4147D0[5] = 5;
  byte_4147D0[6] = 8;
  byte_4147D0[7] = 6;
  byte_4147D0[8] = 0;
  return sub_4015B0(a1, a2);
}
可以看到首先初始化了一个序列
04 01 03 07 02 05 08 06 00
然后经过一系列操作
bool __cdecl sub_4015B0(int a1, int a2)
{
  int i; // [esp+0h] [ebp-Ch]
  int v4; // [esp+8h] [ebp-4h]

  v4 = -858993460;
  if ( a2 % 2 )
    return 0;
  for ( i = 0; i < a2; i += 2 )
  {
    if ( *(_BYTE *)(i + a1) == 119 )
      v4 = 0;
    if ( *(_BYTE *)(i + a1) == 100 )
      v4 = 1;
    if ( *(_BYTE *)(i + a1) == 115 )
      v4 = 2;
    if ( *(_BYTE *)(i + a1) == 97 )
      v4 = 3;
    if ( !sub_401380(v4, *(char *)(i + a1 + 1) - 48) )
      return 0;
  }
  return byte_4147D0[0] == 1
      && byte_4147D0[1] == 2
      && byte_4147D0[2] == 3
      && byte_4147D0[3] == 4
      && byte_4147D0[4] == 5
      && byte_4147D0[5] == 6
      && byte_4147D0[6] == 7
      && byte_4147D0[7] == 8
      && !byte_4147D0[8];
}
使得序列变为
01 02 03 04 05 06 07 08 00
char __cdecl sub_401380(int a1, int a2)
{
  char result; // al
  signed int i; // [esp+8h] [ebp-8h]
  signed int v4; // [esp+Ch] [ebp-4h]

  if ( !a2 )
    return 0;
  v4 = 0;
LABEL_4:
  if ( v4 >= 3 )
    return 0;
  for ( i = 0; ; ++i )
  {
    if ( i >= 3 )
    {
      ++v4;
      goto LABEL_4;
    }
    if ( byte_4147D0[3 * v4 + i] == a2 )
      break;
LABEL_6:
    ;
  }
  switch ( a1 )
  {
    case 0:
      if ( v4 )
      {
        if ( byte_4147D0[3 * (v4 - 1) + i] )
        {
          result = 0;
        }
        else
        {
          byte_4147D0[3 * (v4 - 1) + i] = byte_4147D0[3 * v4 + i];
          byte_4147D0[3 * v4 + i] = 0;
          result = 1;
        }
      }
      else
      {
        result = 0;
      }
      break;
    case 1:
      if ( i == 2 )
      {
        result = 0;
      }
      else if ( byte_4147D1[3 * v4 + i] )
      {
        result = 0;
      }
      else
      {
        byte_4147D1[3 * v4 + i] = byte_4147D0[3 * v4 + i];
        byte_4147D0[3 * v4 + i] = 0;
        result = 1;
      }
      break;
    case 2:
      if ( v4 == 2 )
      {
        result = 0;
      }
      else if ( byte_4147D0[3 * (v4 + 1) + i] )
      {
        result = 0;
      }
      else
      {
        byte_4147D0[3 * (v4 + 1) + i] = byte_4147D0[3 * v4 + i];
        byte_4147D0[3 * v4 + i] = 0;
        result = 1;
      }
      break;
    case 3:
      if ( i )
      {
        if ( byte_4147CF[3 * v4 + i] )
        {
          result = 0;
        }
        else
        {
          byte_4147CF[3 * v4 + i] = byte_4147D0[3 * v4 + i];
          byte_4147D0[3 * v4 + i] = 0;
          result = 1;
        }
      }
      else
      {
        result = 0;
      }
      break;
    default:
      goto LABEL_6;
  }
  return result;
}
对上面的函数进行详细分析发现是用末尾的00对序列进行一系列的置换
注册码每两位分为一个单位,首位为操作码(w:与后三位的数置换  d:前一位的数置换  s:前三位的数置换  a:后一位的数置换),第二位是操作数
观察置换前后的序列不难发现其中的置换操作:
bool __cdecl sub_401290(int a1, int a2)
{
  byte_4147D0[0] = 4;
  byte_4147D0[1] = 1;
  byte_4147D0[2] = 3;
  byte_4147D0[3] = 7;
  byte_4147D0[4] = 2;
  byte_4147D0[5] = 5;
  byte_4147D0[6] = 8;
  byte_4147D0[7] = 6;
  byte_4147D0[8] = 0;
  return sub_4015B0(a1, a2);
}
可以看到首先初始化了一个序列
bool __cdecl sub_401290(int a1, int a2)
{
  byte_4147D0[0] = 4;
  byte_4147D0[1] = 1;
  byte_4147D0[2] = 3;
  byte_4147D0[3] = 7;
  byte_4147D0[4] = 2;
  byte_4147D0[5] = 5;
  byte_4147D0[6] = 8;
  byte_4147D0[7] = 6;
  byte_4147D0[8] = 0;
  return sub_4015B0(a1, a2);
}
可以看到首先初始化了一个序列
bool __cdecl sub_401290(int a1, int a2)
{
  byte_4147D0[0] = 4;
  byte_4147D0[1] = 1;
  byte_4147D0[2] = 3;
  byte_4147D0[3] = 7;
  byte_4147D0[4] = 2;
  byte_4147D0[5] = 5;
  byte_4147D0[6] = 8;
  byte_4147D0[7] = 6;
  byte_4147D0[8] = 0;
  return sub_4015B0(a1, a2);
}
可以看到首先初始化了一个序列
04 01 03 07 02 05 08 06 00
然后经过一系列操作
04 01 03 07 02 05 08 06 00
然后经过一系列操作
bool __cdecl sub_4015B0(int a1, int a2)
{
  int i; // [esp+0h] [ebp-Ch]
  int v4; // [esp+8h] [ebp-4h]

  v4 = -858993460;
  if ( a2 % 2 )
    return 0;
  for ( i = 0; i < a2; i += 2 )
  {
    if ( *(_BYTE *)(i + a1) == 119 )
      v4 = 0;
    if ( *(_BYTE *)(i + a1) == 100 )
      v4 = 1;
    if ( *(_BYTE *)(i + a1) == 115 )
      v4 = 2;
    if ( *(_BYTE *)(i + a1) == 97 )
      v4 = 3;
    if ( !sub_401380(v4, *(char *)(i + a1 + 1) - 48) )
      return 0;
  }
  return byte_4147D0[0] == 1
      && byte_4147D0[1] == 2
      && byte_4147D0[2] == 3
      && byte_4147D0[3] == 4
      && byte_4147D0[4] == 5
      && byte_4147D0[5] == 6
      && byte_4147D0[6] == 7
      && byte_4147D0[7] == 8
      && !byte_4147D0[8];
}
使得序列变为
bool __cdecl sub_4015B0(int a1, int a2)
{
  int i; // [esp+0h] [ebp-Ch]
  int v4; // [esp+8h] [ebp-4h]

  v4 = -858993460;
  if ( a2 % 2 )
    return 0;
  for ( i = 0; i < a2; i += 2 )
  {
    if ( *(_BYTE *)(i + a1) == 119 )
      v4 = 0;
    if ( *(_BYTE *)(i + a1) == 100 )
      v4 = 1;
    if ( *(_BYTE *)(i + a1) == 115 )
      v4 = 2;
    if ( *(_BYTE *)(i + a1) == 97 )
      v4 = 3;
    if ( !sub_401380(v4, *(char *)(i + a1 + 1) - 48) )
      return 0;
  }
  return byte_4147D0[0] == 1
      && byte_4147D0[1] == 2
      && byte_4147D0[2] == 3
      && byte_4147D0[3] == 4
      && byte_4147D0[4] == 5
      && byte_4147D0[5] == 6
      && byte_4147D0[6] == 7
      && byte_4147D0[7] == 8
      && !byte_4147D0[8];
}
使得序列变为
01 02 03 04 05 06 07 08 00
char __cdecl sub_401380(int a1, int a2)
{
  char result; // al
  signed int i; // [esp+8h] [ebp-8h]
  signed int v4; // [esp+Ch] [ebp-4h]

  if ( !a2 )
    return 0;
  v4 = 0;
LABEL_4:
  if ( v4 >= 3 )
    return 0;
  for ( i = 0; ; ++i )
  {
    if ( i >= 3 )
    {
      ++v4;
      goto LABEL_4;
    }
    if ( byte_4147D0[3 * v4 + i] == a2 )
      break;
LABEL_6:
    ;
  }
  switch ( a1 )
  {
    case 0:
      if ( v4 )
      {
        if ( byte_4147D0[3 * (v4 - 1) + i] )
        {
          result = 0;
        }
        else
        {
          byte_4147D0[3 * (v4 - 1) + i] = byte_4147D0[3 * v4 + i];
          byte_4147D0[3 * v4 + i] = 0;
          result = 1;
        }
      }
      else
      {
        result = 0;
      }
      break;
    case 1:
      if ( i == 2 )
      {
        result = 0;
      }
      else if ( byte_4147D1[3 * v4 + i] )
      {
        result = 0;
      }
      else
      {
        byte_4147D1[3 * v4 + i] = byte_4147D0[3 * v4 + i];
        byte_4147D0[3 * v4 + i] = 0;
        result = 1;
      }
      break;
    case 2:
      if ( v4 == 2 )
      {
        result = 0;
      }
      else if ( byte_4147D0[3 * (v4 + 1) + i] )
      {
        result = 0;
      }
      else
      {
        byte_4147D0[3 * (v4 + 1) + i] = byte_4147D0[3 * v4 + i];
        byte_4147D0[3 * v4 + i] = 0;
        result = 1;
      }
      break;
    case 3:
      if ( i )
      {
        if ( byte_4147CF[3 * v4 + i] )
        {
          result = 0;
        }
        else
        {
          byte_4147CF[3 * v4 + i] = byte_4147D0[3 * v4 + i];
          byte_4147D0[3 * v4 + i] = 0;
          result = 1;
        }
      }
      else
      {
        result = 0;
      }
      break;
    default:
      goto LABEL_6;
  }
  return result;
}
对上面的函数进行详细分析发现是用末尾的00对序列进行一系列的置换
注册码每两位分为一个单位,首位为操作码(w:与后三位的数置换  d:前一位的数置换  s:前三位的数置换  a:后一位的数置换),第二位是操作数
01 02 03 04 05 06 07 08 00
char __cdecl sub_401380(int a1, int a2)
{
  char result; // al
  signed int i; // [esp+8h] [ebp-8h]
  signed int v4; // [esp+Ch] [ebp-4h]

  if ( !a2 )
    return 0;
  v4 = 0;
LABEL_4:
  if ( v4 >= 3 )
    return 0;
  for ( i = 0; ; ++i )
  {
    if ( i >= 3 )
    {
      ++v4;
      goto LABEL_4;
    }
    if ( byte_4147D0[3 * v4 + i] == a2 )
      break;
LABEL_6:
    ;
  }
  switch ( a1 )
  {
    case 0:
      if ( v4 )
      {
        if ( byte_4147D0[3 * (v4 - 1) + i] )
        {
          result = 0;
        }
        else
        {
          byte_4147D0[3 * (v4 - 1) + i] = byte_4147D0[3 * v4 + i];
          byte_4147D0[3 * v4 + i] = 0;
          result = 1;
        }
      }
      else
      {
        result = 0;
      }
      break;
    case 1:
      if ( i == 2 )
      {
        result = 0;
      }
      else if ( byte_4147D1[3 * v4 + i] )
      {
        result = 0;
      }
      else
      {
        byte_4147D1[3 * v4 + i] = byte_4147D0[3 * v4 + i];
        byte_4147D0[3 * v4 + i] = 0;
        result = 1;
      }
      break;
    case 2:
      if ( v4 == 2 )
      {
        result = 0;
      }
      else if ( byte_4147D0[3 * (v4 + 1) + i] )
      {
        result = 0;
      }
      else
      {
        byte_4147D0[3 * (v4 + 1) + i] = byte_4147D0[3 * v4 + i];
        byte_4147D0[3 * v4 + i] = 0;
        result = 1;
      }
      break;
    case 3:
      if ( i )
      {
        if ( byte_4147CF[3 * v4 + i] )
        {
          result = 0;
        }
        else
        {
          byte_4147CF[3 * v4 + i] = byte_4147D0[3 * v4 + i];
          byte_4147D0[3 * v4 + i] = 0;
          result = 1;
        }
      }
      else
      {
        result = 0;
      }
      break;
    default:
      goto LABEL_6;
  }
  return result;
}
对上面的函数进行详细分析发现是用末尾的00对序列进行一系列的置换
注册码每两位分为一个单位,首位为操作码(w:与后三位的数置换  d:前一位的数置换  s:前三位的数置换  a:后一位的数置换),第二位是操作数
char __cdecl sub_401380(int a1, int a2)
{
  char result; // al
  signed int i; // [esp+8h] [ebp-8h]
  signed int v4; // [esp+Ch] [ebp-4h]

  if ( !a2 )
    return 0;
  v4 = 0;
LABEL_4:
  if ( v4 >= 3 )
    return 0;
  for ( i = 0; ; ++i )
  {
    if ( i >= 3 )
    {
      ++v4;
      goto LABEL_4;
    }
    if ( byte_4147D0[3 * v4 + i] == a2 )
      break;
LABEL_6:
    ;
  }
  switch ( a1 )
  {
    case 0:
      if ( v4 )
      {
        if ( byte_4147D0[3 * (v4 - 1) + i] )
        {
          result = 0;
        }
        else
        {
          byte_4147D0[3 * (v4 - 1) + i] = byte_4147D0[3 * v4 + i];
          byte_4147D0[3 * v4 + i] = 0;
          result = 1;
        }
      }
      else
      {
        result = 0;
      }
      break;
    case 1:
      if ( i == 2 )
      {
        result = 0;
      }
      else if ( byte_4147D1[3 * v4 + i] )
      {
        result = 0;
      }
      else
      {
        byte_4147D1[3 * v4 + i] = byte_4147D0[3 * v4 + i];
        byte_4147D0[3 * v4 + i] = 0;
        result = 1;
      }
      break;
    case 2:
      if ( v4 == 2 )
      {
        result = 0;
      }
      else if ( byte_4147D0[3 * (v4 + 1) + i] )
      {
        result = 0;
      }
      else
      {
        byte_4147D0[3 * (v4 + 1) + i] = byte_4147D0[3 * v4 + i];
        byte_4147D0[3 * v4 + i] = 0;
        result = 1;
      }
      break;
    case 3:
      if ( i )
      {
        if ( byte_4147CF[3 * v4 + i] )
        {
          result = 0;
        }
        else
        {
          byte_4147CF[3 * v4 + i] = byte_4147D0[3 * v4 + i];
          byte_4147D0[3 * v4 + i] = 0;
          result = 1;
        }
      }
      else
      {
        result = 0;
      }
      break;
    default:
      goto LABEL_6;
  }
  return result;
}
对上面的函数进行详细分析发现是用末尾的00对序列进行一系列的置换
注册码每两位分为一个单位,首位为操作码(w:与后三位的数置换  d:前一位的数置换  s:前三位的数置换  a:后一位的数置换),第二位是操作数
观察置换前后的序列不难发现其中的置换操作:
d6:与前一位的6置换
04 01 03 07 02 05 08 00 06
d8:与前一位的8置换
04 01 03 07 02 05 00 08 06

s7:与前三位的7置换

04 01 03 00 02 05 07 08 06
s4:与前三位的4置换
00 01 03 04 02 05 07 08 06
a1:与后一位的1置换
01 00 03 04 02 05 07 08 06
w2:与后三位的2置换
01 02 03 04 00 05 07 08 06
a5:与后一位的5置换
01 02 03 04 05 00 07 08 06
w6:与后三位的6置换
01 02 03 04 05 06 07 08 00
连起来得到注册码:d6d8s7s4a1w2a5w6
04 01 03 07 02 05 08 00 06
d8:与前一位的8置换
04 01 03 07 02 05 00 08 06

s7:与前三位的7置换

04 01 03 00 02 05 07 08 06
s4:与前三位的4置换
00 01 03 04 02 05 07 08 06
a1:与后一位的1置换
01 00 03 04 02 05 07 08 06
w2:与后三位的2置换
01 02 03 04 00 05 07 08 06
a5:与后一位的5置换
01 02 03 04 05 00 07 08 06
w6:与后三位的6置换
01 02 03 04 05 06 07 08 00
连起来得到注册码:d6d8s7s4a1w2a5w6

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

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