maze writeup
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的更多相关文章
- 【bugku】【ZSCTF】【迷宫RE】Take The Maze WriteUp
Take The Maze 首先拿进PEID里查一下有没有壳: 无壳,果断拖进IDA.可是Graph View中找不到主程序的位置,在函数表里寻找主函数: 函数太多阻扰了我们找到主程序,运行一下程序找 ...
- Backtracking algorithm: rat in maze
Sept. 10, 2015 Study again the back tracking algorithm using recursive solution, rat in maze, a clas ...
- 2016第七季极客大挑战Writeup
第一次接触CTF,只会做杂项和一点点Web题--因为时间比较仓促,写的比较简略.以后再写下工具使用什么的. 纯新手,啥都不会.处于瑟瑟发抖的状态. 一.MISC 1.签到题 直接填入题目所给的SYC{ ...
- ISCC2016 WriteUp
日期: 2016-05-01~ 注:隔了好久才发布这篇文章,还有两道Pwn的题没放,过一阵子放上.刚开始做这个题,后来恰巧赶上校内CTF比赛,就把重心放在了那个上面. 这是第一次做类似于CTF的题,在 ...
- (期望)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 ...
- 参加 Tokyo Westerns / MMA CTF 2nd 2016 经验与感悟 TWCTF 2016 WriteUp
洒家近期参加了 Tokyo Westerns / MMA CTF 2nd 2016(TWCTF) 比赛,不得不说国际赛的玩法比国内赛更有玩头,有的题给洒家一种一看就知道怎么做,但是做出来还需要洒家拍一 ...
- 爱春秋之戏说春秋 Writeup
爱春秋之戏说春秋 Writeup 第一关 图穷匕见 这一关关键是给了一个图片,将图片下载到本地后,打开以及查看属性均无任何发现,尝试把图片转换为.txt格式.在文本的最后发现这样一串有规律的代码: 形 ...
- 1204. Maze Traversal
1204. Maze Traversal A common problem in artificial intelligence is negotiation of a maze. A maze ...
- uva705--slash maze
/*这道题我原本是将斜线迷宫扩大为原来的两倍,但是在这种情况下对于在斜的方向上的搜索会变的较容易出错,所以参考了别人的思路后将迷宫扩展为原来的3倍,这样就变成一般的迷宫问题了*/ #include&q ...
随机推荐
- 基于C#的多边形冲突检测
之前在项目上碰到了一个多边形冲突检测的问题,经百度.bing.google,发现目前已有的方案,要么是场景覆盖不全,要么是通过第三方类库实现(而这些第三方类库几乎是无法逆向反编译的),而项目中禁止使用 ...
- CS 面试题目总结(问题+答案)
开源了一个新的github仓库CS 面试题目总结(问题+答案),主要总结一些CS大厂常见的面试问题,所有的问题与答案参考了网络上的许多博客和github仓库,也希望各位读者能够对这个仓库进行补充,毕竟 ...
- 当VS和Flash builder同时运行时
1, 运行环境: windows 7, VS2010, Flash Builder 4.6 2, 在Flash Builder中运行工作空间和VS2010调试程序是同一个时,也就说在Flash ...
- css 设置body背景图片铺满
background-image: url(../../../assets/images/workflow/work.png); background-repeat: no-repeat; backg ...
- 学会这些CSS技巧让你写样式更加丝滑
目录 1,前言 1,calc() 2,min() 3,max() 4,clamp() 5,gap 6,writing-mode 1,前言 记录一些很好用的css属性 1,calc() calc()函数 ...
- openjudge走迷宫(DFS)
题目: 描述 一个迷宫由R行C列格子组成,有的格子里有障碍物,不能走:有的格子是空地,可以走. 给定一个迷宫,求从左上角走到右下角最少需要走多少步(数据保证一定能走到).只能在水平方向或垂直方向走,不 ...
- get和post两种表单提交方式的区别
今天看到一篇博客谈论get和post区别,简单总结一下https://www.cnblogs.com/logsharing/p/8448446.html 要说两者的区别,接触过web开发的人基本上都能 ...
- Kotlin Coroutine(协程): 三、了解协程
@ 目录 前言 一.协程上下文 1.调度器 2.给协程起名 3.局部变量 二.启动模式 CoroutineStart 三.异常处理 1.异常测试 2.CoroutineExceptionHandler ...
- Python 的上下文管理器是怎么设计的?
花下猫语:最近,我在看 Python 3.10 版本的更新内容时,发现有一个关于上下文管理器的小更新,然后,突然发现上下文管理器的设计 PEP 竟然还没人翻译过!于是,我断断续续花了两周时间,终于把这 ...
- ROS2学习之旅(2)——配置ROS2环境
目录 1.source一下setup文件 2.自动source 3.自动进入工作区(不常用) 4.检查环境变量是否设置成功 5.总结 ROS2依赖于使用shell(终端)环境组合工作空间的概念.工作空 ...