首页
论坛
专栏
课程

[原创]看雪CTF.TSRC 2018 团队赛 第六题 追凶者也 解题过程

2018-12-11 14:04 268

[原创]看雪CTF.TSRC 2018 团队赛 第六题 追凶者也 解题过程

2018-12-11 14:04
268
1.下断点GetDlgItemTextA ,随手输入注册码,点确定断下:

发现有一处hook,跟进401a10 发现这个是验证函数。


主要函数就红圈中两个。
Check函数:


调试了几次发现是个拼图游戏

这个比win7自带的还简单点,是个3*3的:
初始状态:
4  1  3
7  2  5 
8  6 0
0是空块,最终要还原成:
1 2 3
4 5 6
7 8 0
char __cdecl move_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;
}

move 函数有两个参数:
参数1:操作,主要是wdsa(上下左右)
参数2:本次要操作的数字
3*3 拼图比较难还原的是 3,4,7 这几个,而这个拼图,3在原位,4,7,下移一步就到了:
拼图游戏  0 为空块
操作方法 :[操作(上下左右(wsad))][操作的数字对应的块]
起始:
4 1 3
7 2 5
8 6 0

操作  d 6   -->数字6 对应的块右移 
4 1 3
7 2 5
8 0 6

操作  d 8  -->数字8 对应的块右移
4 1 3
7 2 5
0 8 6

操作  s 7  -->数字7 对应的块下移
4 1 3
0 2 5
7 8 6


操作  s 4  -->数字4 对应的块下移
0 1 3
4 2 5
7 8 6

操作 a 1   -->数字1 对应的块左移
1 0 3
4 2 5
7 8 6

操作 w 2   -->数字2 对应的块上移
1 2 3
4 0 5
7 8 6

操作 a 5   -->数字5 对应的块左移
1 2 3
4 5 0
7 8 6

操作 w 6   -->数字6 对应的块上移
1 2 3
4 5 6
7 8 0


将以上步骤组合起来为:d6d8s7s4a1w2a5w6  验证成功。

拼图游戏,每一步都有两个数字可以移动,作者加了一个验证函数:
int __stdcall hash_4017B0(int a1, int a2)
{
  int i; // [esp+0h] [ebp-8h]
  int v4; // [esp+4h] [ebp-4h]

  v4 = a2;
  for ( i = 0; i < a2; ++i )
    v4 = *(char *)(i + a1) ^ (v4 >> 28) ^ 16 * v4;
  return v4;
}
这个是为了防治多解的吧。



[推荐]看雪企服平台,提供安全分析、定制项目开发、APP等级保护、渗透测试等安全服务!

上一主题 下一主题
最新回复 (0)
游客
登录 | 注册 方可回帖
返回