CTF-reverse二维四向迷宫路径求解

news2025/2/25 13:29:11

 二维四向迷宫是一个re中的常考点,说不上难,但也不简单,本篇记录了常规的二维四向迷宫解题套路以及帮助快速解题的脚本

可能你看我的教程会觉得十分繁琐,但实际只要你用了一次熟练之后,基本都是拿到迷宫就一题一分钟解决的,教程繁琐是在力求讲解清楚!

二维四向:指的是题目规定的迷宫应该是一个二维平面(有些题目用一维数组来实现二维迷宫也适用)且移动方向只有四个


一,将数据处理成二维列表

题目给出的数据往往不是二维列表(如果是就直接进行下一步),因此提供以下这个脚本用于快速将数据转换为二维列表

(一)题目提供的是字符组成的迷宫

(二)题目提供的是整数(通常是0和1)组成的迷宫

(三)脚本一:处理迷宫为二维列表

#str为ida中使用快捷键[shift+e]提取到的数据, 如果提取的是string literal则加上引号视作字符串,如果是C array(decimal)则加上中括号视作列表
str = "字符串"/[一维列表] 
s = 0 #s用作索引访问str, 供下面tmp列表取值

#分析题目后设置迷宫的行列
row =  #设置二维迷宫行数
col =  #设置二维迷宫列数

maze = []
for i in range(row):
    tmp = []
    for j in range(col):
        tmp.append(str[s])
        s+=1
    maze.append(tmp) #凑一行添加一行到迷宫中
print(maze)


二,调整下面这个脚本的参数获得路径

遇到二维四向迷宫(有时候分析ida反汇编可能是一维数组,但实际一定是一维数组当作二维用,所以需要上面的脚本来处理成二维列表)路径问题不要再眯着眼画路径了,脚本直接颗秒

需要调整的参数有:①二维列表迷宫,②起点、终点与障碍特征(若题目给出的数据的起点终点无特征, 手动添加特征即可, 障碍通常是1但有的题目也有可能是0或其它字符如'#')

(一)脚本二:获得迷宫路径

from collections import deque

#设置二维四向迷宫, 如果题目是多个小迷宫问题, 拆分多次调用脚本获取路径即可
maze = 二维列表迷宫
path_len = 0x7fffffff#如果题目未给出终点坐标,则一定会指定路径的长度,在此处修改路径长度,否则请保留path_len的极大值

#进行BFS寻找路径
def bfs(start, end, barrier):
    directions = [(0, 1), (1, 0), (0, -1), (-1, 0)] # 定义四个方向的移动
    for i in range(len(maze)):#获取起点和终点在列表中的索引
        for j in range(len(maze[i])):
            if(maze[i][j] == start):
                start = (i, j)
            if(maze[i][j] == end):
                end = (i, j)
    #以下均是bfs算法套路
    queue = deque()
    queue.append((start, [start]))  # (当前位置, 路径)
    visited = set()
    visited.add(start)
    while queue:
        position, path = queue.popleft()
        if position == end:
            return path
        elif len(path)==path_len:
            return path
        for d in directions:
            next_position = (position[0] + d[0], position[1] + d[1])
            if 0 <= next_position[0] < len(maze) and 0 <= next_position[1] < len(maze[0]) and \
               maze[next_position[0]][next_position[1]] != barrier and next_position not in visited:
                queue.append((next_position, path + [next_position]))
                visited.add(next_position)
    return None

#执行BFS搜索并打印结果
if __name__ == '__main__':
    #maze[起点x坐标][起点y坐标] = 'S' #如果题目给了起点终点的坐标,在这里直接给起点和终点添加特征
    #maze[终点x坐标][终点y坐标] = 'E' 
    
    path = bfs('S', 'E', 1) #bfs函数传入参数代表起点、终点、障碍的特征(若题目给出的数据无特征, 手动添加特征即可, 通常障碍是1也有可能是0或其它字符如'#')
    print("移动路径坐标:", path)
    print("移动路径方位:", end='')
    for i in range(1 ,len(path)):
        x1, y1, x2, y2 = path[i - 1][0], path[i - 1][1], path[i][0], path[i][1]
        if(x1 > x2):#上
            print("w", end='')
        elif(x1 < x2):#下
            print("s", end='')
        elif(y1 > y2):#左
            print("a", end='')
        elif(y1 < y2):#右
            print("d", end='')


三,获取路径的md5值

题目一般要求路径的md5值才是flag,使用如下网址进行md5加密

 md5在线加密:MD5在线加密/解密/破解—MD5在线 (sojson.com)


四,实战演练

为了让你更清楚的明白博主的脚本如何使用,下面用两道例题来说明——

两道题目都在此链接处,推荐自己尝试练习后再看讲解->迷宫练习题

(一)题一<help>

下载压缩包并解压得到exe文件

无壳64位,用ida64打开,根据main函数提示很容易想到是迷宫问题

进一步分析,发现本题的迷宫必须通过动态调试生成,因此开启动态调试,提取迷宫

断点打在CreateMap()函数末尾,F9开始调试

 

进入调试后双击map数组,发现是由1和0组成的迷宫,根据本篇标题【一.(二)】,此处快捷键【shift+e】后应选择【C unsigned char array(decimal)

 复制其中的数据到【一.(三)】的<脚本一:处理迷宫为二维列表>中,添加列表符号(即中括号)

再根据CreateMap()函数中对map数组的操作,确认该迷宫为16行16列

修改脚本中行列参数,运行脚本得到16*16的二维列表

将二维列表复制到【二.(一)】中的<脚本二:获得迷宫路径>

 分析check()函数得到起点坐标为(15, 1),且本题未给出确切终点而是在main函数中给出了路径长为54

因此修改脚本中的path_len为54+1,注意一定要+1,因为博主的bfs搜索算法中是先判断路径长度再进行搜索的,如果不+1会导致路径少一步(其实是懒得改算法了hhhh

然后再修改起点坐标为maze[15][1],这题给了路径长度没给终点所以不管终点

 

 参数准备完毕,直接运行脚本得到路径,最后无非是再把这个路径丢到本篇标题【】中在线md5加密就解决了

可能你第一次看这个教程时觉得有些繁琐,还不如自己把迷宫整理出来然后眯着眼画路径?

但其实只要用过一次脚本,明白流程之后,只需要修改一下迷宫、起点坐标、终点坐标或路径长度(有的题不给终点坐标但一定会给路径长度),就能直接运行出来路径flag,既保证了时间又保证了准确性

相信自己,万一你就是下一个一血CTFer呢?

(二)题二<maze>

本题和题一的流程基本一致,主要是为了让读者见识两个不同迷宫的处理办法,因此省略前面的大部分操作直接进入迷宫处理

用ida32打开后双击_maze变量,很显然这就是我们要处理的迷宫

区别于第一题的是,这次是字符组成的迷宫,根据本篇标题【一.(二)】,此处快捷键【shift+e】后应选择【string literal

 复制时注意复制有效数据,复制其中的数据到【一.(三)】的<脚本一:处理迷宫为二维列表>中,添加双引号作为字符串处理

根据后续的move()函数分析得知该迷宫应为8*8,所以设置迷宫行列为8,运行获得二维列表

将二维列表复制到【二.(一)】中的<脚本二:获得迷宫路径>中,这里的path_len就不用修改了,因为本题直接给出了终点和起点的特征'S'和'E',所以不要修改它这个极大值0x7fffffff!

因为原数据已经将起点标志为'S'终点标志为'E'了,所以这题连坐标参数(37、38行)也不用改,所以看下来也只改了迷宫这一个位置

最后直接运行获得路径,再把这个路径丢到本篇标题【】中在线md5加密就解决了

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1654246.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

深入学习Linux内核页框回收

目录 算法 1.选择目标页 2.PFRA设计 3.反向映射 3.1.匿名页的反向映射 3.2.try_to_unmap_anon()函数 3.3.try_to_unmap_one()函数 映射页的反向映射 优先搜索树 try_to_unmap_file()函数 PFRA实现 最近最少使用(LRU)链表 在LRU链表之间移动页 mark_page_accessed(…

【优选算法】——双指针——Leetcode——283.移动零

目录 ​编辑 1.题目 2. 解法&#xff08;快排的思想&#xff1a;数组划分区间-数组分两块&#xff09;&#xff1a; 1.算法思路&#xff1a; 2.算法流程&#xff1a; 3.代码实现 1.C语言 2.C 1.题目 283. 移动零 提示 给定一个数组 nums&#xff0c;编写一个函数将所有…

每日一题 非对称之美

题目描述 I-非对称之美_牛客小白月赛31 (nowcoder.com) 题目解析 贪心算法的应用 考虑以下情况&#xff1a;当字符串中的字符全部相同时&#xff0c;即使删除任意一个字符&#xff0c;也无法使其成为一个回文串。这种情况下&#xff0c;我们无法直接套用上述的逐步比较方法。…

【Android】Room数据库的简单使用方法

Room数据库的使用方法 目录 1、添加Room数据库的依赖2、Entity——定义实体类 2.1 定义主键——PrimaryKey2.2 字段注解——ColumnInfo 3、Dao——定义数据访问对象4、Database——数据库 4.1 通过回调观察数据库是否创建成功 5、使用时注意点6、编写异步 DAO 查询 6.1 写异步…

LabVIEW波浪发电平台浮筒取能效率数据采集系统

LabVIEW波浪发电平台浮筒取能效率数据采集系统 随着化石能源的逐渐减少以及能源价格的上升&#xff0c;寻找可替代的、可再生的、清洁的能源成为了世界各国的共识。波浪能作为一种重要的海洋能源&#xff0c;因其巨大的潜力和清洁性&#xff0c;近年来受到了广泛关注。开发了一…

数据结构学习——二叉树

1. 树概念及结构 1.1 树的概念 树是一种非线性的数据结构&#xff0c;它是由n&#xff08;n>0&#xff09;个有限结点组成一个具有层次关系的集合。把它叫做树是因为它看起来像一棵倒挂的树&#xff0c;也就是说它是根朝上&#xff0c;而叶朝下的。 有一个特殊的结点&…

基于Springboot的校园健康驿站管理系统(有报告)。Javaee项目,springboot项目。

演示视频&#xff1a; 基于Springboot的校园健康驿站管理系统&#xff08;有报告&#xff09;。Javaee项目&#xff0c;springboot项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系…

C语言:指针(1)

1. 内存和地址 内存划分为⼀个个的内存单元&#xff0c;每个内存单元的⼤⼩取1个字节。 计算机中常⻅的单位&#xff08;补充&#xff09;&#xff1a; ⼀个⽐特位可以存储⼀个2进制的位1或者0 C语⾔中给地址起了新的名字叫&#xff1a;指针。 内存单元的编号地址指针。 1.…

重写muduo之Thread、EventLoopThread、EventLoopThreadPool

目录 1、概述 2、Thread 2.1 Thread.h 3、EventLoopThread 3.1 EventLoopThread.h 3.2 EventLoopThread.cc 4、 EventLoopThreadPool 4.1 EventLoopThreadPool.h 4.2 EventLoopThreadPool.cc 1、概述 管理事件循环线程的调度的 打包了一个EventLoop和线程&#xff0c;…

每日OJ题_记忆化搜索①_力扣509. 斐波那契数(四种解法)

目录 记忆化搜索概念和使用场景 力扣509. 斐波那契数 解析代码1_循环 解析代码2_暴搜递归 解析代码3_记忆化搜索 解析代码4_动态规划 记忆化搜索概念和使用场景 记忆化搜索是一种典型的空间换时间的思想&#xff0c;可以看成带备忘录的爆搜递归。 搜索的低效在于没有能够…

Mysql基础(五)外键约束

一 外键 激励&#xff1a; 每天进步一点点即可 ① 思考 1、在MySQL中,我们知道主键 PRIMARY KEY的主要作用是唯一区分表中的各个行 [记录];思考&#xff1a;但是对于外键 foreign key比较陌生? 那么外键作用以及限制条件和目的呢? ② 外键的定义 1、外键是某个表 A中…

DRF视图基类使用方法

【 一 】drf之请求 请求对象Request 【 0 】前言 ​ 在 Python 中&#xff0c;通常通过 request 对象来处理 HTTP 请求&#xff0c;尤其是在 web 开发中&#xff0c;比如使用 Django、Flask 等框架时会经常接触到这个对象。request 对象是框架提供的&#xff0c;用于封装客户…

YOLOv5改进(二)BiFPN替换Neck网络

前言 针对红绿灯轻量化检测&#xff0c;上一节使用MobileNetv3替换了主干网络&#xff0c;本篇将在使用BiFPN替换Neck的方式优化算法~ 往期回顾 YOLOv5改进&#xff08;一&#xff09;MobileNetv3替换主干网络 目录 一、BiFPN简介二、改进方法一第一步&#xff1a;在common.…

实战28套JAVA高端架构P6/P7/P8架构—全栈架构

概述 Java SE Java SE&#xff08;Java Platform&#xff0c;Standard Edition&#xff09;。Java SE 以前称为J2SE。它允许开发和部署在桌面、服务器、嵌入式环境和实时环境中使用的Java应用程序。Java SE 包含了支持Java Web 服务开发的类&#xff0c;并为Java Platform&…

《从零开始,搭建一个简单的UVM验证平台》实操

最近的工作中需要用UVM平台去仿真软件同事写的C程序&#xff0c;虽然只要用EDA同事已经搭好的UVM平台稍微改改就行&#xff0c;但对于我这种从未接触过UVM甚至都没用过System Verilog的纯FPGA工程师来说还是很有难度的&#xff0c;因为我对这方面一点概念都没有。 基于此&…

批量网络装机

1. PXE概念 PXE(preboot execute environment&#xff0c;预启动执行环境)是由Intel公司开发的最新技术&#xff0c;工作于Client/Server的网络模式&#xff0c;支持工作站通过网络从远端服务器下载映像&#xff0c;并由此支持通过网络启动操作系统。在启动过程中&#xff0c;…

【智能算法】雪消融优化算法(SAO)原理及实现

目录 1.背景2.算法原理2.1算法思想2.2算法过程 3.结果展示4.参考文献5.代码获取 1.背景 2023年&#xff0c;L Deng受到雪升华和融化行为启发&#xff0c;提出了雪消融优化算法&#xff08;Snow Ablation Optimizer, SAO&#xff09;。 2.算法原理 2.1算法思想 SAO模拟了雪的…

微信云小程序快速上手云数据库+云函数+云存储的操作

&#x1f680; 作者 &#xff1a;“二当家-小D” &#x1f680; 博主简介&#xff1a;⭐前荔枝FM架构师、阿里资深工程师||曾任职于阿里巴巴担任多个项目负责人&#xff0c;8年开发架构经验&#xff0c;精通java,擅长分布式高并发架构,自动化压力测试&#xff0c;微服务容器化k…

JSP技术讲解

目录 1、JSP简介 2、JSP体验 3、JSP运行原理 4、JSP基本语法 5、JSP指令 6、JSP内置九大对象 7、JSP标签 8、JSP配置 9、JSP排错 10、总结 在前面的Servlet学习中发现Servlet本质是一个java程序&#xff0c;因此Servlet更加擅长编写程序的业务逻辑&#xff0c;而如果要…

Java特性之设计模式【代理模式】

一、代理模式 概述 在代理模式&#xff08;Proxy Pattern&#xff09;中&#xff0c;一个类代表另一个类的功能。这种类型的设计模式属于结构型模式 在代理模式中&#xff0c;我们创建具有现有对象的对象&#xff0c;以便向外界提供功能接口 主要解决&#xff1a; 在直接访问…