攻防世界-Reverse区WP--maze

简介: 攻防世界-Reverse区WP--maze

 疫情当下,都已经耍了半个月了,都不知道干啥了,无聊中,那就写了Reverse解题记录吧。

maze
根据题目描述可知这是一道迷宫题。用IDA64打开,F5将主函数main反编译成C伪代码:

int64 fastcall main(int64 a1, char a2, char a3)
{
signed
int64 v3; // rbx
signed int v4; // eax
bool v5; // bp
bool v6; // al
const char *v7; // rdi
__int64 v9; // [rsp+0h] [rbp-28h]

v9 = 0LL;
puts("Input flag:");
scanf("%s", &s1, 0LL);
if ( strlen(&s1) != 24 || strncmp(&s1, "nctf{", 5uLL) || (&byte_6010BF + 24) != '}' )
{ // flag长度为24 并且由nctf{}包裹
LABEL_22:
puts("Wrong flag!");
exit(-1);
}
v3 = 5LL;
if ( strlen(&s1) - 1 > 5 )
{
while ( 1 )
{
v4 =
(&s1 + v3); // 从flag花括号内的第一个字符开始比对
v5 = 0;
if ( v4 > 'N' )
{
v4 = (unsigned int8)v4;
if ( (unsigned
int8)v4 == 'O' )
{
v6 = sub_400650((_DWORD )&v9 + 1);
goto LABEL_14;
}
if ( v4 == 'o' )
{
v6 = sub_400660((int
)&v9 + 1);
goto LABEL_14;
}
}
else
{
v4 = (unsigned int8)v4;
if ( (unsigned
int8)v4 == '.' )
{
v6 = sub_400670(&v9);
goto LABEL_14;
}
if ( v4 == '0' )
{
v6 = sub_400680((int )&v9);
LABEL_14:
v5 = v6;
goto LABEL_15;
}
}
LABEL_15:
if ( !(unsigned int8)sub_400690((int64)asc_601060, SHIDWORD(v9), v9) ) // 检测是否发生碰撞 只有' '和'#'是可行走的
goto LABEL_22;
if ( ++v3 >= strlen(&s1) - 1 )
{
if ( v5 )
break;
LABEL_20:
v7 = "Wrong flag!";
goto LABEL_21;
}
}
}
if ( asc_601060[8
(signed int)v9 + SHIDWORD(v9)] != '#' ) //循环结束判断 是否到达迷宫终点'#'
goto LABEL_20;
v7 = "Congratulations!";
LABEL_21:
puts(v7);
return 0LL;
}

其中 SHIDWORD(v9)即 &v9 + 1 ,迷宫字符串asc_601060[]如下,长度为64:

* ** * * # ** *
根据以下代码能够判断出 &v9 为纵坐标(所在行), &v9+1为横坐标(所在列),迷宫是8*8规格的。

if ( asc_601060[8 * (signed int)v9 + SHIDWORD(v9)] != '#' ) //判断是否到达迷宫终点'#'
其中逻辑为:

当前位置 = 8(迷宫横长) * 当前纵坐标(所在行) + 当前纵坐标(所在列)
其中横纵坐标由0开始算。又根据伪代码中四个 if判断中的函数判断移动四个方向:

bool __fastcall sub_400650(_DWORD a1) // a1为 &v9+1(横坐标)
{ // v4 = 'O'
int v1;
v1 = (
a1)--; // 横坐标-1 向左移动
return v1 > 0; // 是否超出边界
}

bool __fastcall sub_400660(int a1) // a1为 &v9+1
{ // v4 = 'o'
int v1;
v1 =
a1 + 1; // 横坐标+1 向右移动
*a1 = v1;
return v1 < 8;
}

bool __fastcall sub_400670(_DWORD a1) // a1为 v9(纵坐标)
{ // v4 = '.'
int v1;
v1 = (
a1)--; // 纵坐标-1 向上移动
return v1 > 0; // 超界判断
}

bool __fastcall sub_400680(int a1) // a1为 v9
{
int v1; // v4 = '0'
v1 =
a1 + 1; // 纵坐标+1 向下移动
*a1 = v1;
return v1 < 8;
}

将迷宫字符串以8*8格式打印出来(起点在左上角,终点为#)





  • #



走出迷宫方式为:右下右右下下左下下下右右右右上上左左 对应flag字符串:o0oo00O000oooo…OO 字符串长度刚好也对应为程序开头的判断(18+6=24) 在Linux虚拟机内运行验证也正确。

目录
相关文章
攻防世界---reverse_re3
攻防世界---reverse_re3
|
机器学习/深度学习 NoSQL Linux
攻防世界-Reverse新手区WP--no-strings-attached
攻防世界-Reverse新手区WP--no-strings-attached
61 0
|
Linux
攻防世界-Reverse新手区WP--maze
攻防世界-Reverse新手区WP--maze
56 0
BUUCTF--Reverse--easyre(非常简单的逆向)WP
BUUCTF--Reverse--easyre(非常简单的逆向)WP
|
存储 安全 Linux
CTF 简单的reverse
CTF 简单的reverse
CTF 简单的reverse
LeetCode contest 200 5476. 找出数组游戏的赢家 Find the Winner of an Array Game
LeetCode contest 200 5476. 找出数组游戏的赢家 Find the Winner of an Array Game
|
存储 安全 NoSQL
[PWN][进阶篇]Rop-Ret2Text介绍及实例教学
[PWN][进阶篇]Rop-Ret2Text介绍及实例教学
645 0
[PWN][进阶篇]Rop-Ret2Text介绍及实例教学
|
安全 NoSQL C语言
[PWN][基础篇]printf漏洞介绍
[PWN][基础篇]printf漏洞介绍
221 0
[PWN][基础篇]printf漏洞介绍
|
安全 Linux C语言
[PWN][基础篇]保护函数和溢出实例
[PWN][基础篇]保护函数和溢出实例
177 0
[PWN][基础篇]保护函数和溢出实例