刚开始想对伪代码进行处理,但是需要修改的太多;比较菜不太会处理。
之后发现每个函数的栈空间都是一样的。就拜托pwn手来写gdb脚本来提取一下数据。
为了方便一下子取出来。使用idapython将程序退出的地方进行了patch,这样就算输入错误程序还是会向下运行,方便提取数据。
首先是idapython脚本patch退出的点(idapython临时学了一下,写的可能有些笨)
import idc,idautils,idaapi
funcs = idautils.Functions()
for i in funcs:
if "exit" in get_func_name(i):
print(get_func_name(i))
num = 0
for j in CodeRefsTo(i,0):
for addr in range(j-5,j+5):
idc.patch_byte(addr,0x90)
num += 1
print("patch num:" + str(num))
print("Down!")
break
之后path掉所有退出点的程序,就可以运行到最后了。同时也可以获得100个迷宫的栈空间
gdb脚本:
def b():
for i in range(1,101):
gdb.execute('b maze_'+str(i))
b()
gdb.execute('run')
gdb.execute('b getchar')
for i in range(1,101):
gdb.execute('c')
for a in range(14):
gdb.execute('c')
gdb.execute('finish')
gdb.execute('set logging file '+'maze'+str(i)+'_1.txt')
gdb.execute('set logging on')
gdb.execute('set $i=$rbp-0xc6a')
gdb.execute('x/629xb $i')
gdb.execute('set logging off')
gdb.execute('set logging file '+'maze'+str(i)+'_2.txt')
gdb.execute('set logging on')
gdb.execute('set $i=$rbp-0x9f4')
gdb.execute('x/2xw $i')
gdb.execute('set logging off')
gdb.execute('set logging file '+'maze'+str(i)+'_3.txt')
gdb.execute('set logging on')
gdb.execute('set $i=$rbp-0x9d0')
gdb.execute('x/625xw $i')
gdb.execute('set logging off')
gdb.execute('c')
gdb脚本能力有限,也不会格式化输出,只能这样logging输出了。就是用python处理麻烦点儿。
然后gdb处理后就得到了300个文件。
但是还会有几个迷宫的坐标错误,暂不知原因;分别是61 70 89 95;然后手动修改一下坐标数据。就可以用python处理了
之后就是python处理的脚本啦
import re
def get_maze(filename):
rule = re.compile(r"0x([0123456789abcdef]+)")
arr = []
with open(filename, 'r') as f:
for line in f:
arr += rule.findall(line.split(":")[1])
maze = []
for i in arr:
j = int("0x" + i, 16)
if j < 0:
j += 256
elif j > 256:
j %= 256
maze.append(j)
return maze
def main():
flag = ""
for k in range(1,101):
arrt = get_maze("./maze_data/maze"+ str(k) +"_1.txt")
maze1 = arrt[:625]
fx = arrt[625::]
for i in range(len(fx)):
fx[i] = chr(fx[i])
zb = get_maze("./maze_data/maze"+str(k)+"_2.txt")
maze2 = get_maze("./maze_data/maze"+str(k)+"_3.txt")
f = find(maze1, maze2, zb, fx)
print(f,end="")
flag += f
with open("./flag.txt",'w') as f:
f.write(flag)
print("\nDown!")
def find(maze1, maze2, zb, fx):
flag = ""
hang = zb[1]
lie = zb[0]
#print(hang)
#print(lie)
fl = [0, 0, 0, 0]
for i in range(15):
if fl[1] == 0 and (hang - 1) >= 0 and maze1[
25 * (hang - 1) + lie] ^ maze2[25 * (hang - 1) + lie] == 46:
hang -= 1
flag += fx[0]
fl = [1, 0, 0, 0]
elif fl[2] == 0 and (lie + 1) < 25 and maze1[
25 * hang + lie + 1] ^ maze2[25 * hang + lie + 1] == 46:
lie += 1
flag += fx[3]
fl = [0, 0, 0, 1]
elif fl[0] == 0 and (hang + 1) < 25 and maze1[
25 * (hang + 1) + lie] ^ maze2[25 * (hang + 1) + lie] == 46:
hang += 1
flag += fx[1]
fl = [0, 1, 0, 0]
elif fl[3] == 0 and (lie - 1) >= 0 and maze1[
25 * hang + lie - 1] ^ maze2[25 * hang + lie - 1] == 46:
lie -= 1
flag += fx[2]
fl = [0, 0, 1, 0]
else:
flag += "#"
return flag
if __name__ == '__main__':
main()