maze writeup

  攻防世界的一道迷宫题,第一次接触这样的题,个人感觉很有意思,收获也挺多,做一篇笔记记录一下。

程序分析

__int64 sub_4006B0()
{
signed __int64 v0; // rbx
signed int v1; // eax
bool v2; // bp
bool v3; // al
const char *v4; // rdi
__int64 v6; // [rsp+0h] [rbp-28h] v6 = 0LL;
puts("Input flag:");
scanf("%s", &s1, 0LL);
if ( strlen(&s1) != 24 || strncmp(&s1, "nctf{", 5uLL) || *(&byte_6010BF + 24) != 125 )// flag长度为24字节,前五个字节为"nctf{",最后一个字节要是"}"
{
LABEL_22:
puts("Wrong flag!");
exit(-1);
}
v0 = 5LL;
if ( strlen(&s1) - 1 > 5 )
{
while ( 1 )
{
v1 = *(&s1 + v0); // 对每一位进行判断
v2 = 0;
if ( v1 > 78 )
{
v1 = (unsigned __int8)v1;
if ( (unsigned __int8)v1 == 'O' ) // "O"表示向左移动
{
v3 = sub_400650((__int64)&v6 + 4);
goto LABEL_14;
}
if ( v1 == 'o' ) // "o"表示向右移动
{
v3 = sub_400660((__int64)&v6 + 4);
goto LABEL_14;
}
}
else
{
v1 = (unsigned __int8)v1;
if ( (unsigned __int8)v1 == '.' ) // "."表示向上移动
{
v3 = sub_400670((__int64)&v6);
goto LABEL_14;
}
if ( v1 == '0' ) // "0"表示向下移动
{
v3 = sub_400680((__int64)&v6);
LABEL_14:
v2 = v3;
goto LABEL_15;
}
}
LABEL_15:
if ( !(unsigned __int8)sub_400690((__int64)asc_601060, SHIDWORD(v6), v6) )// asc_601060是字符串首地址
goto LABEL_22;
if ( ++v0 >= strlen(&s1) - 1 )
{
if ( v2 )
break;
LABEL_20:
v4 = "Wrong flag!";
goto LABEL_21;
}
}
}
if ( asc_601060[8 * (signed int)v6 + SHIDWORD(v6)] != '#' )
goto LABEL_20;
v4 = "Congratulations!";
LABEL_21:
puts(v4);
return 0LL;
}

  主函数如上所示。我开始看的时候没有看明白,后来发现给出了四种操作符,对应上下左右四种移动,给出的字符串要想象成一个二维图像,相当于要用一个二维数组表示出来。

  flag的格式已经给我们规定好了:nctf{......}。

__int64 __fastcall sub_400690(__int64 a1, int a2, int a3)
{
__int64 result; // rax result = *(unsigned __int8 *)(a1 + a2 + 8LL * a3);
LOBYTE(result) = (_DWORD)result == 32 || (_DWORD)result == 35;
return result;
}
if ( !(unsigned __int8)sub_400690((__int64)asc_601060, SHIDWORD(v6), v6) )// asc_601060是字符串首地址
goto LABEL_22;

  sub_400690函数这里拉出来看一下,SHIDWORD这里是一个宏定义,定义如下:

#define SHIDWORD(x)  (*((int32*)&(x)+1))

  对字符串如何取值或者对二级指针理解还不清楚的,可以尝试敲一下下面的测试代码:

#include<stdio.h>
#include<string.h> int main()
{
__int64 v6;
v6=1LL;char* a="abcdefghjk";
printf("%p\n",a);
printf("%p\n",*(&a));
printf("%p\n",&a);
printf("%c\n",*a);
printf("%c",*(a+1));
return 0;
}

  宏定义和四种操作符理解不了,尝试下面的测试代码:

#include<stdio.h>
#include<string.h> #define SHIDWORD(x) (*((__int32*)&(x)+1))
int main()
{
__int64 v6;
v6=1LL;
char* a="abcdefghjk";
printf("%p\n",&v6);
printf("%p\n",(__int64)&v6);
printf("%p\n",&v6+4);
printf("%p\n",(__int64)&v6+4);
printf("%p",&(SHIDWORD(v6)));
return 0;
}

  sub_400690中,v6是行数,即y坐标,SHIDWORD(v6)是列数,即x坐标,(__int64)asc_601060是字符串首地址。后面的判断表示走的时候,只能走“#”和空格。

  我们先把字符串转换成一个二维的迷宫

maze="  *******   *  **** * ****  * ***  *#  *** *** ***     *********"
x=""
New_maze=""
for a in maze:
if a==" ":
New_maze+="0"
elif a=="*":
New_maze+="1"
else:
New_maze+=a
x=""
for i in range(len(New_maze)):
x+=New_maze[i]
if (i+1)%8==0:
print(x)
x=""

  然后从头开始,“O”表示向左移动,“o”表示向右移动,“.”表示向上移动,“0”表示向下移动(上下这里要注意,容易搞错)。四种操作符看不懂,就好好看一下上面给出的测试代码。

  最后得到flag:nctf{o0oo00O000oooo..OO}。

maze writeup的更多相关文章

  1. 【bugku】【ZSCTF】【迷宫RE】Take The Maze WriteUp

    Take The Maze 首先拿进PEID里查一下有没有壳: 无壳,果断拖进IDA.可是Graph View中找不到主程序的位置,在函数表里寻找主函数: 函数太多阻扰了我们找到主程序,运行一下程序找 ...

  2. Backtracking algorithm: rat in maze

    Sept. 10, 2015 Study again the back tracking algorithm using recursive solution, rat in maze, a clas ...

  3. 2016第七季极客大挑战Writeup

    第一次接触CTF,只会做杂项和一点点Web题--因为时间比较仓促,写的比较简略.以后再写下工具使用什么的. 纯新手,啥都不会.处于瑟瑟发抖的状态. 一.MISC 1.签到题 直接填入题目所给的SYC{ ...

  4. ISCC2016 WriteUp

    日期: 2016-05-01~ 注:隔了好久才发布这篇文章,还有两道Pwn的题没放,过一阵子放上.刚开始做这个题,后来恰巧赶上校内CTF比赛,就把重心放在了那个上面. 这是第一次做类似于CTF的题,在 ...

  5. (期望)A Dangerous Maze(Light OJ 1027)

    http://www.lightoj.com/volume_showproblem.php?problem=1027 You are in a maze; seeing n doors in fron ...

  6. 参加 Tokyo Westerns / MMA CTF 2nd 2016 经验与感悟 TWCTF 2016 WriteUp

    洒家近期参加了 Tokyo Westerns / MMA CTF 2nd 2016(TWCTF) 比赛,不得不说国际赛的玩法比国内赛更有玩头,有的题给洒家一种一看就知道怎么做,但是做出来还需要洒家拍一 ...

  7. 爱春秋之戏说春秋 Writeup

    爱春秋之戏说春秋 Writeup 第一关 图穷匕见 这一关关键是给了一个图片,将图片下载到本地后,打开以及查看属性均无任何发现,尝试把图片转换为.txt格式.在文本的最后发现这样一串有规律的代码: 形 ...

  8. 1204. Maze Traversal

    1204.   Maze Traversal A common problem in artificial intelligence is negotiation of a maze. A maze ...

  9. uva705--slash maze

    /*这道题我原本是将斜线迷宫扩大为原来的两倍,但是在这种情况下对于在斜的方向上的搜索会变的较容易出错,所以参考了别人的思路后将迷宫扩展为原来的3倍,这样就变成一般的迷宫问题了*/ #include&q ...

随机推荐

  1. 21、linux系统grup和bios加密

    21.1.grup加密(加密单用户模式): 1.使用加密算法对grup密码进行加密: 2.修改grup.conf配置文件: 21.2.bios加密(因为救援模式可以破解grup加密,所以使用bios加 ...

  2. echarts 根据geojson 数据绘制区域图(精确到镇)

    步骤:1)先获取区域(县.镇)json数据 :2)使用echarts 绘制地图: 先上一波效果图(昆明市东川区) 一.获取区域json数据 1.下载工具"水经微图", 2.下载东川 ...

  3. FlowNet:simple / correlation 与 相关联操作

    Flow Net : simple / correlation 与 相关联操作 ​ 上一篇文章中(还没来得及写),已经简单的讲解了光流是什么以及光流是如何求得的.同时介绍了几个光流领域的经典传统算法. ...

  4. Docker构建mysql主从

    一.为什么要搭建主从架构呢 1.数据安全,可以进行数据的备份. 2.读写分离,大部分的业务系统来说都是读数据多,写数据少,当访问压力过大时,可以把读请求给到从服务器.从而缓解数据库访问的压力 3.故障 ...

  5. Linux:阿里云设置安全组开放对应端口过程

    手动添加后 保存就可以了.

  6. ESP-IDF硬件设计相关知识

    1.更新ESP-IDF:直接删除您本地的 esp-idf 文件夹,然后克隆新版本:更新完成后,请执行 install.sh (Windows 系统中为 install.bat)脚本,避免新版 ESP- ...

  7. 315M、433M和2.4G笔记

    一.315M无线模块 315m无线模块广泛地运用在车辆监控.遥控.遥测.小型无线网络.无线抄表.门禁系统.小区传呼.工业数据采集系统.无线标签.身份识别.非接触RF智能卡.小型无线数据终端.安全防火系 ...

  8. 备战-Java IO

    备战-Java IO 君如载酒须尽醉,醉来不复思天涯. 简介:备战-Java IO. 一.概述 Java 的 I/O 大概可以分成以下几类: 磁盘操作:File 字节操作:InputStream 和 ...

  9. nacos集群部署

    对于nacos的集群部署,建议大家参考nacos官网进行,地址:https://nacos.io/zh-cn/docs/cluster-mode-quick-start.html 下面是我自己部署na ...

  10. K8s基本概念资料

    https://www.cnblogs.com/menkeyi/p/7134460.html