吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 1609|回复: 3
收起左侧

[CTF] BUUCTF - re - [ACTF新生赛2020]Oruga

[复制链接]
骑着驴子追宝马 发表于 2021-11-13 16:49
BUUCTF - re - [ACTF新生赛2020]Oruga下载好后直接用IDA就可以打开,找到main函数 _int64 __fastcall main(__int64 a1, char **a2, char **a3)
[C++] 纯文本查看 复制代码
{
  __int64 result; // rax
  __int64 v4; // [rsp+0h] [rbp-40h]
  char v5; // [rsp+9h] [rbp-37h]
  char s2[4]; // [rsp+Ah] [rbp-36h]
  char s[40]; // [rsp+10h] [rbp-30h]
  unsigned __int64 v8; // [rsp+38h] [rbp-8h]
​
  v8 = __readfsqword(0x28u);
  memset(s, 0, 0x19uLL);
  printf("Tell me the flag:", 0LL);
  scanf("%s", s);
  strcpy(s2, "actf{");
  LODWORD(v4) = 0;
  while ( (signed int)v4 <= 4 )                 // v4为8字节,低4位存储索引,高四位存储值
  {
    *((_BYTE *)&v4 + (signed int)v4 + 4) = s[(signed int)v4];
    LODWORD(v4) = v4 + 1;
  }
  v5 = 0;
  if ( !strcmp((const char *)&v4 + 4, s2) )     // 比较flag头
  {
    if ( (unsigned __int8)sub_78A((__int64)s) )
      printf("That's True Flag!", s2, v4);
    else
      printf("don't stop trying...", s2, v4);
    result = 0LL;
  }


通过这些代码,我们知道flag的头为actf{进入到主要的函数分析sub_78Awhile ( byte_201020[v2] !=0x21 )
[C++] 纯文本查看 复制代码
  {
    v2 -= v4;                                   // 当前坐标
                                                // 减去上次移动多移动的一次
    if ( *(_BYTE *)(v3 + a1) != 87 || v4 == -16 )
    {
      if ( *(_BYTE *)(v3 + a1) != 69 || v4 == 1 )
      {
        if ( *(_BYTE *)(v3 + a1) != 77 || v4 == 16 )
        {
          if ( *(_BYTE *)(v3 + a1) != 74 || v4 == -1 )
            return 0LL;                         // 判断最后一位是否为'}'
                                                //
          v4 = -1;                              // a1[v3]='J'向左移动
        }
        else
        {
          v4 = 16;                              // a1[v3]='M'向下
        }
      }
      else
      {
        v4 = 1;                                 // a1[v3]='E'向右
      }
    }
    else
    {
      v4 = -16;                                 // a1[v3]='W'向上移动
    }


这个函数其实就是一个迷宫,16*16,这个迷宫并不是很复杂可以直接手动写向下移动:M向左移动:J向上移动:E向右移动:W外层while循环,就是到0x21时停止,v2为当前位置,v3从输入的第六个字符开始遍历数组,v4实际是对v2位置的移动。第二处,用了个循环,if条件判断的是位置是否到达边界,越界退出整个迷宫就是用WEMJ控制移动,0可以移动(一直移动),到达非0位置停止,返回上一位置。左上角为起点,0x21为终点。手动解迷宫别人写的脚本:
[C++] 纯文本查看 复制代码
#include <stdio.h>
char maze[256] = {
    0x00, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x23, 0x23, 0x23,
    0x00, 0x00, 0x00, 0x23, 0x23, 0x00, 0x00, 0x00, 0x4F, 0x4F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4F, 0x4F, 0x00, 0x50, 0x50, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x4C, 0x00, 0x4F, 0x4F, 0x00, 0x4F, 0x4F, 0x00, 0x50, 0x50, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x4C, 0x00, 0x4F, 0x4F, 0x00, 0x4F, 0x4F, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x4C, 0x4C, 0x00, 0x4F, 0x4F, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x4F, 0x4F, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00,
    0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4D, 0x4D, 0x4D, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4D, 0x4D, 0x4D, 0x00, 0x00, 0x00, 0x00, 0x45, 0x45,
    0x00, 0x00, 0x00, 0x30, 0x00, 0x4D, 0x00, 0x4D, 0x00, 0x4D, 0x00, 0x00, 0x00, 0x00, 0x45, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x45,
    0x54, 0x54, 0x54, 0x49, 0x00, 0x4D, 0x00, 0x4D, 0x00, 0x4D, 0x00, 0x00, 0x00, 0x00, 0x45, 0x00,
    0x00, 0x54, 0x00, 0x49, 0x00, 0x4D, 0x00, 0x4D, 0x00, 0x4D, 0x00, 0x00, 0x00, 0x00, 0x45, 0x00,
    0x00, 0x54, 0x00, 0x49, 0x00, 0x4D, 0x00, 0x4D, 0x00, 0x4D, 0x21, 0x00, 0x00, 0x00, 0x45, 0x45
};
int main(void)
{
    int i, j;
    for (i = 0; i < 16; i++)
    {
        for (j = 0; j < 16; j++)
        {
            if (i == 0 && j == 0)
                printf("☆");  //起点
            else if (maze[16 * i + j] == 0)
                printf("□");  //路
            else if (maze[16 * i + j] == 0x21)
                printf("★");  //终点
            else printf("■"); //障碍物
        }
        putchar('\n');
    }
} flag{MEWEMEWJMEWJM}

免费评分

参与人数 1吾爱币 +7 热心值 +1 收起 理由
Hmily + 7 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

Hmily 发表于 2021-11-15 11:39
代码用代码框处理一下吧,或者用markdown写,这样会好看一些。
jsncy 发表于 2021-11-16 11:34
suxiaosu67 发表于 2021-11-18 16:14
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-16 03:34

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表