BUUCTF逆向wp [HDCTF2019]Maze

第一步  查壳,本题是32位,有壳,进行脱壳。

第二步    这里的 jnz 指令会实现一个跳转,并且下面的0EC85D78Bh被标红了,应该是一个不存在的地址,这些东西就会导致IDA无法正常反汇编出原始代码,也称为花指令。(如下图)

我们把先把jnz指令右键nop,之后再将call指令变成数据再进行下一步nop。

点击call指令,按D数据化后尝试先把第一个数据nop掉,之后尝试建立主函数,如果不行的话再将下一个数据也nop掉。

nop完后从这里开始到00401128,按p构建main函数。

构建后是这个样子,我们跟进main

这里有关本题解决花指令的方法详情前参考这篇文章:

[HDCTF2019]Maze(考点:去花)_[hdctf2019]maze 题解-CSDN博客

第三步   按tab键转换(红色的不用管,可能是我脏字节没弄干净,不影响)。

分析一下这段代码:

其中终点为(5,-4),因此后面显示congratulations的字样。

函数调用和输入读取

  1. sub_401140(aGoThroughTheMa);
    • 调用函数 sub_401140 并传入参数 aGoThroughTheMa,这可能是一个提示或指示信息。
  2. v5 = scanf("%14s", v7);
    • 使用 scanf 从标准输入读取最多14个字符的字符串到变量 v7 中,并将读取的字符数赋值给 v5。

循环处理用户输入

  1. for (i = 0; i <= 13; ++i)
    • 遍历用户输入的每个字符(最多14个),进行相应的处理。
  2. switch (v7[i])  根据当前字符 v7[i] 的值,执行不同的操作:
    • default: continue;
      • 对于其他字符,继续下一次循环。
    • case 'w': ++dword_40807C;
      • 如果字符是 'w',则增加变量 dword_40807C 的值。
    • case 's': --dword_40807C;
      • 如果字符是 's',则减少变量 dword_40807C 的值。
    • case 'd': ++*(_DWORD *)asc_408078;
      • 如果字符是 'd',则增加 asc_408078 指向的 DWORD 类型的值。
    • case 'a': --*(_DWORD *)asc_408078;
      • 如果字符是 'a',则减少 asc_408078 指向的 DWORD 类型的值。

结果判断

  1. if (*(_DWORD *)asc_408078 == 5 && dword_40807C == -4)
    • 检查 asc_408078 指向的值是否为5,并且 dword_40807C 的值是否为-4。这两个条件可能代表了玩家需要达到的目标状态。
  2. 成功与否的处理
    • 成功 (true 分支)
      • sub_401140(aCongratulation);
        • 调用 sub_401140 并传入 aCongratulation,可能用于显示恭喜信息。
      • sub_401140(aHereIsTheFlagF);
        • 调用 sub_401140 并传入 aHereIsTheFlagF,可能用于显示成功获得的奖励或标志。
    • 失败 (else 分支)
      • sub_401140(aTryAgain);
        • 调用 sub_401140 并传入 aTryAgain,提示用户再次尝试。

返回值

  1. return 0;
    • 函数返回0,通常表示程序执行成功。

我们在代码中发现“a”“s”“d”“w”四个操作对应我们键盘上的四个按键,这是迷宫问题的典型特征。

跟进一下asc_408078(或dword_40807C),得到如下信息:

a和d控制左右,w和s控制上下,因此asc对应横着的第几列,dword对应竖着的第几行

上图告诉我们,起点为(7,0)。

我们推测:+对应的是起点,F对应的是终点(之前的迷宫题目也是差不多的)

第四步   编写脚本

分析一下脚本:

  1. 变量定义和查找
    • maze 是一个包含迷宫字符的字符串。
    • sid 和 eid 分别是字符 '+' 和 'F' 在 maze 中的索引位置。
  2. 计算行和列
    • ex, ey 被定义为 -4 和 5。这些值在代码中的具体含义不明确,但看起来像是尝试定义某种“步长”或“方向”。
    • c = (eid - ey) // (-ex) 计算列数。这里的计算方式比较特殊,看起来是尝试根据某种规则来确定列宽。
    • r = len(maze) // c 计算行数,即迷宫的总长度除以每行的字符数。
  3. 输出迷宫
    • 循环从 0 到 r,每次循环打印从 c*i 到 c*(i+1) 的子字符串,这应该是尝试将一维字符串按照每行 c 个字符分割成多行。

r = 7 (即7行)

c = 10(即10列)

为了方便读者理解F的位置ex,ey =(5,-4)我在下面的图上标出了坐标轴,类似于把该迷宫放在第四象限。

flag{ssaaasaassdddw}

相关推荐

  1. BUUCTF)actf_2019_actfnote

    2024-07-17 22:38:04       50 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-17 22:38:04       67 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-17 22:38:04       72 阅读
  3. 在Django里面运行非项目文件

    2024-07-17 22:38:04       58 阅读
  4. Python语言-面向对象

    2024-07-17 22:38:04       69 阅读

热门阅读

  1. 卡码网语言基础课 | 5. A+B问题⑤

    2024-07-17 22:38:04       23 阅读
  2. Web前端-Web开发CSS基础2-选择器

    2024-07-17 22:38:04       17 阅读
  3. 448. 找到所有数组中消失的数字

    2024-07-17 22:38:04       20 阅读
  4. 洛谷P1255 数楼梯

    2024-07-17 22:38:04       20 阅读
  5. C#后台向某个网站发送Get或者Post请求

    2024-07-17 22:38:04       26 阅读
  6. c#中的事件

    2024-07-17 22:38:04       24 阅读
  7. 用python写一个爬虫,爬取google中关于蛇的照片

    2024-07-17 22:38:04       21 阅读
  8. Log4j的原理及应用详解(五)

    2024-07-17 22:38:04       24 阅读
  9. 私域运营 组织架构

    2024-07-17 22:38:04       20 阅读
  10. ipvsadm命令的详细使用方法

    2024-07-17 22:38:04       24 阅读
  11. 2024/6/26 Stream流

    2024-07-17 22:38:04       20 阅读