
下载、查壳、pyinstall打包,惯例解包就行
解包之后是这样
接下来就是用uncompyle6,反编译5.pyc

是个迷宫题

明显是个25*25的迷宫,1是墙,0是路,w,a,s,d分别是上下左右,flag就是wasd组成的迷宫的路,起点(0,1),终点(24,23),很明显要bfs/dfs算法实现了,
写解密脚本
python
# ===================== 导入依赖库 =====================
import hashlib # 用于计算MD5哈希值,生成最终flag
import random, msvcrt # 原程序的依赖库(随机提示文本、键盘无回显输入),本解题脚本未实际调用
from collections import deque # 双端队列,BFS的核心数据结构,左端弹出操作是O(1)常数效率
# ===================== 迷宫基础数据 =====================
# 25行 × 25列的迷宫网格
# 规则:0 = 可通行的通路,1 = 不可通行的墙壁
maze = [
[1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],
[1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1],
[1,0,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,0,1,0,1],
[1,0,1,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,1,0,0,0,1,0,1],
[1,0,1,1,1,1,1,0,1,0,1,0,1,0,1,1,1,1,1,0,1,1,1,0,1],
[1,0,0,0,1,0,0,0,1,0,1,0,1,0,1,0,1,0,0,0,1,0,0,0,1],
[1,1,1,0,1,1,1,1,1,0,1,0,1,0,1,0,1,0,1,1,1,1,1,0,1],
[1,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,1,0,0,0,0,0,1,0,1],
[1,0,1,1,1,0,1,0,1,1,1,1,1,1,1,0,1,1,1,1,1,0,1,0,1],
[1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,1,0,0,0,1],
[1,0,1,1,1,1,1,1,1,0,1,0,1,0,1,1,1,0,1,0,1,1,1,0,1],
[1,0,1,0,0,0,0,0,1,0,1,0,1,0,0,0,1,0,0,0,1,0,0,0,1],
[1,0,1,0,1,1,1,0,1,1,1,0,1,0,1,0,1,1,1,0,1,0,1,1,1],
[1,0,0,0,1,0,1,0,1,0,0,0,1,0,1,0,0,0,1,0,1,0,1,0,1],
[1,1,1,1,1,0,1,0,1,0,1,1,1,0,1,1,1,0,1,0,1,0,1,0,1],
[1,0,1,0,0,0,1,0,1,0,0,0,1,0,1,0,0,0,1,0,1,0,1,0,1],
[1,0,1,0,1,0,1,0,1,0,1,0,1,1,1,0,1,1,1,1,1,0,1,0,1],
[1,0,1,0,1,0,0,0,1,0,1,0,1,0,0,0,1,0,0,0,1,0,0,0,1],
[1,0,1,0,1,1,1,1,1,0,1,0,1,0,1,1,1,0,1,0,1,1,1,0,1],
[1,0,1,0,0,0,1,0,0,0,1,0,1,0,0,0,1,0,1,0,0,0,1,0,1],
[1,0,1,1,1,0,1,1,1,1,1,0,1,1,1,0,1,0,1,1,1,0,1,0,1],
[1,0,1,0,0,0,1,0,0,0,1,0,1,0,0,0,1,0,1,0,1,0,1,0,1],
[1,0,1,0,1,1,1,0,1,0,1,0,1,0,1,1,1,0,1,0,1,0,1,0,1],
[1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1],
[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1]
]
# ===================== 起点与终点坐标 =====================
# 坐标格式:(行号, 列号)
# 行号:从上到下递增,第0行在最顶部
# 列号:从左到右递增,第0列在最左侧
start = (0, 1) # 起点:第0行第1列(迷宫最上方的入口)
end = (24, 23) # 终点:第24行第23列(迷宫最下方的出口)
# ===================== 移动方向映射表 =====================
# 每个元素格式:(按键字符, (行偏移量, 列偏移量))
# 按下对应按键时,当前坐标 + 偏移量 = 移动后的新坐标
direction = [
('w', (-1, 0)), # w键:向上走,行号减1,列号不变
('s', (1, 0)), # s键:向下走,行号加1,列号不变
('a', (0, -1)), # a键:向左走,列号减1,行号不变
('d', (0, 1)), # d键:向右走,列号加1,行号不变
]
# ===================== BFS 算法初始化 =====================
# 队列:存储所有待遍历的状态
# 每个状态是一个三元组:(当前行号, 当前列号, 走到当前位置的路径字符串)
# 起点状态:站在起点还没移动,所以路径为空字符串
queue = deque([(start[0], start[1], "")])
# 已访问集合:记录已经走过的坐标,作用是去重、防止走回头路和死循环
# 起点一开始就标记为已访问
visited = {start}
# 最终结果容器:存储找到的最短路径按键字符串,初始为空
shortest_path = ""
# ===================== BFS 主循环(广度优先搜索) =====================
while queue:
# 取出队列最左端的元素(最先入队的状态)
# popleft() 保证按「步数从小到大」的顺序逐层遍历,是BFS的核心
x, y, path = queue.popleft()
# ---------- 终点判断 ----------
# 如果当前坐标就是终点,说明找到了最短路径
# BFS特性:第一次到达终点的路径,一定是步数最少的最短路径
if (x, y) == end:
shortest_path = path # 保存最短路径字符串
break # 找到答案,直接终止搜索
# ---------- 向四个方向扩展 ----------
for char, (dx, dy) in direction:
# 计算移动后的新坐标
nx, ny = x + dx, y + dy
# ---------- 边界合法性检查 ----------
# 确保新坐标在迷宫网格范围内
if 0 <= nx <= 24 and 0 <= ny <= 24:
# ---------- 通路检查 + 去重检查 ----------
# 两个条件同时满足才可以走:
# 1. 新位置是通路(maze值为0)
# 2. 新位置没被访问过(避免重复走)
if maze[nx][ny] == 0 and (nx, ny) not in visited:
visited.add((nx, ny)) # 标记该位置为已访问
# 新状态入队:新坐标 + 拼接当前按键后的新路径
queue.append((nx, ny, path + char))
# ===================== 计算并输出最终Flag =====================
# hashlib.md5 只能处理字节(bytes)类型数据,所以先把字符串编码为utf-8字节流
# hexdigest() 输出标准的32位十六进制MD5字符串,即题目要求的flag格式
print(hashlib.md5(shortest_path.encode("utf-8")).hexdigest())
本题知识点:1、查壳
2、脱壳
3、反编译
4、bfs算法实现