2022国赛Re1 baby_tree



前言

打开题目,发现是一大串非代码格式的文字。(萌新慌了)

在这里插入图片描述

第一步

结合文件后缀名以及题目名称baby_tree,可以明白这是ast的语法树。在文件开头可以发现这是由swift编写的程序,即"re.swift"。
搜索相关资料后得知,
Swift compiler has an interesting mode: -dump-ast which outputs the abstract syntax tree of a swift source code. AST is used to represent the source code in form of a tree containing syntactic information.

由此可以得知该题的考点,分析swift的ast语法,判断加密流程,得到flag,开始分析。(tips:应该也可以本地部署swift的环境对照分析)

第二步

1.找到密文

由于该AST共有635行,顺着读效率太低,于是打算先找密文,找到突破口。在文件的528行开始,找到了密文,并发现了比对的痕迹。
在这里插入图片描述
这里有一个点是要明白该ast逻辑如何生效,并把它套用到之后的分析。
通过分析,发现是先在decl处调用Swift.(file).Array extension.==,类似于先声明运算符,然后在type处声明该运算符操作结果 typerepr='ArrayUInt8>,最后再载入操作数,该题是b和加密后的数组88,35,88,225,7,201,57,94,77,56,75,168,72,218,64,91,16,101,32,207,73,130,74,128,76,201,16,248,41,205,103,84,91,99,79,202,22,131,63,255,20,16

2.逐行分析

基于刚刚的逻辑开始从头分析,可以节省很多时间。
在这里插入图片描述
可以看到,check函数有2个string参数encodedkeyvalue,然后分别把它们转换成bk。(图中是b的,k的在下方)

然后就是r0,r1,r2,r3的生成

在这里插入图片描述
之后进入重点for循环
在这里插入图片描述
参照密文比对的逻辑,不难发现这就是声明了for i in range(0,len(b)-4+1)
然后进入循环体

在这里插入图片描述
整理一下逻辑,就是r0 = b[i],r1 = b[i+1],r2=b[i+2],r3=b[i+3](图中是r0r1的赋值)
继续往下看
在这里插入图片描述
发现是b[i]=r2^((k[0]+(r0>>4))&0xff) (图片不是完整的,整个流程很长,但逻辑不难,是从207-288行)
然后就是一直往下看,发现是不断赋值,取新值
最终发现for循环在return前停止,后面就是进行密文比对,那么说明check函数到这里结束。

在这里插入图片描述

3.写出加密流程

def check(data,key):
    b=data
    k=key
    for i in range(len(b)-4+1):
        r0,r1,r2,r3=b[i],b[i+1],b[i+2],b[i+3]
        b[i]=r2^((k[0]+(r0>>4))&0xff)
        b[i+1]=r3^((k[1]+(r1>>2))&0xff)
        b[i+2]=r0^k[2]
        b[i+3]=r1^k[3]
        k[0] = k[1]
        k[1] = k[2]
        k[2] = k[3]
        k[3] = k[0]
    return b==res

4.逆回去解密

def decode(data,key):
    b=data
    k=key
    k[0] = k[2]
    k[1] = k[3]
    k[2] = k[0]
    k[3] = k[1]
    r1 = b[38 + 3] ^ k[3]
    r0 = b[38 + 2] ^ k[2]
    r3 = b[38 + 1] ^ ((k[1] + (r1 >> 2)) & 0xff)
    r2 = b[38] ^ ((k[0] + (r0 >> 4)) & 0xff)
    b[38], b[38 + 1], b[38 + 2], b[38 + 3] = r0, r1, r2, r3
    for i in range(37,-1,-1):
        k[1] = k[0]
        k[2] = k[1]
        k[3] = k[2]
        k[0] = k[3]
        r1=b[i+3]^k[3]
        r0=b[i+2]^k[2]
        r3=b[i+1]^((k[1]+(r1>>2))&0xff)
        r2=b[i]^((k[0]+(r0>>4))&0xff)
        b[i], b[i + 1], b[i + 2], b[i + 3] = r0, r1, r2, r3
    print("".join(chr(i) for i in b))

总结

硬看

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值