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

embedded/2024/10/18 10:25:59/

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

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

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


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

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

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

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

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

python">#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+=1maze.append(tmp) #凑一行添加一行到迷宫中
print(maze)


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

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

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

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

python">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 pathelif len(path)==path_len:return pathfor 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.ppmy.cn/embedded/38186.html

相关文章

【智能楼宇秘籍】一网关多协议无缝对接BACnet+OPC+MQTT

在繁华的都市中心&#xff0c;一座崭新的大型商业综合体拔地而起&#xff0c;集购物、餐饮、娱乐、办公于一体&#xff0c;是现代城市生活的缩影。然而&#xff0c;这座综合体的幕后英雄——一套高度集成的楼宇自动化系统&#xff0c;正是依靠多功能协议网关&#xff0c;实现了…

深入了解 NumPy:深度学习中的数学运算利器

文章目录 1. 导入NumPy2. 创建NumPy数组3. 数组的算术运算4. N维数组4.1 创建和操作多维数组4.2 高维数组 5. NumPy的广播功能5.1 基本广播示例5.2 更复杂的广播示例 6. 访问数组元素6.1 基于索引的访问6.2 遍历数组6.3 基于条件的访问6.4 高级索引6.5 性能考虑 在深度学习和数…

关于Git的commit message规范

前几天在提交代码的时候突然发现自己的commit message写的有点问题&#xff0c;然后到网上查了下发现Git的commit message也是有规范的&#xff0c;下面我总结了三条我认为最重要的。 1.commit message需要简洁明了&#xff0c;突出变更的目的 2.提交信息的前缀用来表示你的这…

密码学《图解密码技术》记录学习 第十章

目录 第十章 10.1 本章学习的内容 10.2 证书 10.2.1 什么是证书 10.2.2 证书的应用场景 &#xff08;1) Bob 生成密钥对 (2) Bob在认证机构Trent注册自己的公钥 (3)认证机构Trent用自己的私钥对Bob的公钥施加数字签名并生成证书 (4) Alice得到带有认证机构Trent的数字签名的…

QTDay3

思维导图 #include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this);//窗口相关设置this->resize(540,415);this->setFixedSize(540,415);//窗口标题this->setWi…

第IV章-Ⅱ Vue3中的插槽使用

第IV章-Ⅱ Vue3中的插槽使用 基本插槽默认内容 具名插槽作用域插槽 在 Vue 3 中&#xff0c;插槽&#xff08;slots&#xff09;是一种强大的模式&#xff0c;用于将模板代码从父组件注入到子组件中&#xff0c;使得子组件的内容可以在使用时被自定义。Vue 3 中的插槽用法包括基…

C#知识|上位机项目登录窗口设计(实例)

哈喽,你好啊,我是雷工! 本节通过练习实例学习上位机项目UI设计方法与技巧,以下为学习笔记。 01 界面尺寸 1.1、对于客户对界面有要求的,则需要按照客户要求设计和开发; 1.2、对于客户没有提出要求的情况,则需要前期调研客户对软件界面的功能要求,布局想法,及大概展示…

Star-CCM+通过将所有部件创建一个区域的方式分配至区域后发热功率的赋值方法介绍

前言 Star-CCM通过将所有部件创建一个区域的方式分配至区域后发热功率的赋值方法与上文介绍的方法基本一致。 赋值热源 ● 热源类型选择&#xff1a; 本文按照“总热源”的类型展开介绍。具体的操作方式如下图1所示&#xff0c;在区域内下的物理条件中的能量源选项选择总热…