CISCN 初赛复盘 RE baby_tree

这道题,逆向下来会发现还是挺有规律的,多注意观察decl与extension即可
这里只写了一些关键点

一、ast树

0
经过搜索了解到这是swift语言的ast结构,编译原理的知识

二、利用Nopated++转化为js风格的代码

这样可以提高代码的可读性

0
 

三、ast树的特点

我在逆向的时候,发现ast树有个很大的特点,他总是先声明出运算符号,如==、-、+、&、arr等等,然后再在后面的argument_list(参数列表中) 列出运算所用到的参数,但很多时候,参数会再次嵌套运算符,形成如下的结构:
 
0
我们逆向的时候,会有种层层嵌套,最后递归回来的豁然感觉
 

四、注意关键词extension和decl

这两个关键词每次出现都会带来运算符、参数、函数调用之类的,如下图
 
0
 
0
 
0
(取下标)
0
(b数组)
 
甚至有的时候,decl会表示函数的含义,如下图,count代表len()函数
0

五、参数的赋值

=的运算是有点神奇的,ast没有把 '='列入运算符号中
0
是通过两行并列的式子完成的 subscript_expr 在等号左边, binary_expr在等号右边

六、最后逆向出的代码如下

bool check(string encoded,string keyValue){
    uint8[] b= arr[utf8(encoded)]               //参数类型逆向的有问题   //39行之前///
    uint8[] k= arr[utf8(keyValue)]
    UInt8 r0,r1,r2,r3;
    for i in range(len(b)-4):
        r0=b[i],r1=b[i+1],r2=b[i+2],r3=b[i+3];        //207行之前//
        b[i+0] = r2^(0xff&(k[0] + (r0>>4)));            //287行之前//
        b[i+1] = r3^(0xff&(k[1] + (r1>>2)));      //269行之前//       
        b[i+2] = r0^(k[1]);                     //410行之前//
        b[i+3] = r1^k[3];                       //451行之前
        k[0],k[1],k[2],k[3] = k[1],k[2],k[3],k[0]

    return 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]
}   //571行之前

if len(CommandLine) >= 2:
    data = CommandLine.arguments[1];//612行之前
    string key = "345y";    //621行之前
    bool result = check(data,key)   //644行之前
    print(......)   //最后的print没逆明白

七、写出解密脚本

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]
k = list('345y')    #pytohn中字符串不能修改,我们需要先把他转化为列表...


k[0], k[1], k[2], k[3] = k[2], k[3], k[0], k[1] #循环38次后的k值
for i in range(len(b)-4,-1,-1):
    r1 = b[i+3] ^ ord(k[3])
    r0 = b[i+2] ^ ord(k[2])
    r3 = b[i+1] ^ (0xff&(ord(k[1])+(r1>>2)))
    r2 = b[i+0] ^ (0xff&(ord(k[0])+(r0>>4)))
    b[i] = r0 ; b[i+1] = r1;b[i+2] = r2;b[i+3] = r3
    k[0], k[1], k[2], k[3] = k[3], k[0], k[1], k[2] #倒置

for i in b:
    print(chr(i),end="")
#flag{30831242-56db-45b4-96fd-1f47e60da99d}

八、一些小疑点

1、print的逆向没看懂
2、这两个 '->' 相当于返回类型的变化(从右往左看),暗示了函数嵌套调用...
0
 
这道题的所有点就这么多,写的有点粗糙,可能只有我自己能看懂(:
这道题给我的感觉是,只要下决心去逆向,很快就能找到规律,不错的一道题
posted @ 2022-06-13 23:29  TLSN  阅读(137)  评论(0)    收藏  举报