2016华山杯CTF toetrix_crackme.exe反编译分析

反编译 源码分析

int __cdecl main(int argc, const char **argv, const char **envp)
{
  char *str; // esi@1
  char sec; // bl@2
  int fst; // eax@2
  int result; // eax@13
  int arg2; // [sp+8h] [bp-30h]@2
  int arg1; // [sp+Ch] [bp-2Ch]@2
  char v9; // [sp+10h] [bp-28h]@1 v9的储存大小为 36h-10h=38
  char v10; // [sp+36h] [bp-2h]@1

  str = &v9;
  printf(aInputYourSn);                         // 输入
  scanf(aS, &v9);
  v10 = 0;
  if ( v9 )
  {
    do
    {
      sec = str[1];                             // 一次处理两位,两位做一次操作,由于空间最大38,所以最多19次操作
      fst = *str - '0';                         // sec 用于switch 
                                                // fst 用于设置arg1和arg2
                                                // 
      str += 2;                                 // str指针地址向右移动两位
                                                // 
      if ( !IsFind(fst, &arg1, &arg2) )         // 判断fst是否在矩阵中,若不在则do while循环,在则顺序执行
        break;
      switch ( sec )                            // 剩下的字符串的第二位
      {                                         // sec决定方向 fst决定移动哪个数
                                                // 直到碰到0以外的数字停止
        case '1':
          left(arg1, arg2);
          break;
        case '2':
          right(arg1, arg2);
          break;
        case '3':
          up(arg1, arg2);
          break;
        default:
          if ( sec != '4' )
            goto LABEL_12;
          down(arg1, arg2);
          break;
      }
    }
    while ( *str );                             // 处理完字符串退出循环
  }
LABEL_12:
  if ( is_no_2() )                              // 矩阵里没有带2的数即成功
  {
    printf(aBDBuzeBuDGoodJ);
    result = 0;
  }
  else
  {
    printf(aIsbuzebuIsjrII);
    result = 0;
  }
  return result;
}

trix矩阵

  1  1  0  1  1  1  0  1  1
  1  0  0  0  0  0  0  0  1
  1  0  0  0  0 12 22  0  1
  1 32  0  0  0 42  0  0  1
  0  0  0  0  0  0  0  0  0
  1  0  0 52  0  0  0  0  1
  0  0  0  0  0  0 62  0  0
  1 72  0  0 82  0  0  0  1
  1  1  0  1  1  1  1  0  1

Is_find()函数

char __cdecl isfind(int fst, int *arg1, int *arg2)
{
  int j; // ecx@3
  int i; // eax@5 函数功能:指定一个数fst,寻找其在trix 9x9矩阵中的位置
         //                找到,返回1,同时此时arg1,arg2为其坐标
         //                未找到,返回0

  *arg1 = 0;
  while ( 2 )
  {
    *arg2 = 0;
    do                                          // arg2++ in [0,8]
    {
      j = *arg2;
      if ( *(&trix[8 * *arg1] + *arg1 + *arg2) == 10 * fst + 2 )// trix[9*arg1 + arg2] == 10*fst + 2 arg1代表行 arg2代表列
        return 1;
      *arg2 = j + 1;
    }
    while ( j + 1 < 9 );
    i = *arg1 + 1;                              // arg1++ in [0,8]
    *arg1 = i;
    if ( i < 9 )
      continue;
    break;
  }
  return 0;
}

letf 函数 (其他的类似)

char *__cdecl left(int arg1, int arg2)
{
  int i; // eax@1 若将trix看成9x9的二维数组,则fst坐标为trix[arg2][arg1]

  for ( i = arg2 - 1; i >= 0; --i )             // arg2--即向左移动一个位置
  {
    if ( *(&trix[9 * arg1] + i) )               // 若左边存在不为0的数,则跳出循环,此时i不为-1
                                                // 不存在则循环执行到i=-1
      break;
  }
  if ( i == -1 )
    *(&trix[8 * arg1] + arg1 + arg2) = 1;       // 即trix[arg2][arg1]变为1
  return mov_trix_i_a1_trix_a2_a1(arg1, arg2, arg1, i + 1);//将trix[arg2][arg1]赋值给trix[i+1][arg1]的位置
}

is_no_2()

char is_no_2()
{
  char *v0; // esi@1
  signed int v1; // ecx@2

  v0 = trix;
  while ( 2 )
  {
    v1 = 0;
    do
    {
      if ( v0[v1] % 10 == 2 )                   // 若有个位是2的数字则返回0
        return 0;
      ++v1;
    }
    while ( v1 < 9 );
    v0 += 9;
    if ( (signed int)v0 < (signed int)&unk_407081 )
      continue;
    break;
  }
  return 1;
}

ans='513431131143414314122354516281847274'

你可能感兴趣的:(反编译与软件逆向)