栢鹭杯2023RE
第一次遇到AVX指令集的题目,感觉比较有意思记录一下
了解VPSHUFB指令
重点是这个说明书
https://www.felixcloutier.com/x86/pshufb
里面介绍了AVX指令集中vpshufb的使用方法(左上Index可以看到所有指令)
当然最重要的部分我先放这了:
1 | PSHUFB performs in-place shuffles of bytes in the destination operand (the first operand) according to the shuffle control mask in the source operand (the second operand). |
即
1 | PSHUFB 以第二个操作数为shuffle控制掩码将目标操作数(第一个操作数)中执行以字节为单位的shuffle。该指令排列目标操作数中的数据,使随机掩码不受影响。 |
那么问题来了
shuffle是什么?
直译是洗牌,当然也有随机播放、改组的意思
在这个地方,我觉得可以理解为“重组”
即将操作数依据某个掩码(mask)进行“重组”操作
因此,我们可以这么理解
1 | PSHUFB的作用就是将给到的第一个操作数以第二个操作数为索引进行重组 |
举个例子
现在我们在有操作数1,写成数组形式为
1 | ymm0 = [0x2A, 0x3A, 0x4A] |
操作数2
1 | ymm1 = [0x01, 0x02, 0x00] |
当我们使用VPSHUFB,以ymm2为shuffle control mask时,就会得到这样的结果
1 | ymm0 = [0x4A, 0x2A, 0x3A] |
可见,ymm0内的数根据ymm1给出的进行了重排,得到了一个原有元素不变但位置变化的数组,并覆盖了原先ymm0内的数
让我们开始做题吧
题目是栢鹭杯2023RE赛道的第一题
相关文件我懒得放了,想学的找个方式联系我我发你(小社工)
第一步,先查壳
(吐槽一下已经很久没见过比赛有壳的了)
好的没壳
第二步,上IDA
没壳就先上IDA吧(32位)
一眼Input code
直接在这F5吧
加载一下VC32_14的签名,然后把printf标注一下可以得到这个
可以看到两个函数sub_415190和sub_4156D0
看看第一个
下滑看到不少常量,应该很有用
然后看看第二个
也是常量,不过按照Little Endian来看,这就是0123…DEF然后循环,应该没什么大作用
那么重点可能就在第一个函数那几个__asm里面了
__asm为内联汇编,也就是说IDA没有分析出来这玩意干什么的,于是直接丢进来了
所以要知道这个玩意干什么用的,就得上动态调试了
第三步,动态调试
使用x32dbg进行动调
(别问我为什么不用OD,OD解析不出来AVX指令集,把我坑惨了)
这里用的是吾爱的itruth,感谢大佬施舍
直接定位关键位置吧
这个就是最重要的函数
随便输点东西先看看能不能走完它
不太友善,直接一个failed
看来得一步步找cmp然后nop掉了
先把爆破狂魔放一边,这种题硬跳肯定出不来flag的
不过便于后续操作,先硬跳一遍看看结果如何
硬跳之后发现给出来的flag似乎是一个hash值
也就是说我们可能只需要解决一个函数即可,后面交由程序生成
(这样就不用敲hash函数力(喜))
先保存下来,去看看到底有什么call
先看第一个call
这个call的数据格式很像在IDA里面看到的常量的格式,于是在内存中跟到这个ebp地址看看得到一个全FF的内容
似乎没什么作用
那么继续走一走
那么这里就有收获了
这就是我们刚刚看到的那些常量,以及一些奇奇怪怪的汇编
由于这些常量应该是有用的,那么我们就可以把他们按照Little Endian拿出来备用
接下来看汇编
值得注意的是三个指令
vpxor、vpshufb和vpcmpeqb
根据字面意思,应该能推断第一和第二个的作用
即异或运算和比较运算
至于中间这个,参考文章开头所述
那么就可以知道,最后一段的数据是用来比较的,第二段的数据是用来重排的,第一段的数据是用来异或的
知道这些那么题目就好做了
这里放上python代码
1 | a = [0xCD, 0xEB, 0x5E, 0x76, 0x0F, 0x22, 0xAF, 0x31, 0x82, 0x92, 0x3C, 0xEF, 0xB8, 0xC1, 0x76, 0x06, |
最后结果放入源程序中就可以得到flag了