周六忘了比赛,晚上快六点才拿到题目,看了下感觉能做,研究了下,最后还是可惜,比赛结束了
拿到题目ida打开惯例看一下main
再看看汇编
基本上确定是ollvm了
下面那一堆整齐的是真实块,上面通过分发器跳转才到达真实块执行代码。看到群里有大佬直接通过动调跳转找代码的,那确实是真功夫...脚本小子直接拿deflat.py还原了。
建议放虚拟机里面,装GitHub页面推荐的angr版本
脚本还原之后的样子
这个时候f5已经可以看了
PART1
先看看第一部分的代码,前面到qmemcpy的代码是正常的分配内存和输入输出。后面进行了很长一堆的运算,其实都不用看,其实可以分析出来,前面都是静态的拿现有的进行操作,最后都给了v20,直接断在59行然后拿出v20就行了。
59行之后是一个flag格式比对,把flag里面的内容截取出来放到v22里面
PART2
我们先不看400670这个函数,先看看后面的东西,做游戏题比较多的应该很容易就能看出来这是个迷宫了,拿400670函数对flag内容处理后的数据逐位进行操作(也就是迷宫里面的上下左右)这边其实故意搞复杂了点,把上下弄成加减100,然后再在后面!v20[v5 % 100 - -24 * (v5 / 100)]
拿去判断。
能看出来其实v20也就是24*16的一张map,动调提取出来的结果是只包含0和1的一张map(我这里为了方便看,把1改成O,0改成.了)我们需要到823这个终点,也就是9行24列,从1行1列开始走即可
PART3
最后再来看sub_400670,这个函数也有ollvm,这里已经去掉了,我这里看了一阵子还没看出来是啥东西,不懂怎么逆向,后来比赛结束进一个re群问了下说是进制转换。
其实应该马上就能看出来的因为控制走路的上下左右是0123....
那么flag直接就出来了,动调取出来map在自己手搓一下路径即可
最后贴个脚本
#进制转换
def anyToDecimal(num,n):
baseStr = {"0":0,"1":1,"2":2,"3":3,"4":4,"5":5,"6":6,"7":7,"8":8,"9":9,
"a":10,"b":11,"c":12,"d":13,"e":14,"f":15,"g":16,"h":17,"i":18,"j":19}
new_num = 0
nNum = len(num) - 1
for i in num:
new_num = new_num + baseStr[i]*pow(n,nNum)
nNum = nNum -1
return new_num
a=[0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]
map=""
#路径
b="232222322330030000303322223333333222233333333"
'''输出map
for i in range(384):
if a[i]==0:
map+="."
if a[i]==1:
map+="O"
if (i+1)%24==0:
print map
map=""
'''
print("flag{"+str(anyToDecimal('232222322330030000303322223333333222233333333', 4))+"}")
总结
拿到手前面一大堆位运算还是能挺吓人(这可能是某种算法把,求大佬教教),仔细看一下其实还是不难的,可能大佬们觉得这很简单,我太菜了,做了应该算三个小时左右 😣 所以最后找个逆向带佬手把手教教我