Buuctf - oruga 解释地图边界问题

while ( !map[v2] )                          // 每次移动一定遇到障碍物才停下
   {
     if ( v4 == -1 && (v2 & 0xF) == 0 )        // 往左
       return 0LL;
     if ( v4 == 1 && v2 % 16 == 15 )           // 往右
       return 0LL;
     if ( v4 == 16 && (unsigned int)(v2 - 240) <= 0xF )
       return 0LL;
     if ( v4 == -16 && (unsigned int)(v2 + 15) <= 0x1E )
       return 0LL;
     v2 += v4;
   }

条件:

(v2 & 0xF) == 0

检查v2是否位于地图的最左侧
v2 & 0xF提取v2的第4位,即(v2 % 16),表示当前的列号
如果列号为0,说明已经达到最左侧,不能再向左移动
功能:
如果尝试向左移动但已达到边界,则直接返回0,表示无法移动

( v4 == 1 && v2 % 16 == 15 )

向右移动

检查v2 % 16 ==15,检查v2是否位于地图的最右列
如果列号为15,说明已经达到最有侧列,不能再向右移动
功能:
如果尝试向右移动但已达到边界,则直接返回0

( v4 == 16 && (unsigned int)(v2 - 240) <= 0xF )

向下移动,检查v2是否位于地图的最底行,地图底行的范围是[240,255] (假设地图大小为16 * 16)
如果v2在这个范围内,说明已经达到最底行,不能再向下移动
功能:
如果尝试向下移动但已达到边界,则直接返回0

( v4 == -16 && (unsigned int)(v2 + 15) <= 0x1E )

向上移动,检查是否位于地图的最顶行


 (v4 == -16 && (unsigned int)(v2 + 15) <= 0x1E)

移动方向向上,检测v2是否位于地图的最顶端

此while代码是指朝一个方向前进,直到遇到障碍物才停止
查看地图

打印地图有两种方法
一种是利用插件 convert to list即可
第二种着重强调,利用idapython

点击File - script command

代码如下

  #include <idc.idc>
> static main(){
>     Message("\nStart:--------------------------------------------------------------------------------\n");
>     auto addr = 0x201020;
>     auto i = 0;
>     for (i = addr;i < 0x201120;i++){
>         Message("0x%02x,",Byte(i));
>         }
>         Message("\nEnd:-----------------------------------------------------------------------------\n");
}

也能得到迷宫

然后分析迷宫写代码
有很多奇怪的T,M之类的,其实都是障碍物
退出v4加减,map[v2]的机制是== 33转化后为! 所以出口是'!'

map = [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]
flag=""
for i in range(16):
    for j in range(16):
        if map[16*i + j] == 0:
            flag += "0"
        elif map[16*i + j] == 0x21:
            flag += "#"
        else:
            flag += "*"
    flag += "\n"
print(flag)

然后打印出迷宫

0000*0000000****
000**000**000000
00000000**0**000
000*0**0**0**000
000*0**0**0*0000
00**0**0000*0000
00000**0000*0000
*000000000000000
000000000000*000
000000***000*000
0000000***0000**
000*0*0*0*0000*0
00000000000000**
****0*0*0*0000*0
0*0*0*0*0*0000*0
0*0*0*0*0*#000**

初始v2 = 0,即从开始出发
而且要注意是上左下右的顺序试错

所以
flag{MEWEMEWJMEWJM}

posted @ 2025-04-19 23:21  LingWann  阅读(15)  评论(0)    收藏  举报