IDA分析发现题目所谓的迷宫没有一个数据结构来表示,而是每一个函数就是一关:
输入S后进入下一关:
然后一直过关到这个函数:
开始的时候我没注意看有多少个函数,以为就几十个,手工用crossref从结果逆推,搞了很久发现有问题,然后已统计,发现有7000多个函数(关),看来只能写脚本跑。
用IDA导出C代码,然后写python脚本处理,先解析每个关卡的函数,得到一个字典:
再用穷举路径来爆破,可以得到正确的输入:
import sys
with open(r'F:\share\20210731\baby_maze\maze.c','r') as f:
srclines=f.readlines()
totals=len(srclines)
line=0
infunc=0
funcdicts={}
while(line<391893):
if infunc==0 and srclines[line][0:9]=="void sub_":
func_name=srclines[line][5:].split("(")[0].strip()
funcdict={}
label=''
infunc=1
elif srclines[line]=="}\n":
infunc=0
funcdicts[func_name]=funcdict
elif infunc:
if srclines[line][0:11]==" case ":
key=srclines[line][12:13]
if srclines[line+1][0:11]==" case ":
if srclines[line+2][0:11]==" case ":
if srclines[line+3][0:5]=="LABEL":
label=srclines[line+3].split(":")[0]
labeldo=srclines[line+4].split("(")[0].strip()
funcdict[label]=labeldo
funcdict[key]=labeldo
funcdict[srclines[line+2][12:13]]=labeldo
funcdict[srclines[line+1][12:13]]=labeldo
line+=1
elif srclines[line+3][0:13]==" goto ":
funcdict[srclines[line+1][12:13]]=srclines[line+3][13:].split(";")[0]
funcdict[srclines[line+2][12:13]]=srclines[line+3][13:].split(";")[0]
funcdict[key]=srclines[line+3][13:].split(";")[0]
else:
funcdict[srclines[line+1][12:13]]=srclines[line+3].split("(")[0].strip()
funcdict[srclines[line+2][12:13]]=srclines[line+3].split("(")[0].strip()
funcdict[key]=srclines[line+3].split("(")[0].strip()
line+=1
elif srclines[line+2][0:5]=="LABEL":
label=srclines[line+2].split(":")[0]
labeldo=srclines[line+3].split("(")[0].strip()
funcdict[label]=labeldo
funcdict[key]=labeldo
funcdict[srclines[line+1][12:13]]=labeldo
line+=1
elif srclines[line+2][0:13]==" goto ":
funcdict[srclines[line+1][12:13]]=srclines[line+2][13:].split(";")[0]
funcdict[key]=srclines[line+2][13:].split(";")[0]
else:
funcdict[srclines[line+1][12:13]]=srclines[line+2].split("(")[0].strip()
funcdict[key]=srclines[line+2].split("(")[0].strip()
line+=1
elif srclines[line+1][0:13]==" goto ":
funcdict[key]=srclines[line+1][13:20]
elif srclines[line+1][0:5]=="LABEL":
label=srclines[line+1].split(":")[0]
labeldo=srclines[line+2].split("(")[0].strip()
funcdict[label]=labeldo
funcdict[key]=labeldo
line+=1
else:
funcdict[key]=srclines[line+1].split("(")[0].strip()
line+=1
elif srclines[line][0:5]=="LABEL":
label=srclines[line].split(":")[0]
labeldo=srclines[line+1].split("(")[0].strip()
funcdict[label]=labeldo
line+=1
line+=1
keys=['A','D','W','S']
for f in funcdicts:
for k in keys:
if funcdicts[f][k].count('LABEL'):
l=funcdicts[f][k]
funcdicts[f][k]=funcdicts[f][l]
start='sub_40187C'
end='sub_54DE35'
def goforward(start,flag,path):
if start=='sub_54DE35':
print("done",'S'+flag)
sys.exit(1)
if start not in path:
path=list(path)
path.append(start)
for k in keys:
if start in funcdicts:
if k in funcdicts[start]:
if funcdicts[start][k][0:3]=='sub':
#print(funcdicts[start][k],len(path),flag)
goforward(funcdicts[start][k],flag+k,path)
goforward(start,'',[])
不到1分钟可以跑出结果:
输入程序验证成功:
这题我开始手撸浪费了很多时间,不过感觉也没这么简单,为啥有61个队伍都做出来了,我个人觉得这题其实比medical_app要难一些,那题才38个队伍做出来。
可能这题有简便方法,麻烦有知道的大佬赐教下。