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}

浙公网安备 33010602011771号