[安洵杯 2019]game

发布时间 2023-08-04 11:11:04作者: h40vv3n

[安洵杯 2019]game

将文件放入IDA中打开,查看main()函数

image-20230713103733078

发现读取用户的输入,并存入v8这个变量当中,下面有两个关键函数check1()check3()使用到了该变量,我们首先分析check1()

image-20230713105604301

发现有大量的循环,根据以往的经验,这是一种混淆手段,此题的程序流程不算复杂,可以跟着流程一步步分析

image-20230713105933045

image-20230713105940471

image-20230713110003310

经过分析得知,该函数执行的操作为:

将用户的输入的前半段与后半段进行呼唤→然后再以两个为单位进行两两互换→最后再按位做运算

然后我们返回分析check()函数

image-20230713110310057

发现该函数最后提示成功需要v4==1,此时点进check2()进一步分析,发现同样经过了混淆,我们直接寻找关键的部分

image-20230713110826115

首先是将用户的输入减去48存入v16中,此时推测如果用户输入的是数字,则该操作为将字符型转换为数字型,继续分析

image-20230713111317011

image-20230713111513765

然后将v16的值赋值给D0g3这个数组,看这个数组索引的计算方式,推测形式为二维数组,又根据v15必须小于9来看,这是一个9×9的数组

image-20230713111627287

然后又跟sudoku这个数组进行比较,点进这个数组查看发现是已知的,我们直接将数据以9×9的形式提取出来,然后整理成如下所示

image-20230713111904520

发现这似乎是一个数独,然后根据先前的操作,得出该数独的解应该是经过check1()变化后的值,我们在网站上找到数独计算器可以快速得到答案

image-20230713113621701

所以此数独的解为:469364162894685722843556137219876255986

然后再根据check1()的逻辑编写解题脚本:

str1 = '4693641762894685722843556137219876255986'
str2 = []
for i in range(len(str1)):
    temp = int(str1[i])+20+48
    str2.append(str(temp & 0xf3 | ~temp & 0xc))

for i in range(0,len(str2),2):
    temp1 = str2[i]
    str2[i] = str2[i+1]
    str2[i+1] = temp1

flag = ''
for i in range(len(str2)//2):
    temp2 = str2[i]
    str2[i] = str2[len(str2)//2 + i]
    str2[len(str2)//2 + i] = temp2

for i in range(len(str2)):
    flag += chr(int(str2[i]))

print(flag)

因此此题的flag为:flag:flag{KDEEIFGKIJ@AFGEJAEF@FDKADFGIJFA@FDE@JG@J}