题目:


丢到PE里, 无壳,64bit

丢到IDA里,shift+F12,查看字符串,找到一个很可疑的字符串

跟进去看看,找到目标函数,我另外搜索了一下,没有mian函数,sub_400F8E应该就是解题的关键函数

有部分变量我修改的名字,为了方便理解

1 __int64 __fastcall sub_400F8E(__int64 a1, int a2, int a3, int a4, int a5, inta6)2 {3   int v6; //edx
4   int v7; //ecx
5   int v8; //r8d
6   int v9; //r9d
7   int v10; //ecx
8   int v11; //r8d
9   int v12; //r9d
10   char v14; //[rsp+0h] [rbp-C0h]
11   char v15; //[rsp+0h] [rbp-C0h]
12   char input[136]; //[rsp+10h] [rbp-B0h] BYREF
13   int v17; //[rsp+98h] [rbp-28h]
14   char v18; //[rsp+9Fh] [rbp-21h]
15   int v19; //[rsp+A0h] [rbp-20h]
16   unsigned __int8 input_1; //[rsp+A6h] [rbp-1Ah]
17   char key; //[rsp+A7h] [rbp-19h]
18   int v22; //[rsp+A8h] [rbp-18h]
19   int v23; //[rsp+ACh] [rbp-14h]
20   int v24; //[rsp+B0h] [rbp-10h]
21   int v25; //[rsp+B4h] [rbp-Ch]
22   _BOOL4 bool_type; //[rsp+B8h] [rbp-8h]
23   int i; //[rsp+BCh] [rbp-4h]
24 
25   sub_407470((unsigned int)"Give me the password:", a2, a3, a4, a5, a6, a2);26   sub_4075A0((unsigned int)"%s", (unsigned int)input, v6, v7, v8, v9, v14);27   for ( i = 0; input[i]; ++i )28 ;29   bool_type = i == 22;                          //下面要打印Congras,那if里面的bool_type必须为130                                                 //i=22
31   v25 = 10;32   do
33 {34     v10 = (int)sub_406D90() % 22;               //v10的范围0~21
35     v22 =v10;36     v24 = 0;37     key =byte_6B4270[v10];38     input_1 =input[v10];39     v19 = v10 + 1;40     v23 = 0;41     while ( v23 <v19 )42 {43       ++v23;44       v24 = 1828812941 * v24 + 12345;45 }46     v18 = v24 ^input_1;47     if ( key != ((unsigned __int8)v24 ^input_1) )48       bool_type = 0;49     --v25;50 }51   while( v25 );52   if( bool_type )53     v17 = sub_407470((unsigned int)"Congras\n", (unsigned int)input, v24, v10, v11, v12, v15);54   else
55     v17 = sub_407470((unsigned int)"Oh no!\n", (unsigned int)input, v24, v10, v11, v12, v15);56   return0LL;57 }
  • sub_407470((unsigned int)"Give me the password: "
    , a2, a3, a4, a5, a6, a2); sub_4075A0((unsigned int)"%s", (unsigned int
    )input, v6, v7, v8, v9, v14);
    我一开始猜测是输出输入用的,预防万一后面查了资料,就是根据C语言函数可变参数的特性反汇编出来的,就是普通输出输入函数
    至于为什么五个变量就第一个我修改了名称————是看后面代码,通过个人理解,推出是输入量。
  • v10 = (int)sub_406D90() % 22;
    可以得知v10的范围是0~21,`sub_406D90`点进去跟踪,我没有得到什么有用的东西,大佬说`v10`是一个随机数,范围也的确是0 ~ 21,但是不是顺序来取值的——就算不知道`v10`的具体数值,但是肯定是0~21中的一个,写逆向脚本的时候遍历也是可以得出的。

  • key = byte_6B4270[v10];
    双击byte_6B4270得到一串东西,应该是关键字符串了,结合上面可以理解为:`v10`是一个随机的下标,根据下标从`byte_6B4270`中随机抽取一个放到`key`里面
  • input_1 = input[v10];
    在输入中随机抽取一个放到`input_1`里面,方便后面的异或操作
  • while ( v23 < v19 )
    {
    ++v23;
    v24 = 1828812941 * v24 + 12345;
    }v18 = v24 ^ input_1
    这就是变换的关键部分了。经过加法乘法异或一系列操作,得到`v18`

  • if ( key != ((unsigned __int8)v24 ^ input_1) )
    这个if的作用就是检查变换后得出的`v18`与`key`是否相等


解题脚本

1 key = [95,242,94,139,78,14,163,170,199,147,129,61,95,116,163,9,145,43,73,40,147,103]2 flag = ""
3 
4 for j in range(22):5     v23 =06     v24 =07     v19 = j + 1
8     while v23 <v19:9         v23 += 1
10         v24 = 1828812941 * v24 + 12345
11     flag += chr((v24 ^ key[j])&0xff)12 
13 print(flag)

flag:
flag{d826e6926098ef46}

标签: none

添加新评论