[ACTF新生赛2020]easyre
得到一个 exe 程序,先查壳
发现是 UPX 壳,直接脱壳
upx -d easyre.exe
这里将 if 判断里面的数字转换成字符后,发现是 if ( v6[0] != 'A' || v6[1] != 'C' || v6[2] != 'T' || v6[3] != 'F' || v6[4] != '{' || v10 != '}' )
,因此推测 v7、v8、v9 里面是需要的 flag 值
程序逻辑如下:
(1)将变量 v4 赋值为 *F'\"N,\"(I?+@
(2)用户输入 v6
(3)经过 if 判断,都不满足时候继续执行
(4)对 v5 进行赋值
(5)for 循环中进行 if 判断,只有全部满足,才能继续执行
(6)输出 “You are correct!”
在(5)中的 if 判断里面,注意到 _data_start__[*((char *)v5 + i) - 1]
这一句
这里需要注意到,原来的 v5 数组是 DWORD 数据类型,对其进行赋值的 v7、v8、v9 是 int 数据类型,而这里用
(char *)v5
的操作后,就把地址强转指针为 char 类型指针,因为一个 int 类型数据或者 DWORD 数据类型的空间可以存储 4 个 char 类型数据,因此这里的 v5 数组,即 v7、v8、v9,实际上存放了12个 char 类型的变量。
查看数组 _data_start__
的值为 ~}|{zyxwvutsrqponmlkjihgfedcba`_^]\[ZYXWVUTSRQPONMLKJIHGFEDCBA@?>=<;:9876543210/.-,+*)(
,27h,&%$# !"
。
_data_start__[*((char *)v5 + i) - 1]
是将地址强转指针为 char 类型指针,然后 + i,再取出对应位置的 char 类型变量,然后将对应的字符的值 - 1,最后得到的值,取数组 data_start_ 对应下标的字符
若要求得 v5 的值,只需要知道 data_start_ 数组在第 i 位对应的下标然后 +1 即可,相应的下标又可以通过 v4[i] 得到,因此编写解密脚本如下
_data_start__ = '~}|{zyxwvutsrqponmlkjihgfedcba`_^]\[ZYXWVUTSRQPONMLKJIHGFEDCBA@?>=<;:9876543210/.-,+*)(' +chr(0x27) + '&%$# !"'
v4 = "*F'\"N,\"(I?+@"
flag = ''
for i in range(12):
flag += chr(_data_start__.find(v4[i]) + 1)
print(flag)