逆向迷宫题总结(持续更新) 2020华南师大CTF新生赛maze,攻防世界新手区:NJUPT CTF 2017,BUUCTF:不一样的flag

本文通过多个实例解析CTF逆向工程中的迷宫题类型,介绍如何分析程序结构,确定迷宫布局和行走规则,并利用算法寻找正确路径获取flag。

CTF逆向入门:迷宫题学习记录(持续更新)

**


(前言)

本文将不断更新以具体题目为载体,分析CTF逆向迷宫题的解题思路与方法。由于本人是新手,学识有限,若有错漏或不当之处,欢迎指出。


提示:以下是本篇文章正文内容,下面案例可供参考

一、 逆向迷宫题概述

迷宫题当然是走迷宫最后得到flag啦!
主要步骤:
1.分析程序的主函数,找到迷宫
2分析程序,确定走迷宫的方法(上下左右…怎么走)
3写程序或手走迷宫,得到flag

二、 具体题目分析

1. 2019华南师大CTF新生赛maze

题目地址:https://github.com/scnu-sloth/hsctf-2019-freshmen
在这里插入图片描述在hex-view里看到了迷宫,下一步是找走迷宫的规则和方法
点开check函数看到

bool __cdecl check(char *flag)
{
   
   
  char *v1; // eax
  int v2; // eax
  char *cur; // [esp+Ch] [ebp-4h]170个字符,其中有一个是空字符'0'

  cur = &maze[14];//这是一个含14*12的迷宫
  while ( *flag && *cur != '*' )//由此可见'*'是迷宫的墙
  {
   
   
    v1 = flag++;
    v2 = *v1;
    if ( v2 == 'd' )
    {
   
   
      ++cur;//d为向右走一步
    }
    else if ( v2 > 'd' )
    {
   
   
      if ( v2 == 's' )
      {
   
   
        cur += 13;//s为向右13步,在本二维数组中为向左下方一步或向右13步
      }
      else
      {
   
   
        if ( v2 != 'w' )
          return 0;
        cur -= 13;//w为向右上方一步或向左13步
      }
    }
    else
    {
   
   
      if ( v2 != 'a' )
        return 0;
      --cur;//a为向左一步
    }
  }
  return *cur == '#';//'#'是迷宫终点
}

由题意,这是个14*12的迷宫,@是起点,#是终点,flag走迷宫的路径
d:向前一步,a:向后一步,s:向前13步,w:向后13步
在这里插入图片描述由main函数可见,flag长度即走迷宫步数一共为24步
手画迷宫如下,X表示不可走,O表示可走
写代码生成迷宫

int main()
{
   
   
	char s[]="**************@************-************-***-**-*****--*****-*****-***#**-*****--**----******-*****-******-****--******---**-*******-*-----******-------*****************";
	int i,j;
	for(i=0;i<12;i++)
	{
   
   
		for(j=0;j<14;j++)
			{
   
   
				if(s[i*14+j]=='-')
				cout<<"0"<<' ';
				else if(s[i*14+j]=='*')
				cout<<"X"<<' ';
				else 
				cout<<s[i*14+j]<<' ';
			}
		cout<<endl;
	}
	return 0;
} 

在这里插入图片描述用BFS走迷宫(代码如下)

#include<bits/stdc++.h>
using namespace std;
char mp[12*15];
int vis[12*15];
int dir[4]={
   
   1,-1,13,-13};
char S[4]={
   
   'd','a','s','w'};
struct node
{
   
   
	int x;
	string s;
};
queue<node> Q;
void bfs()
{
   
   
	node tmp;
	tmp.x=15;tmp.s="";
	Q.push(tmp);
	while(!Q.empty())
	{
   
   
		node now=Q.front();
		Q.pop();
		vis[now.x]=1;
		if(mp[now.x]=='#')
		{
   
   
			cout<<"flag{"<<now.s<<"}"<<endl;
			return;
		}
		for(int k=0;k<4;k++)
		{
   
   
			int ux=now.x+dir[k];
			if(ux<1||ux>168||mp[ux]=='X'||vis[ux]==1)
			continue;
			tmp.x=ux;
			tmp.s=now.s+S[k];
			Q.push(tmp);
		}
	}
}
int main()
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

June_gjy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值