-
Notifications
You must be signed in to change notification settings - Fork 0
/
analyzer_maat.py
336 lines (265 loc) · 10.7 KB
/
analyzer_maat.py
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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
from maat import *
import datetime
import time
import ntpath
from pathlib import Path
import os
import symbolic_master
from result import result
reg_r_number=0
reg_r_time_before=0
reg_r_time_after=0
reg_r_time=0
reg_w_number=0
reg_w_time_before=0
reg_w_time_after=0
reg_w_time=0
mem_r_number=0
mem_r_time_before=0
mem_r_time_after=0
mem_r_time=0
mem_w_number=0
mem_w_time_before=0
mem_w_time_after=0
mem_w_time=0
path_number=0
instruction_number=0
constraint_number=0
solving_time=0
vars_number=0
save_next = True
endexplore=False
snapshot_next = True
EXPLORATION=True
TRACEING=False
def write_results_to_database(result):
conn = sqlite3.connect('res.db')
c = conn.cursor()
c.execute('''CREATE TABLE IF NOT EXISTS maat_result (filename text, flag text, level text, exploration boolean, readattempts integer, writeattempts integer, reg_readattempts integer, reg_writeattempts integer, read_time real, write_time real, reg_read_time real, reg_write_time real, executed_insts integer, executed_stmts integer, possiblestates integer, total_time real, initializing_time real, state_forking_time real, solving_time real, constraint_number integer, variable_number integer, constraint_depth integer, constraints text, solving_attempts integer, transferring_time_cost real, transferring_number integer)''')
c.execute("INSERT INTO result VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", (result.filename, result.flag, result.level, result.Exploration, result.readattempts, result.writeattempts, result.reg_readattempts, result.reg_writeattempts, result.read_time, result.write_time, result.reg_read_time, result.reg_write_time, result.executed_insts, result.executed_stmts, result.possiblestates, result.total_time, result.initializing_time, result.state_forking_time, result.solving_time, result.constraint_number, result.variable_number, result.constraint_depth, str(result.constraints), result.solving_attempts, result.transferring_time_cost, result.transferring_number))
conn.commit()
conn.close()
def reg_r_before(m: MaatEngine):
global reg_r_number
global reg_r_time_before
reg_r_number=reg_r_number+1
reg_r_time_before=time.time()
def reg_r_after(m: MaatEngine):
global reg_r_time_after
global reg_r_time
reg_r_time_after=time.time()
reg_r_time=reg_r_time+(reg_r_time_after-reg_r_time_before)
def reg_w_before(m: MaatEngine):
global reg_w_number
global reg_w_time_before
reg_w_number=reg_w_number+1
reg_w_time_before=time.time()
def reg_w_after(m: MaatEngine):
global reg_w_time_after
global reg_w_time
reg_w_time_after=time.time()
reg_w_time=reg_w_time+(reg_w_time_after-reg_w_time_before)
def mem_r_before(m: MaatEngine):
global mem_r_number
global mem_r_time_before
mem_r_number=mem_r_number+1
mem_r_time_before=time.time()
def mem_r_after(m: MaatEngine):
global mem_r_time_after
global mem_r_time
mem_r_time_after=time.time()
mem_r_time=mem_r_time+(mem_r_time_after-mem_r_time_before)
def mem_w_before(m: MaatEngine):
global mem_w_number
global mem_w_time_before
mem_w_number=mem_w_number+1
mem_w_time_before=time.time()
def mem_w_after(m: MaatEngine):
global mem_w_time_after
global mem_w_time
mem_w_time_after=time.time()
mem_w_time=mem_w_time+(mem_w_time_after-mem_w_time_before)
def calcins(m: MaatEngine):
global instruction_number
instruction_number=instruction_number+1
def solve2(m: MaatEngine):
global path_number
global constraint_number
path_number=path_number+1
def symexplore(m: MaatEngine):
global snapshot_next
if snapshot_next:
m.take_snapshot()
# We can skip only one branch when we just inverted it, but then
# we want to take snapshots for the next ones
snapshot_next = True
def explore(m: MaatEngine, exploration):
global save_next
global path_number
global constraint_number
global vars_number
global solving_time
global snapshot_next
global endexplore
# We keep trying new paths as long as execution is stopped by reaching
while m.run() != STOP.HOOK and (not endexplore):
# Otherwise, restore previous snapshots until we find a branch condition
# that can successfuly be inverted to explore a new path
while True:
# Use the solver to invert the branch condition, and find an
# input that takes the other path
if (not exploration):
endexplore=True
path_number=path_number+1
try:
m.restore_snapshot(remove=True)
except:
endexplore=True
break
s = Solver()
# We start by adding all constraints that led to the current path.
# Those constraints need to be preserved to ensure that the new input
# we compute will still reach the current branch.
# Since the snapshots are taken *before* branches are resolved,
# m.path.constraints() doesn't contain the current branch as a constraint.
for c in m.path.constraints():
s.add(c)
vars_number=vars_number+len(c.contained_vars())
constraint_number=constraint_number+1
if m.info.branch.taken:
# If branch was previously taken, we negate the branch condition
# so that this time it is not taken
s.add(m.info.branch.cond.invert())
else:
# If the branch was not previously taken, we solve the branch condition
# so that this time it is taken
s.add(m.info.branch.cond)
# If the solver found a model that inverts the current branch, apply this model
# to the current symbolic variables context and continue exploring the next path!
start =time.time()
if s.check():
m.vars.update_from(s.get_model())
# When successfully inverting a branch, we set snapshot_next to False. We do
# this to avoid taking yet another snapshot of the current branch when
# resuming execution. We just inverted the branch, which means that one of
# both possibilities (taken and not taken) has been explored already, and
# that the other will get explored now. So there is no need to take a
# snapshot to go back to that particular branch.
snapshot_next = False
break
end = time.time()
solving_time= solving_time + (end-start)
def init_global():
global reg_r_number
reg_r_number=0
global reg_r_time_before
reg_r_time_before=0
global reg_r_time_after
reg_r_time_after=0
global reg_r_time
reg_r_time=0
global reg_w_number
reg_w_number=0
global reg_w_time_before
reg_w_time_before=0
global reg_w_time_after
reg_w_time_after=0
global reg_w_time
reg_w_time=0
global mem_r_number
global mem_r_time_before
global mem_r_time_after
global mem_r_time
global mem_w_number
global mem_w_time_before
global mem_w_time_after
global mem_w_time
global path_number
global instruction_number
global constraint_number
global solving_time
global vars_number
mem_r_number=0
mem_r_time_before=0
mem_r_time_after=0
mem_r_time=0
mem_w_number=0
mem_w_time_before=0
mem_w_time_after=0
mem_w_time=0
path_number=0
instruction_number=0
constraint_number=0
solving_time=0
vars_number=0
global endexplore
endexplore=False
global snapshot_next
snapshot_next = True
global save_next
save_next = True
def explore_single_file(filepath,flag,level,exploration):
start = datetime.datetime.now()
m = MaatEngine(ARCH.X64, OS.LINUX)
init_global()
m.hooks.add(EVENT.EXEC, WHEN.BEFORE, name="instruction", callbacks=[calcins])
m.hooks.add(EVENT.REG_R, WHEN.BEFORE, name="reg_r_before", callbacks=[reg_r_before])
m.hooks.add(EVENT.REG_R, WHEN.AFTER, name="reg_r_after", callbacks=[reg_r_after])
m.hooks.add(EVENT.REG_W, WHEN.BEFORE, name="reg_w_before", callbacks=[reg_w_before])
m.hooks.add(EVENT.REG_W, WHEN.AFTER, name="reg_w_after", callbacks=[reg_w_after])
m.hooks.add(EVENT.MEM_R, WHEN.BEFORE, name="mem_r_before", callbacks=[mem_r_before])
m.hooks.add(EVENT.MEM_R, WHEN.AFTER, name="mem_r_after", callbacks=[mem_r_after])
m.hooks.add(EVENT.MEM_W, WHEN.BEFORE, name="mem_w_before", callbacks=[mem_w_before])
m.hooks.add(EVENT.MEM_W, WHEN.AFTER, name="mem_w_after", callbacks=[mem_w_after])
m.load(filepath, BIN.ELF64,base=0x04000000, libdirs=["."])
m.hooks.add(EVENT.PATH, WHEN.BEFORE, name="path", callbacks=[symexplore])
stdin = m.env.fs.get_fa_by_handle(0)
buf = m.vars.new_concolic_buffer(
"input",
b'aaaaaaaa',
nb_elems=8,
elem_size=1,
trailing_value=ord('\n') # concrete new line at the end of the input
)
stdin.write_buffer(buf)
explore(m, exploration)
end=datetime.datetime.now()
re = result(str(filepath), flag, level)
re.Exploration = endexplore
re.readattempts = mem_r_number
re.writeattempts = mem_w_number
re.read_time = mem_r_time
re.write_time = mem_w_time
re.reg_read_time = reg_r_time
re.reg_write_time = reg_w_time
re.reg_readattempts = reg_r_number
re.reg_writeattempts = reg_w_number
re.executed_insts = instruction_number
re.variable_number = vars_number
re.possiblestates = path_number
re.solving_time = solving_time
re.total_time = str(end-start)
re.constraint_number = constraint_number
return re
def explore_one_pair(filepath,exploration):
enabled_path=filepath
r, file = ntpath.split(filepath)
disabled_path=os.path.join(r,file[:8] + 'no-' + file[8:])
if "-Ofast" in file:
disabled_path = os.path.join(r, file[:11] + 'no-' + file[11:])
path=Path(filepath)
level=path.parent.name
flag=path.parent.parent.name
enabled_res=explore_single_file(enabled_path,flag,level,exploration)
disabled_res=explore_single_file(disabled_path,flag,level,exploration)
print(enabled_res.get_result())
print(disabled_res.get_result())
f = open(os.path.join(symbolic_master.root, "maat-"+flag+".res"), "a")
f.write(enabled_res.get_result() + "\n")
f.write(disabled_res.get_result() + "\n")
f.close()
if not exploration:
f = open(os.path.join(symbolic_master.root, "maatrunning.log"), "a")
f.write(enabled_path + "\n")
f.write(disabled_path + "\n")
f.close()