re学习笔记(73)2021美团CTF-Re-100mazes

推荐肉丝r0ysue课程(包含安卓逆向与js逆向):https://img-blog.csdnimg.cn/7fa698312c304ab7bb0a03e2c866990f.png
刚开始想对伪代码进行处理,但是需要修改的太多;比较菜不太会处理。
之后发现每个函数的栈空间都是一样的。就拜托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()

在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Forgo7ten

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值