GFSJ1031-【reverse_re3】
迷宫
mian
__int64 __fastcall main(__int64 a1, char **a2, char **a3)
{
int v4; // [rsp+4h] [rbp-Ch]
sub_11B4(a1, a2, a3);
do
v4 = sub_940();
while ( v4 != 1 && v4 != -1 );
return 0;
}
sub_11B4 把当前迷宫编号初始化为 0
unsigned __int64 sub_11B4()
{
unsigned __int64 v1; // [rsp+8h] [rbp-8h]
v1 = __readfsqword(0x28u);
dword_202AB0 = 0;
return __readfsqword(0x28u) ^ v1;
}
迷宫方向函数
__int64 sub_940()
{
int v0; // eax
int v2; // [rsp+8h] [rbp-218h]
int v3; // [rsp+Ch] [rbp-214h]
_BYTE v4[520]; // [rsp+10h] [rbp-210h] BYREF
unsigned __int64 v5; // [rsp+218h] [rbp-8h]
v5 = __readfsqword(0x28u);
v3 = 0;
memset(v4, 0, 0x200u);
_isoc99_scanf(&unk_1278, v4, v4);
while ( 1 )
{
do
{
v2 = 0;
sub_86C();
v0 = (char)v4[v3];
if ( v0 == 100 )
{
v2 = sub_E23();
}
else if ( v0 > 100 )
{
if ( v0 == 115 )
{
v2 = sub_C5A();
}
else if ( v0 == 'w' )
{
v2 = sub_A92();
}
}
else
{
if ( v0 == 27 )
return 0xFFFFFFFFLL;
if ( v0 == 97 )
v2 = sub_FEC();
}
++v3;
}
while ( v2 != 1 );
if ( dword_202AB0 == 2 )
break;
++dword_202AB0;
}
puts("success! the flag is flag{md5(your input)}");
return 1;
}
迷宫生成
unsigned __int64 sub_86C()
{
int i; // [rsp+0h] [rbp-10h]
int j; // [rsp+4h] [rbp-Ch]
unsigned __int64 v3; // [rsp+8h] [rbp-8h]
v3 = __readfsqword(0x28u);
for ( i = 0; i <= 14; ++i )
{
for ( j = 0; j <= 14; ++j )
{
if ( dword_202020[225 * dword_202AB0 + 15 * i + j] == 3 )
{
dword_202AB4 = i;
dword_202AB8 = j;
break;
}
}
}
return __readfsqword(0x28u) ^ v3;
}
获取人物当前坐标
unsigned __int64 sub_86C()
{
int i;
int j;
for ( i = 0; i <= 14; ++i )
{
for ( j = 0; j <= 14; ++j )
{
if ( dword_202020[225 * dword_202AB0 + 15 * i + j] == 3 )
{
dword_202AB4 = i;
dword_202AB8 = j;
break;
}
}
}
}
函数遍历当前迷宫 找到值为 3 的位置
dword_202AB4 当前行
dword_202AB8 当前列
地图中各数值含义为
0 墙
1 可通行道路
3 当前人物位置
4 终点
向右移动
__int64 sub_E23()
{
if ( dword_202AB8 != 14 )
{
if ( dword_202020[225 * dword_202AB0 + 1 + 15 * dword_202AB4 + dword_202AB8] == 1 )
{
dword_202020[225 * dword_202AB0 + 1 + 15 * dword_202AB4 + dword_202AB8] = 3;
dword_202020[225 * dword_202AB0 + 15 * dword_202AB4 + dword_202AB8] = 1;
}
else if ( dword_202020[225 * dword_202AB0 + 1 + 15 * dword_202AB4 + dword_202AB8] == 4 )
{
return 1;
}
}
return 0;
}
当前列不是最右边时 检查右侧格子
右侧坐标为
row * 15 + col + 1
如果右侧是 1 就把右侧改成 3 当前格改成 1 完成移动
如果右侧是 4 说明到达终点 返回 1
因此该函数对应
d 向右
向左移动
__int64 sub_FEC()
{
if ( dword_202AB8 )
{
if ( dword_202020[225 * dword_202AB0 - 1 + 15 * dword_202AB4 + dword_202AB8] == 1 )
{
dword_202020[225 * dword_202AB0 - 1 + 15 * dword_202AB4 + dword_202AB8] = 3;
dword_202020[225 * dword_202AB0 + 15 * dword_202AB4 + dword_202AB8] = 1;
}
else if ( dword_202020[225 * dword_202AB0 - 1 + 15 * dword_202AB4 + dword_202AB8] == 4 )
{
return 1;
}
}
return 0;
}
左侧坐标为
row * 15 + col - 1
所以该函数对应
a 向左
向上移动
__int64 sub_A92()
{
if ( dword_202AB4 )
{
if ( dword_202020[225 * dword_202AB0 - 15 + 15 * dword_202AB4 + dword_202AB8] == 1 )
{
dword_202020[225 * dword_202AB0 - 15 + 15 * dword_202AB4 + dword_202AB8] = 3;
dword_202020[225 * dword_202AB0 + 15 * dword_202AB4 + dword_202AB8] = 1;
}
else if ( dword_202020[225 * dword_202AB0 - 15 + 15 * dword_202AB4 + dword_202AB8] == 4 )
{
return 1;
}
}
return 0;
}
上一行需要减去一行的宽度 15
row * 15 + col - 15
所以该函数对应
w 向上
向下移动
__int64 sub_C5A()
{
if ( dword_202AB4 != 14 )
{
if ( dword_202020[225 * dword_202AB0 + 15 + 15 * dword_202AB4 + dword_202AB8] == 1 )
{
dword_202020[225 * dword_202AB0 + 15 + 15 * dword_202AB4 + dword_202AB8] = 3;
dword_202020[225 * dword_202AB0 + 15 * dword_202AB4 + dword_202AB8] = 1;
}
else if ( dword_202020[225 * dword_202AB0 + 15 + 15 * dword_202AB4 + dword_202AB8] == 4 )
{
return 1;
}
}
return 0;
}
下一行需要增加一行的宽度 15
row * 15 + col + 15
所以该函数对应
s 向下
最终方向关系为
w 上
s 下
a 左
d 右
主校验函数
v0 = (char)v4[v3];
if ( v0 == 'd' )
v2 = sub_E23();
else if ( v0 == 's' )
v2 = sub_C5A();
else if ( v0 == 'w' )
v2 = sub_A92();
else if ( v0 == 'a' )
v2 = sub_FEC();
程序逐字节读取输入 根据 wasd 控制人物移动 每次移动函数返回 1 就表示当前迷宫到达终点
if ( dword_202AB0 == 2 )
break;
++dword_202AB0;
当第一张迷宫完成后
dword_202AB0 由 0 变成 1
当第二张迷宫完成后
dword_202AB0 由 1 变成 2
当第三张迷宫完成时 当前编号已经是 2 所以直接跳出循环 这也说明题目一共有三张迷宫 根据数据将每 225 个整数切成一张 15 × 15 的地图
第一张迷宫
.....##########
.....#S..######
.....###.######
.....###.######
.....###.....##
.....#######.##
.....#######.##
.....#######..#
.....########.#
.....########E#
...............
...............
...............
...............
...............
最短路径
ddsssddddsssdss
第二张迷宫
..#############
..#S.....######
..#..###.######
..######.######
..#..###.....##
..#..#######.##
..#..#######.##
..#..#####....#
..#..#####.##.#
..#..#####.####
..#......#.#..#
..#...........#
..###########E#
...............
...............
最短路径
dddddsssddddsssaassssddds
第三张迷宫
###############
#S..###########
###.#...#######
###...#.#######
####..#.#######
#..#.##.#######
##...##.#######
#######.#######
#######....####
##########.####
##########.####
##########.####
##########....#
#############.#
#############E#
最短路径
ddssddwddssssssdddssssdddss
三张迷宫需要连续通关 所以把三段路径拼接
ddsssddddsssdss
dddddsssddddsssaassssddds
ddssddwddssssssdddssssdddss
得到完整输入
ddsssddddsssdssdddddsssddddsssaassssdddsddssddwddssssssdddssssdddss
exp
import hashlib
path = (
"ddsssddddsssdss"
"dddddsssddddsssaassssddds"
"ddssddwddssssssdddssssdddss"
)
print(f"flag{{{hashlib.md5(path.encode()).hexdigest()}}}")
一把梭了
评论