Tree

首先进来是2个函数第一个函数如下,作用是将flag中的0f 转成对应的二进制。【暗示着flag中也只有0f这些】

image-20230923222140572

看第二个函数:是将刚刚的0和1进行寻址的操作,最下面那个v3=al 是找到字符了,然后进行下一个的寻找。【这里得知道的是要do while 好几次才能找到一个字符】最后这些字符所组成的字符串要和“zvzjyvosgnzkbjjjypjbjdvmsjjyvsjx”相同。这个就是二叉树吧

这里我们要解密的就是这个二叉树。

image-20230924003936702

第二个函数的传参是root,在函数里面是al。要知道二叉树的根就得知道他的地址。静态的时候是不知道他的值是多少的,但是我们可以动态调试出来:【0x00406530】

image-20230923222015958

然后就是用IDApython来对它进行操作

方法一:爆破的思想:https://blog.csdn.net/szxpck/article/details/106197474

【需要在动态调试的时候shift + f12】

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
root = 0x00406530  # 根结点地址
secret = 'zvzjyvosgnzkbjjjypjbjdvmsjjyvsjx'


def encrypt(way):
a = root
result = ''
bin_s = '{:010b}'.format(way) # 这里设成10位二进制高位补0,起初设成8位导致a和r没有出结果
for each in bin_s: # 模拟parse函数
if (each == '1'):
a = idc.get_wide_dword(a + 12)
result += '0'
elif (each == '0'):
a = idc.get_wide_dword(a + 16)
result += '1'
if (idc.get_wide_dword(a) > 96 and idc.get_wide_dword(a) <= 122):
return result + ':' + chr(idc.get_wide_dword(a))
return 0


L = []
for each in range(1024): # 开爆,奥里给爆就完了
if (encrypt(each) != 0):
L.append(encrypt(each))

Table = list(set(L))
print(Table)

image-20230924004850668

得到:

1
['11101010:u', '11100:o', '100:s', '0011:f', '0000:y', '111010111:a', '1111:v', '00010:b', '1011:n', '0111011:i', '1110100:l', '01100:w', '1101:h', '011100:x', '110011:e', '110010:t', '1010:z', '010:j', '0111010:d', '111010110:r', '01111:k', '01101:p', '0010:g', '00011:q', '11000:c', '111011:m']

方法二:https://www.52pojie.cn/thread-1181476-1-1.html

还是需要动态调试的时候来运行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
a=[]
lujing=[]
def traverse_leaf(pnode):
if pnode != 0:
if get_wide_dword(pnode + 12) == 0 and get_wide_dword(pnode + 16) == 0:
print(chr(get_wide_byte(pnode)))
print("".join(a))
lujing.append([chr(get_wide_byte(pnode)), "".join(a)])
a.append('0')
traverse_leaf(get_wide_dword(pnode + 12))
a.append('1')
traverse_leaf(get_wide_dword(pnode + 16))
if pnode != 0x00406530:
a.pop()


traverse_leaf(0x00406530)
print(lujing)

image-20230924005107324

然后就是解flag:https://www.52pojie.cn/thread-1181476-1-1.html

1
2
3
4
5
6
7
8
9
10
11
12
13
lujing = [['y', '0000'], ['b', '00010'], ['q', '00011'], ['g', '0010'], ['f', '0011'], ['j', '010'], ['w', '01100'], ['p', '01101'], ['x', '011100'], ['d', '0111010'], ['i', '0111011'], ['k', '01111'], ['s', '100'], ['z', '1010'], ['n', '1011'], ['c', '11000'], ['t', '110010'], ['e', '110011'], ['h', '1101'], ['o', '11100'], ['l', '1110100'], ['u', '11101010'], ['r', '111010110'], ['a', '111010111'], ['m', '111011'], ['v', '1111']]
res = "zvzjyvosgnzkbjjjypjbjdvmsjjyvsjx"
flag01 = ""
flagx = ""
for i in res:
for j in lujing:
if i in j[0]:
flag01 += j[1]
print(flag01)
for i in range(0, len(flag01), 4):
tmp = "%x" % int(flag01[i:i+4], 2)
flagx += tmp
print(flagx)

这个题也有巧妙的解法:它这里有一个没有调用过的函数·outtree·这个函数也是输出二叉树的函数

但是没有调用过。它有一个参数,而且这个参数就是树的根。

我们通过修改call 命令来使它被调用,因为:parse这个函数的参数和outtree的参数一样,所以我们就只需要修改一个call指令就好了。

image-20230924005610663

image-20230924005647144

“回车”

然后弄出来:

image-20230924005809418

image-20230924005840609

然后运行它:image-20230924005953305

然后手搓:

image-20230924010112880

image-20230924010209351

最后也能解到flag