Take The Maze

  首先拿进PEID里查一下有没有壳:

  无壳,果断拖进IDA。可是Graph View中找不到主程序的位置,在函数表里寻找主函数:

  函数太多阻扰了我们找到主程序,运行一下程序找一些关键词来搜索主程序位置:

  得知主程序中应当含有“welcome to zsctf!”字符串,在IDA中搜索来找到主程序:

  成功找到主函数,双击进入主函数,F5出伪代码:

  可以看出输入的KEY为24位由0-9,a-f构成的字符串,且需要根据sub_45E593()的返回值确定是否为正确KEY。其他函数先放下,先分析一下sub_45E593():

  多个if对应多个处理函数,且根据dlru初步猜测是迷宫问题。先来看看这个byte_541168存着什么:

  该数组存的是"delru0123456789",在回过头分析四个if上面的switch语句:

  可以根据两次的自加操作判断,输入的数据两两为一组。而且drc的值被用于在下面的if语句中判断是byte_541168[]前五个中的哪一个字符,所以drc就决定了迷宫的走向。stp是朝着byte_541168[drc]方向行走的步数。

  点开四个if对应的函数分别分析一下:

  从这个函数可以推测出这个迷宫一行有26个元素。根据中pos == 311则return true,而311 == 11 * 26 + 25,再加上每一行的列标号从零开始,所以相当于从地图的左上角走到地图的(12, 25)的位置,即左上角走到右下角。

  而且在上图向下走的函数中,往下走能否可行是根据dword_540548[i] ^ dword_540068[i]的值来确定的,所以可以直接根据四个方向函数中的数组地址写出IDC脚本来判断某个节点是否可以往某个特定的方向走。IDC脚本如下:

  1. auto i;
  2. for(i = ;i <= ; ++i){
  3. if(Dword(0x540548 + i * ) ^ Dword(0x540068 + i * ))
  4. Message(".");
  5. else
  6. Message("D");
  7.  
  8. if(Dword(0x5404DC + i * ) ^ Dword(0x53FFFC + i * ))
  9. Message(".");
  10. else
  11. Message("L");
  12.  
  13. if(Dword(0x5404E4 + i * ) ^ Dword(0x540004 + i * ))
  14. Message(".");
  15. else
  16. Message("R");
  17.  
  18. if(Dword(0x540478 + i * ) ^ Dword(0x53FF98 + i * ))
  19. Message(".");
  20. else
  21. Message("U");
  22.  
  23. Message(" ");
  24. if(!((i + ) % ))
  25. Message("\n\n");
  26. }
  27. return ;

  在IDA中执行效果如下:

  放到记事本里走一遍迷宫:

  手动走迷宫走出来的字符串为06360836063b0839073e0639,结果输到程序里发现还是错误的KEY,返回到主函数检查一下有没有加密函数:

  v5因为地址和v4紧挨着,所以v5其实就是v4[16],所以v5 ^= 1就相当于v4[16] ^= 1。这是加密的第一部分,分析一下疑似为加密函数的sub_45C748():

  。。。。。。这tm是什么玩意儿。

  看不太懂这是什么神奇加密,移步OD碰下运气。

  令输入的字符串为24个“1”,步过这加密函数后它变成了这样:

  右下角的框框高亮部分就是经过加密函数的样子。

  。。。。。。这不就是按位异或吗加密函数那么复杂作死啊??

  再试验一组24个“0”,发现其实是按位异或了一下,python脚本如下:

  1. a = list("06360836063b0839073e0639")
  2. a[16] = chr(ord(a[16]) ^ 1)
  3. for i in range(24):
  4. print chr(ord(a[i])^i),

  跑出来结果如下:

  去掉空格就是真正的KEY了,输进程序里面:

  工作目录下便生成了一个.png文件,点开发现是个二维码:

  扫出来:

  把之前解出来的KEY后面加上Docupa就是zsctf{}中括号里的内容啦!

【bugku】【ZSCTF】【迷宫RE】Take The Maze WriteUp的更多相关文章

  1. maze writeup

    maze writeup 攻防世界的一道迷宫题,第一次接触这样的题,个人感觉很有意思,收获也挺多,做一篇笔记记录一下. 程序分析 __int64 sub_4006B0() { signed __int ...

  2. [Swift]LeetCode1036.逃离大迷宫 | Escape a Large Maze

    In a 1 million by 1 million grid, the coordinates of each grid square are (x, y) with 0 <= x, y & ...

  3. Maze迷宫问题(求最优解)

    迷宫地形我们可以通过读文件的形式,通过已知入口逐个遍历坐标寻找通路. 文件如图: 每个坐标的位置用结构体来记录: struct Pos //位置坐标 { int _row; int _col; }; ...

  4. [LeetCode] 499. The Maze III 迷宫 III

    There is a ball in a maze with empty spaces and walls. The ball can go through empty spaces by rolli ...

  5. [LeetCode] 505. The Maze II 迷宫 II

    There is a ball in a maze with empty spaces and walls. The ball can go through empty spaces by rolli ...

  6. 解迷宫的C++的未完善编程代码........请大神们帮忙改善下.........

    这...................................................................... 我也是醉了 看不太懂,大神们求解............ ...

  7. C语言递归回溯法迷宫求解

    本例将随机产生一个10*10的迷宫输出后,在下面输出此迷宫的解法. 解法为从坐标(1,1)处进入,从(8,8,)出去,优先线路为先右后下再上最后为左. 不少人求解此题时运用的栈的相关知识,本例寻找线路 ...

  8. Java与算法之(5) - 老鼠走迷宫(深度优先算法)

    小老鼠走进了格子迷宫,如何能绕过猫并以最短的路线吃到奶酪呢? 注意只能上下左右移动,不能斜着移动. 在解决迷宫问题上,深度优先算法的思路是沿着一条路一直走,遇到障碍或走出边界再返回尝试别的路径. 首先 ...

  9. golang 实现广度优先算法(走迷宫)

    maze.go package main import ( "fmt" "os" ) /** * 广度优先算法 */ /** * 从文件中读取数据 */ fun ...

随机推荐

  1. 通过实例来学习XML DTD

    使用DTD的原因: 注意:由于它自身的一些缺点,DTD终将被淘汰,但是它还是要学习的.学习完DTD后,后面继续学习XML Schema. 1,通过 DTD,您的每一个 XML 文件均可携带一个有关其自 ...

  2. [CTF技巧]批量连接SSH批量执行命令

    https://files.cnblogs.com/files/nul1/autossh1.3.jar.zip 下载下来以后直接将后缀去除就好了. 比赛的时候可以批量写一个不死马然后你懂的. Linu ...

  3. peepscan前期准备工作

    具有的功能 1.whoami 2.sub doamin https://dns.aizhan.com/huayi-faucet.com/ 3.dir scan 4.web server 5.port ...

  4. %和format 细说

    Python中格式化字符串目前有两种阵营:%和format,我们应该选择哪种呢? 自从Python2.6引入了format这个格式化字符串的方法之后,我认为%还是format这根本就不算个问题.不信你 ...

  5. 嵌入式 uboot引导kernel,kernel引导fs【转】

    转自:http://www.cnblogs.com/lidabo/p/5383934.html#3639633 1.uboot引导kernel: u-boot中有个bootm命令,它可以引导内存中的应 ...

  6. monkey测试===Monkey测试策略(系列二)转

    Monkey的测试策略 一. 分类 Monkey测试针对不同的对象和不同的目的采用不同的测试方案,首先测试的对象.目的及类型如下: 测试的类型分为:应用程序的稳定性测试和压力测试 测试对象分为:单一a ...

  7. 小白成长记-----python实现注册的小程序

    # 3.写一个注册的程序,输入username,密码,# 密码确认,输入的账号和密码不能为空,两次输入密码必须一致,# 用户名不能重复,错误次数四次 .注册成功提示成功# 把注册账号密码信息的写到文件 ...

  8. SQL 列 转换成 查询出来的 行

    查询  每个学生 的  (姓名,语文,数学,英语,成绩)为列 表结构如下: student: 学生表 grade 成绩表 : 查询出如下效果: SQL如下: select s.name,a.* fro ...

  9. java - 线程1打印1-10,当线程打印到5后,线程2打印“hello”,然后线程1继续打印

    public class T { private static int a =1;//1代表线程1 2线程2 public static void main(String[] args) { fina ...

  10. poj 3264(RMQ或者线段树)

    Balanced Lineup Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 42929   Accepted: 20184 ...