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 ...
随机推荐
- 一次鞭辟入里的 Log4j2 异步日志输出阻塞问题的定位
一次鞭辟入里的 Log4j2 日志输出阻塞问题的定位 问题现象 线上某个应用的某个实例突然出现某些次请求服务响应极慢的情况,有几次请求超过 60s 才返回,并且通过日志发现,服务线程并没有做什么很重的 ...
- [源码解析] 深度学习分布式训练框架 horovod (11) --- on spark --- GLOO 方案
[源码解析] 深度学习分布式训练框架 horovod (11) --- on spark --- GLOO 方案 目录 [源码解析] 深度学习分布式训练框架 horovod (11) --- on s ...
- Jenkins之搭建部署
一.部署环境 操作系统:Centos7 软件: apache-tomcat-9.0.48--地址:https://tomcat.apache.org/download-90.cgi jdk-8u291 ...
- Tomcat:Tomcat优化(内存,并发,缓存,安全,网络,系统等)详解
一.Tomcat的安全配置 1.当Tomcat完成安装后首先要做的事情如下:首次安装完成后立即删除webapps下面的所有代码 rm -rf /srv/apache-tomcat/webapps/* ...
- Linux:jar服务部署
1.进入jar包所在文件夹中 2.启动jar,将jar在后台运行,并且记录jar的pid 命令为 : nohup java -jar test.jar (同jar包的配置文件要在jar包同级目录 ...
- Quzrtz.net 示例
//框架.Net Core 2.0//先用Nuget 安装最新quartz.net using System; using Quartz; using Quartz.Impl; using Syste ...
- mysql中函数cast使用
CAST函数语法规则是:Cast(字段名 as 转换的类型 ),其中类型可以为: CHAR[(N)] 字符型DATE 日期型DATETIME 日期和时间型DECIMAL float型SIGNED in ...
- python 常用命令sys.exit()
Python的程序有两中退出方式:os._exit(), sys.exit() os._exit()会直接将python程序终止,之后的所有代码都不会继续执行. sys.exit()会引发一个异常:S ...
- Jmeter之事务控制器
性能测试的结果统计时我们一定会关注TPS,TPS代表的是每秒事务数,每个事务对应的是我们的请求.虽然JMeter能够帮我们把每个请求统计成一个事务,但有时候我们希望把多个操作统计成一个事务,JMete ...
- js浮点数保留位数方法封装
大家在平时业务中应该经常跟小数打交道吧,有没有被小数点的保留位数问题搞得头疼啊.比如,保留一位小数,保留俩位小数,保留三位小数,向上取整.四舍五入等等. 而我最近在项目中正好遇到类似的问题:有的地方要 ...