实验吧-逆向-分道扬镳

解题链接: [http://ctf5.shiyanbar.com/423/re/rev2.exe](javascript:;)

实验吧-逆向-分道扬镳_第1张图片

1.打开附件随便输入点东西,报错(你要是对了那我没话说)
实验吧-逆向-分道扬镳_第2张图片

2.PEID走一波,Microsoft Visual C++ 5.0
实验吧-逆向-分道扬镳_第3张图片

3.先用IDA打开,找到主代码换成 Grap ViewF5(视图模式) ,反编译下先
实验吧-逆向-分道扬镳_第4张图片

实验吧-逆向-分道扬镳_第5张图片

4.分析反编译后的代码
这是我结合OD分析完成后的



char *sub_401020()
{
  char *result; // eax@19
  char v1; // [sp+Ch] [bp-110h]@1
  char v2; // [sp+4Ch] [bp-D0h]@11
  char *v3; // [sp+50h] [bp-CCh]@1          //动态调试出V3是关键//local.51  " *    ** * ** ** * ** ** * #* ** **** **      *********" 
  char v4; // [sp+54h] [bp-C8h]@1               //local.50  "********* *    ** * ** ** * ** ** * #* ** **** **      *********"
  char v5; // [sp+5Dh] [bp-BFh]@1
  char v6; // [sp+94h] [bp-88h]@1               //local.34  v6 = 0
  char v7; // [sp+98h] [bp-84h]@1               //输入的key
  char v8; // [sp+99h] [bp-83h]@1
  __int16 v9; // [sp+10Dh] [bp-Fh]@1
  char v10; // [sp+10Fh] [bp-Dh]@1
  char v11; // [sp+110h] [bp-Ch]@11
  char v12; // [sp+114h] [bp-8h]@5
  int v13; // [sp+118h] [bp-4h]@4               //local.1  相当于count

  memset(&v1, 0xCCu, 0x110u);
  v7 = 0;
  memset(&v8, 0, 0x74u);
  v9 = 0;
  v10 = 0;
  qmemcpy(&v4, "********* *    ** * ** ** * ** ** * #* ** **** **      *********", 0x41u);
  v3 = &v5;
  printf("Please input your key:\n");
  gets(&v7);                                    //输入的key
  if ( strlen(&v7) != 22 )                      // 输入的数据长度要为22位
  {
    printf("Sorry you are wrong!\n");
    system("pause");
    exit(1);
  }
  v13 = 0;                                      //用来历遍输入的字符串
  do
  {
    v12 = *(&v7 + v13);
    if ( v12 != 0x6B && v12 != 0x6A && v12 != 0x68 && v12 != 0x6C )// 107-k;106-j;104-h;108-l;输入的22个字符必须由这些组成
    {
      printf("Sorry you are wrong!\n");
      system("pause");
      exit(2);
    }
    v11 = *(&v7 + v13);
    v2 = v11;
    
    
    if ( v11 == 104 )                           // 输入的字符为h -1
    {
      if ( --v3 < &v4 || v3 > &v6 || (result = *v3, result == 0x2A) )// 42的ascii值为*
      {
        printf("Sorry you are wrong!\n");
        system("pause");
        exit(3);
      }
      if ( *v3 == 35 )                          // 35的ascii值#
      {
LABEL_41:
        printf("Good!\n");
        system("pause");
        exit(0);
      }
    }
   

   else if ( v2 == 106 )                       // 输入的字符为j +8
    {
      v3 += 8;
      if ( v3 < &v4 || v3 > &v6 || *v3 == 42 )              *
      {
        printf("Sorry you are wrong!\n");
        system("pause");
        exit(3);
      }
      result = *v3;
      if ( result == 35 )
        goto LABEL_41;
    }
   

   else if ( v2 == 107 )      //输入字符为k  -8
    {
      v3 -= 8;
      if ( v3 < &v4 || v3 > &v6 || *v3 == 42 )              *
      {
        printf("Sorry you are wrong!\n");
        system("pause");
        exit(3);
      }
      result = v3;
      if ( *v3 == 35 )
        goto LABEL_41;
    }
  

  else              //输入字符为l    +1
    {
      if ( ++v3 < &v4 || v3 > &v6 || *v3 == 42 ) 
      {
        printf("Sorry you are wrong!\n");
        system("pause");
        exit(4);
      }
      result = v3;
      if ( *v3 == 35 )
        goto LABEL_41;
    }
    ++v13;
  }
  while ( v13 < 25 );
  return result;
}


 

可以看出用户输入的必须是由h,j,k,l四个字母组成的长度为22的字符串,且IDA静态分析是得不出V3的值,必须用OD动态分析。

以前刚接触被动态分析V3难倒,其实只要在inut your key 处下好断点,输入任意22个h,j,k,l,在OD中一步一步观察,因为它是按代码流程来的,当他在判断第一个字符是h,j,k,l中一个,跳转后,必然会有v3的运算,
如你输入的第一个字符串是j,则必有v3 += 8;

实验吧-逆向-分道扬镳_第6张图片

其实就是你的光标起始位为 V3第一个空格,通过左移8位,1位,右移8位,1位,使光标一直停留在空格位,并在第22下停在#处。
运算是:+8,+8,+8,+8,+8,+1,+1,+1,+1,+1,-8,-8,-8,-8,-8,-1,-1,-1,+8,+8,+8,+1

也就是(FLAG):jjjjjlllllkkkkkhhhjjjl

注:还有将"********* * ** * ** ** * ** ** * #* ** **** ** *********"弄成8*8的小迷宫的解题方法,但我就是喜欢犟。

你可能感兴趣的:(实验吧-逆向-分道扬镳)