这场比赛唯一有意义的一道逆向题,需要熟悉idapython的api,并要求一定数据结构知识,在这贴几个脚本方便以后可能用到
整个题目就是在探索路径,动调得知main_convert
会把输入转换成二进制01数组,然后根据01走相应的分支,一个点往后对应两条路,相当于要建一个二叉树
给节点改个名先
1
2
3
4
5
6
7
|
start = 0x401000
end = 0x583400
index = 0
for i in range(start, end):
if "godeep_tree." in get_name(i):
set_name(i, "node"+str(index))
index += 1
|
总共5672个节点,获取所有节点和边
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
28
29
30
31
32
33
34
35
|
from idaapi import *
from idc import *
start = 0x401000
end = 0x583400
out = open("out.txt", "w")
for i in range(start, end):
parent = get_name(i)
if parent[0:4] != "node":
continue
out.write(parent[4:]+" ")
j = i
f = False
child = GetDisasm(j)
last = ""
while child != "retn":
if last == child:
j += 1
child = GetDisasm(j)
continue
if child == 'call node5672':
if f:
out.write(child[child.find('e')+1:] +" ")
else:
f = True
elif 'call node' in child:
out.write(child[child.find('e')+1:]+" ")
elif 'wrong' in child:
out.write("wrong ")
elif 'right' in child:
out.write("right ")
last = child
j += 1
child = GetDisasm(j)
out.write('\n')
|
建立二叉树+dfs求路径
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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
|
from Crypto.Util.number import *
file = open("out.txt", "r")
dic = dict()
class TreeNode:
def __init__(self, id):
self.id = id
self.state = True
self.flag = False
self.left = None
self.right = None
root = TreeNode(9999)
node0 = TreeNode(0)
root.left = node0
dic[0] = node0
for i in file.readlines():
parent = eval(i.split()[0])
parent_node = TreeNode(parent)
if dic.get(parent) != None:
parent_node = dic.get(parent)
else:
dic[parent] = parent_node
if i.split()[1] == 'wrong':
parent_node.state = False
continue
if i.split()[1] == 'right':
parent_node.flag = True
continue
if len(i.split()) == 2:
left_node = TreeNode(eval(i.split()[1]))
dic[eval(i.split()[1])] = left_node
parent_node.left = left_node
elif len(i.split()) == 3:
left_node = TreeNode(eval(i.split()[1]))
dic[eval(i.split()[1])] = left_node
parent_node.left = left_node
right_node = TreeNode(eval(i.split()[2]))
dic[eval(i.split()[2])] = right_node
parent_node.right = right_node
path = []
def dfs(parent):
if parent.flag:
print(path)
print(long_to_bytes(eval("0b"+"".join(str(i) for i in path).removeprefix('1'))))
exit()
if not parent.state:
return
if parent.left:
path.append(1)
dfs(parent.left)
path.pop(-1)
if parent.right:
path.append(0)
dfs(parent.right)
path.pop(-1)
dfs(root)
print("no answer")
print(path)
|
flag{fc03bd97-ff7b-419f-8987-78bc745d3b0a}