0%

一道maze

xctf里新手区的那道maze

​ 其实并不是很懂为什么我查到的wp全部一笔带过如何判断上下左右所对应的字母。满屏“易知”“不难看出”还有各种转载我也是挺无语的。。

大概是正常做法8

​ 使用ubuntu中的file命令得知这是一个elf文件 。ida出来后第一个关键在这句:

1
2
3
if ( asc_601060[8 * (signed int)v10 + SHIDWORD(v10)] != '#' )
goto LABEL_20;
v8 = "Congratulations!";

asc_601060这个地方就是存储迷宫的地方,看到8*将视图调整为8列显示,如图:

迷宫.png

我们在上一句看到了宏定义SHIDOWORD,查阅了这篇博客查到这句#define SHIDWORD(x) (*((int32*)&(x)+1))。对小端序的理解自我认为还阔以吧,解释下就是把当前指针&x强制转换为32位整型指针(4个字节),地址加1,也就到了当前指针+4个字节的位置,指向下一个32位整型数据。在先前的声明中已经看到__int64 v10; // [rsp+0h] [rbp-28h],所以实际上就是用v10的低4个字节存行(signed int大概是直接取低4个字节?8字节会溢出反正emm),高四个字节存列。

然后再分析四个函数所对应的方向。

函数.png

参数是_DWORD *a1,做图不小心盖住了。char *同理,指向单字节的指针,+-时指向地址+-1个字节。对了,不知道传v3干嘛哦。

  • 左:传入高4字节,指向的内容+1
  • 右:传入高4字节,+1
  • 上:传入低4字节,-1
  • 下:传入低4字节,+1

返回值应该是用来是否出界的。在加完以后判断是否仍小于8,减完之后判断是否仍大于0。

再结合主函数的四个字母可以得出答案。

不用判断上下左右的方法

​ 之前我一直觉得宏定义神马的不用看(想锤死当时的自己),是做一道8位整型溢出的时候才注意到声明得看,宏定义也得看。前两天没看懂的时候是这么做的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
from pwn import *
from itertools import *

def crack():
left=right=up=down='.'
j=1
for i in permutations('Oo.0',4):
left,right,up,down=i
way=right+down+2*right+2*down+left+3*down+4*right+2*up+left*2
p=process('./maze')
#gdb.attach(p,'b *0x400827')
p.sendline('nctf{'+way+'}')
log.success('j='+str(j)+' sent:'+'nctf{'+way+'}')
if 'Congratulations!\n' in p.recv():
print way
break
j+=1
p.interactive()

crack()

没啥好说的,拿排列组合偷了个懒。顺便记一下itertools里C几几(无序)是combinations

我知道这题不难!但是没人好好说我就烦!(完)