xctf里新手区的那道maze
其实并不是很懂为什么我查到的wp全部一笔带过如何判断上下左右所对应的字母。满屏“易知”“不难看出”还有各种转载我也是挺无语的。。
大概是正常做法8
使用ubuntu
中的file
命令得知这是一个elf
文件 。ida出来后第一个关键在这句:
1 | if ( asc_601060[8 * (signed int)v10 + SHIDWORD(v10)] != '#' ) |
asc_601060
这个地方就是存储迷宫的地方,看到8*将视图调整为8列显示,如图:
我们在上一句看到了宏定义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),高四个字节存列。
然后再分析四个函数所对应的方向。
参数是
_DWORD *a1
,做图不小心盖住了。char *
同理,指向单字节的指针,+-时指向地址+-1个字节。对了,不知道传v3
干嘛哦。
- 左:传入高4字节,指向的内容+1
- 右:传入高4字节,+1
- 上:传入低4字节,-1
- 下:传入低4字节,+1
返回值应该是用来是否出界的。在加完以后判断是否仍小于8,减完之后判断是否仍大于0。
再结合主函数的四个字母可以得出答案。
不用判断上下左右的方法
之前我一直觉得宏定义神马的不用看(想锤死当时的自己),是做一道8位整型溢出的时候才注意到声明得看,宏定义也得看。前两天没看懂的时候是这么做的:
1 | from pwn import * |
没啥好说的,拿排列组合偷了个懒。顺便记一下itertools
里C几几(无序)是combinations
。
我知道这题不难!但是没人好好说我就烦!(完)