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 ...
随机推荐
- POJ 3126 Prime Path 简单广搜(BFS)
题意:一个四位数的质数,每次只能变换一个数字,而且变换后的数也要为质数.给出两个四位数的质数,输出第一个数变换为第二个数的最少步骤. 利用广搜就能很快解决问题了.还有一个要注意的地方,千位要大于0.例 ...
- Sublime3 markdown preview 修改输出的html页面默认宽度
在sublime3 中安装了 Markdown Preview,Ctrl+B生成的HTML页面显示很窄,默认值为width: 45em,很多代码不能完整显示,需要拖动进度条,于是想要调整默认的宽度. ...
- Mybatis学习(7)实现mybatis分页
上一篇文章里已经讲到了mybatis与spring MVC的集成,并且做了一个列表展示,显示出所有article 列表,但没有用到分页,在实际的项目中,分页是肯定需要的.而且是物理分页,不是内存分页. ...
- mysql被收购 用mariadb (转)
~]# systemctl start mysql.service 要启动MySQL数据库是却是这样的提示 Failed to start mysqld.service: Unit not found ...
- ctf实验吧Once More
题目链接:http://ctf5.shiyanbar.com/web/more.php 思路分析:显然是后台逻辑代码. 1.ereg函数有漏洞,可以使用%00截断,这个就做笔记了好吧.这个函数大致意思 ...
- SpringBoot缓存管理(三) 自定义Redis缓存序列化机制
前言 在上一篇文章中,我们完成了SpringBoot整合Redis进行数据缓存管理的工作,但缓存管理的实体类数据使用的是JDK序列化方式(如下图所示),不便于使用可视化管理工具进行查看和管理. 接下来 ...
- C语言:宏定义
#include <stdio.h> #define PI 3.14159265454454235432453245 main() { printf("%f\n",PI ...
- VMware workstation虚拟机配置文件不兼容无法使用解决方法
VMware workstation虚拟机配置文件不兼容无法使用解决方法打开VMware workstation虚拟机提示:配置文件"--.vmx"是由Vmware产品创建,但该产 ...
- c语言字符串占据字节数
# include <stdio.h> //字符串占据的字节数 /* 不能将一个字符串常量赋给一个字符变量 为什么不能将一个字符串常量赋给一个字符变量?可以从两个方面作出解释: 前面讲过, ...
- 开源桌面快速启动工具-GeekDesk
GeekDesk 小巧.美观的桌面快速启动工具 开发框架 wpf .net 4.7.2 HandyControl 全局热键 鼠标跟随 快速启动 随时随地 支持自定义热键 支持鼠标跟随 自定义壁纸 随意 ...