This repository has been archived by the owner on May 10, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathkernel_handlers.py
622 lines (532 loc) · 26.5 KB
/
kernel_handlers.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
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
import logging
from os_dict import IOCTLS_INT_TO_IOCTL
from os_dict import SIGNAL_INT_TO_SIG
from os_dict import SIGPROCMASK_INT_TO_CMD
from os_dict import STACK_SS_TO_INT
from os_dict import SIGNAL_SIG_TO_INT
from os_dict import SIGNAL_DFLT_HANDLER_TO_INT
from os_dict import SIGNAL_FLAG_TO_HEX
# from util import *
from util import(validate_integer_argument,
should_replay_based_on_fd,
noop_current_syscall,
apply_return_conditions,
cint,
swap_trace_fd_to_execution_fd,
cleanup_return_value,
ReplayDeltaError,)
def rt_sigaction_entry_handler(syscall_id, syscall_object, pid):
logging.debug("Entering rt_sigaction entry handler")
# check if there is an old action. as only need to worry about those
old_action_found = syscall_object.args[-2].value.strip() != 'NULL'
if not old_action_found:
logging.debug("No rt_sigaction read intercepted!")
noop_current_syscall(pid)
else:
logging.debug("rt_sigaction read intercepted")
# figure out if there is a new action, and whether strace is showing the sa_restorer value in the actions
restorer_value_in_trace = True
new_action_found = syscall_object.args[1].value != "NULL"
if (new_action_found):
logging.debug("rt_sigaction write intercepted")
restorer_value_in_trace = syscall_object.args[4].value.find('}') != -1
else:
restorer_value_in_trace = syscall_object.args[5].value.find('}') != -1
logging.debug("Trace %s restorer values" % ('contains'
if restorer_value_in_trace
else 'does not contain'))
# figure out at what indexes the old_action arguments will start and end at
if new_action_found and restorer_value_in_trace:
old_action_start_pos = 5
elif new_action_found:
old_action_start_pos = 4
else:
old_action_start_pos = 2
old_action_end_pos = old_action_start_pos + (4 if restorer_value_in_trace
else 3)
# seperate out the old_action part of the trace
old_action_args = syscall_object.args[old_action_start_pos:old_action_end_pos]
logging.debug("ARGUMENTS BEGIN")
# these are the values we need to put into memory
old_action_addr = 0
old_sa_flags = 0
old_sa_handler = 0
old_sa_mask_list = []
old_sa_restorer = 0
# old_sa_sigaction = 0 # void (int, siginfo_t*, void*) Serves as an alternate for old_sa_handler but yet to be seen or implemented
# buffer address
old_action_addr = cint.peek_register(pid, cint.EDX)
logging.debug("Old Action Address: 0x%x" % (old_action_addr & 0xffffffff))
# done with registers so can noop now
noop_current_syscall(pid)
# now parse arguments out of the strace object
# old_sa_flags
old_flags_str = old_action_args[2].value.strip('{}')
if (old_flags_str != '0'):
old_flags_list = old_flags_str.split('|')
logging.debug("FLAGS: " + str(old_flags_list))
for flag in old_flags_list:
flag_int = int(SIGNAL_FLAG_TO_HEX.get(flag))
if (flag_int == None):
raise LookupError("The flag " + str(flag) + " was not found")
old_sa_flags += flag_int
logging.debug("Old Flags: " + str(old_sa_flags))
# if flags include SA_SIGINFO should use old_sa_sigaction instead of old_sa_handler
should_use_sigaction = (old_sa_flags & 4) == 4
if (should_use_sigaction):
raise NotImplementedError("rt_sigaction should use sa_sigaction instead of sa_handler here but this functionality is not yet implemented")
# old_sa_handler
old_sa_handler_str = old_action_args[0].value.strip('{')
logging.debug("Handler Raw: " + str(old_sa_handler_str));
# handler is either one of 3 default handlers (in which case strace gives a name) or a pointer value
default_handler_int = SIGNAL_DFLT_HANDLER_TO_INT.get(old_sa_handler_str)
if (default_handler_int != None):
old_sa_handler = default_handler_int
else:
old_sa_handler = int(old_sa_handler_str, 16)
logging.debug("Old Handler: 0x%x" % (old_sa_handler & 0xffffffff))
# sa_mask
old_mask_list_str = old_action_args[1].value
is_non_empty_list = old_mask_list_str != '[]'
if (is_non_empty_list):
old_mask_list = old_mask_list_str[1:-1].split(' ')
# add 'SIG' to say 'PIPE' to make 'SIGPIPE' as strace leaves the beginning off
old_mask_list = ["SIG" + name for name in old_mask_list if not str(name)[0:3] == "SIG"]
# convert names into ints
old_sa_mask_list = [SIGNAL_SIG_TO_INT[sig] for sig in old_mask_list]
logging.debug("Old Mask List: " + str(old_sa_mask_list))
# sa_restorer
if restorer_value_in_trace:
restorer_str = old_action_args[3].value.strip('}')
old_sa_restorer = int(restorer_str, 16)
logging.debug("Restorer: 0x%x " % (old_sa_restorer & 0xffffffff))
else:
logging.debug("No restorer found")
logging.debug("ARGUMENTS END")
cint.populate_rt_sigaction_struct(pid,
old_action_addr,
old_sa_handler,
old_sa_mask_list,
old_sa_flags,
old_sa_restorer
)
# finish
apply_return_conditions(pid, syscall_object)
def getresuid_entry_handler(syscall_id, syscall_object, pid):
logging.debug('Entering getresuid entry handler')
ruid = int(syscall_object.args[0].value.strip('[]'))
euid = int(syscall_object.args[0].value.strip('[]'))
suid = int(syscall_object.args[0].value.strip('[]'))
ruid_addr = cint.peek_register(pid, cint.EBX)
euid_addr = cint.peek_register(pid, cint.ECX)
suid_addr = cint.peek_register(pid, cint.EDX)
logging.debug('ruid: %d', ruid)
logging.debug('euid: %d', euid)
logging.debug('suid: %d', suid)
logging.debug('ruid addr: %x', ruid_addr & 0xffffffff)
logging.debug('ruid addr: %x', euid_addr & 0xffffffff)
logging.debug('ruid addr: %x', suid_addr & 0xffffffff)
noop_current_syscall(pid)
cint.populate_unsigned_int(pid, ruid_addr, ruid)
cint.populate_unsigned_int(pid, euid_addr, euid)
cint.populate_unsigned_int(pid, suid_addr, suid)
apply_return_conditions(pid, syscall_object)
def getresgid_entry_handler(syscall_id, syscall_object, pid):
logging.debug('Entering getresgid entry handler')
ruid = int(syscall_object.args[0].value.strip('[]'))
euid = int(syscall_object.args[0].value.strip('[]'))
suid = int(syscall_object.args[0].value.strip('[]'))
ruid_addr = cint.peek_register(pid, cint.EBX)
euid_addr = cint.peek_register(pid, cint.ECX)
suid_addr = cint.peek_register(pid, cint.EDX)
logging.debug('ruid: %d', ruid)
logging.debug('euid: %d', euid)
logging.debug('suid: %d', suid)
logging.debug('ruid addr: %x', ruid_addr & 0xffffffff)
logging.debug('ruid addr: %x', euid_addr & 0xffffffff)
logging.debug('ruid addr: %x', suid_addr & 0xffffffff)
noop_current_syscall(pid)
cint.populate_unsigned_int(pid, ruid_addr, ruid)
cint.populate_unsigned_int(pid, euid_addr, euid)
cint.populate_unsigned_int(pid, suid_addr, suid)
apply_return_conditions(pid, syscall_object)
def set_tid_address_entry_handler(syscall_id, syscall_object, pid):
logging.debug('Entering set_tid_address_entry_handler')
# POSIX-omni-parser treats this argument as a hex string with no 0x
# We have to do manual cleanup here
addr_from_trace = int('0x' + syscall_object.args[0].value, 16)
addr_from_execution = cint.peek_register(pid, cint.EBX) & 0xffffffff
logging.debug('Address from trace: %x', addr_from_trace)
logging.debug('Address from execution: %x', addr_from_execution)
if addr_from_trace != addr_from_execution:
raise ReplayDeltaError('Address from trace ({}) does not match '
'address from execution ({})'
.format(addr_from_trace,
addr_from_execution))
def set_tid_address_exit_handler(syscall_id, syscall_object, pid):
logging.debug('Entering set_tid_address_exit_handler')
addr_from_trace = int('0x' + syscall_object.args[0].value, 16)
tid_from_trace = int(syscall_object.ret[0])
# We have to use the address from the trace here for two reasons:
# 1. We already confirmed at the traces matches execution in this regard
# in the entry handler
# 2. Registers have been trashed by this point so we don't have any choice
logging.debug('Address from trace: %x', addr_from_trace)
logging.debug('TID from trace: %d', tid_from_trace)
# We place the TID from the trace into the appropriate memory location
# so future references are correct
cint.populate_unsigned_int(pid, addr_from_trace, tid_from_trace)
apply_return_conditions(pid, syscall_object)
def futex_entry_handler(syscall_id, syscall_object, pid):
logging.debug('Entering futex entry handler')
addr_from_trace = int('0x' + syscall_object.args[0].value, 16)
addr_from_execution = cint.peek_register(pid, cint.EBX) & 0xffffffff
logging.debug('Address from trace: %x', addr_from_trace)
logging.debug('Address from execution: %x', addr_from_execution)
if addr_from_trace != addr_from_execution:
raise ReplayDeltaError('Address from trace ({}) does not match '
'address from execution ({})'
.format(addr_from_trace,
addr_from_execution))
def futex_exit_handler(syscall_id, syscall_object, pid):
logging.debug('Entering futex exit handler')
ret_val_from_trace = syscall_object.ret[0]
ret_val_from_execution = cint.peek_register(pid, cint.EAX) & 0xffffffff
if ret_val_from_trace != ret_val_from_execution:
raise ReplayDeltaError('Return value from trace ({}) does not match '
'return value from execution ({})'
.format(ret_val_from_trace,
ret_val_from_execution))
def fadvise64_64_entry_handler(syscall_id, syscall_object, pid):
logging.debug('Entering fadvise_64_64 entry handler')
validate_integer_argument(pid, syscall_object, 0, 0)
validate_integer_argument(pid, syscall_object, 1, 1)
validate_integer_argument(pid, syscall_object, 2, 2)
if should_replay_based_on_fd(int(syscall_object.args[0].value)):
logging.debug('Replaying this system call')
noop_current_syscall(pid)
apply_return_conditions(pid, syscall_object)
else:
logging.debug('Not replaying this system call')
# This handler assumes that uname cannot fail. The only documented way it can
# fail is if the buffer it is handed is somehow invalid. This code assumes that
# well written programs don't do this.
def uname_entry_handler(syscall_id, syscall_object, pid):
logging.debug('Entering uname handler')
args = {x.value.split('=')[0]: x.value.split('=')[1]
for x in syscall_object.args}
args = {x.strip('{}'): y.strip('"{}') for x, y in args.iteritems()}
logging.debug(args)
address = cint.peek_register(pid, cint.EBX)
noop_current_syscall(pid)
cint.populate_uname_structure(pid,
address,
args['sysname'],
args['nodename'],
args['release'],
args['version'],
args['machine'],
args['domainname'])
apply_return_conditions(pid, syscall_object)
def getrlimit_entry_handler(syscall_id, syscall_object, pid):
logging.debug('Entering getrlimit handler')
cmd = syscall_object.args[0].value[0]
if cmd != 'RLIMIT_STACK':
raise Exception('Unimplemented getrlimit command {}'.format(cmd))
addr = cint.peek_register(pid, cint.ECX)
rlim_cur = syscall_object.args[1].value.strip('{')
rlim_cur = rlim_cur.split('=')[1]
if rlim_cur.find('*') == -1:
raise Exception('Unimplemented rlim_cur format {}'.format(rlim_cur))
rlim_cur = int(rlim_cur.split('*')[0]) * int(rlim_cur.split('*')[1])
rlim_max = syscall_object.args[2].value.strip('}')
rlim_max = rlim_max.split('=')[1]
if rlim_max != 'RLIM_INFINITY':
raise Exception('Unlimited rlim_max format {}'.format(rlim_max))
rlim_max = 0x7fffffffffffffff
logging.debug('rlim_cur: %s', rlim_cur)
logging.debug('rlim_max: %x', rlim_max)
logging.debug('Address: %s', addr)
noop_current_syscall(pid)
cint.populate_rlimit_structure(pid, addr, rlim_cur, rlim_max)
apply_return_conditions(pid, syscall_object)
def ioctl_entry_handler(syscall_id, syscall_object, pid):
logging.debug('Entering ioctl handler')
validate_integer_argument(pid, syscall_object, 0, 0)
trace_fd = int(syscall_object.args[0].value)
if not should_replay_based_on_fd(trace_fd):
logging.debug('Not replaying this system call')
swap_trace_fd_to_execution_fd(pid, 0, syscall_object)
return
logging.debug('Replaying this system call')
edx = cint.peek_register(pid, cint.EDX)
logging.debug('edx: %x', edx & 0xffffffff)
addr = edx
noop_current_syscall(pid)
if syscall_object.ret[0] != -1:
cmd = syscall_object.args[1].value
cmd_from_exe = cint.peek_register(pid, cint.ECX)
_validate_ioctl_cmd(cmd, cmd_from_exe)
# HACK: this if statement is terrible
if not ('TCGETS' in cmd or 'FIONREAD' in cmd or 'TCSETSW' in cmd or
'FIONBIO' in cmd or 'TIOCGWINSZ' in cmd or
'TIOCSWINSZ' in cmd or 'TCSETSF' in cmd or 'TCSETS' in cmd or
'FIOCLEX' in cmd):
raise NotImplementedError('Unsupported ioctl command')
if 'TIOCGWINSZ' in cmd:
ws_row = syscall_object.args[2].value
ws_row = int(ws_row.split('=')[1])
ws_col = syscall_object.args[3].value
ws_col = int(ws_col.split('=')[1])
ws_xpixel = syscall_object.args[4].value
ws_xpixel = int(ws_xpixel.split('=')[1])
ws_ypixel = syscall_object.args[5].value
ws_ypixel = int(ws_ypixel.split('=')[1].strip('}'))
logging.debug('ws_row: %s', ws_row)
logging.debug('ws_col: %s', ws_col)
logging.debug('ws_xpixel: %s', ws_xpixel)
logging.debug('ws_ypixel: %s', ws_ypixel)
cint.populate_winsize_structure(pid,
addr,
ws_row,
ws_col,
ws_xpixel,
ws_ypixel)
elif 'FIONREAD' in cmd:
num_bytes = int(syscall_object.args[2].value.strip('[]'))
logging.debug('Number of bytes: %d', num_bytes)
cint.populate_int(pid, addr, num_bytes)
elif 'FIONBIO' in cmd:
out_val = int(syscall_object.args[2].value.strip('[]'))
out_addr = cint.peek_register(pid, cint.EDX)
cint.poke_address(pid, out_addr, out_val)
elif 'TCGETS' in cmd:
c_iflags = syscall_object.args[2].value
c_iflags = int(c_iflags[c_iflags.rfind('=')+1:], 16)
c_oflags = syscall_object.args[3].value
c_oflags = int(c_oflags[c_oflags.rfind('=')+1:], 16)
c_cflags = syscall_object.args[4].value
c_cflags = int(c_cflags[c_cflags.rfind('=')+1:], 16)
c_lflags = syscall_object.args[5].value
c_lflags = int(c_lflags[c_lflags.rfind('=')+1:], 16)
c_line = syscall_object.args[6].value
c_line = int(c_line[c_line.rfind('=')+1:])
if not ('c_cc' in syscall_object.args[-1].value):
raise NotImplementedError('Unsupported TCGETS argument format')
cc = syscall_object.args[-1].value
cc = cc.split('=')[1].strip('"{}')
cc = cc.decode('string-escape')
logging.debug('pid: %s', pid)
logging.debug('Addr: %s', addr)
logging.debug('cmd: %s', cmd)
logging.debug('c_iflags: %x', c_iflags)
logging.debug('c_oflags: %x', c_oflags)
logging.debug('c_cflags: %x', c_cflags)
logging.debug('c_lflags: %x', c_lflags)
logging.debug('c_line: %s', c_line)
logging.debug('len(cc): %s', len(cc))
cint.populate_tcgets_response(pid, addr, c_iflags, c_oflags,
c_cflags,
c_lflags,
c_line,
cc)
else:
logging.debug('Got a %s ioctl() call', cmd)
logging.debug('WARNING: NO SIDE EFFECTS REPLICATED')
apply_return_conditions(pid, syscall_object)
def ioctl_exit_handler(syscall_id, syscall_object, pid):
pass
def _ioctl_int_to_flag(i):
f = IOCTLS_INT_TO_IOCTL[i]
# HACK!
if f == 'TIOCINQ':
return ('TIOCINQ', 'FIONREAD')
else:
return (f,)
def _validate_ioctl_cmd(cmd_t, cmd_e):
if 'or' in cmd_t:
cmd_t = cmd_t.split(' or ')
else:
cmd_t = [cmd_t]
cmd_t = set(cmd_t)
cmd_e = _ioctl_int_to_flag(cmd_e)
cmd_e = set(cmd_e)
if (not (cmd_t <= cmd_e)) and (not (cmd_e <= cmd_t)):
raise ReplayDeltaError('Command from trace (one of {}) does not match '
'command from execution (one of {})'
.format(cmd_t, cmd_e))
def prlimit64_entry_handler(syscall_id, syscall_object, pid):
logging.debug('Entering prlimit64 entry handler')
validate_integer_argument(pid, syscall_object, 0, 0)
have_new_limit = False
have_old_limit = False
if(syscall_object.args[2].value != 'NULL'
and syscall_object.args[3].value != 'NULL'
and syscall_object.args[4].value == 'NULL'):
logging.debug('We have a new limit')
have_new_limit = True
elif(syscall_object.args[2].value == 'NULL'
and syscall_object.args[3].value != 'NULL'
and syscall_object.args[4].value != 'NULL'):
logging.debug('We have an old limit')
have_old_limit = True
if have_new_limit and not have_old_limit:
if syscall_object.args[1].value != 'RLIMIT_CORE':
raise NotImplementedError('prlimit commands with a new limit only '
'support RLIMIT_CORE')
noop_current_syscall(pid)
apply_return_conditions(pid, syscall_object)
elif not have_new_limit and have_old_limit:
if syscall_object.args[1].value != 'RLIMIT_NOFILE':
raise NotImplementedError('prlimit commands other than '
'RLIMIT_NOFILE are not supported')
rlim_cur = int(syscall_object.args[3].value.split('=')[1])
logging.debug('rlim_cur: %d', rlim_cur)
rlim_max = syscall_object.args[4].value.split('=')[1]
rlim_max = rlim_max.split('*')
rlim_max = int(rlim_max[0]) * int(rlim_max[1].strip('}'))
logging.debug('rlim_max: %d', rlim_max)
addr = cint.peek_register(pid, cint.ESI)
logging.debug('addr: %x', addr & 0xFFFFFFFF)
noop_current_syscall(pid)
cint.populate_rlimit_structure(pid, addr, rlim_cur, rlim_max)
apply_return_conditions(pid, syscall_object)
else:
raise NotImplementedError('prlimit64 calls with both a new and old '
'limit are not supported')
def mmap2_entry_handler(syscall_id, syscall_object, pid):
logging.debug('Entering mmap2 entry handler')
validate_integer_argument(pid, syscall_object, 4, 4)
trace_fd = int(syscall_object.args[4].value)
if trace_fd != -1:
swap_trace_fd_to_execution_fd(pid, 4, syscall_object)
else:
logging.debug('ignoring anonymous mmap2 call')
def mmap2_exit_handler(syscall_id, syscall_object, pid):
logging.debug('Entering mmap2 exit handler')
ret_from_execution = cint.peek_register(pid, cint.EAX)
ret_from_trace = cleanup_return_value(syscall_object.ret[0])
logging.debug('Return value from execution %x', ret_from_execution)
logging.debug('Return value from trace %x', ret_from_trace)
if ret_from_execution < 0:
ret_from_execution &= 0xffffffff
if ret_from_execution != ret_from_trace:
logging.debug('Return value from execution (%d, %x) differs '
'from return value from trace (%d, %x)',
ret_from_execution,
ret_from_execution,
ret_from_trace,
ret_from_trace)
def sched_getaffinity_entry_handler(syscall_id, syscall_object, pid):
logging.debug('Entering sched_getaffinity entry handler')
# We don't validate the first argument because the PID,
# which is different for some reason?
validate_integer_argument(pid, syscall_object, 1, 1)
try:
cpu_set_val = int(syscall_object.args[2].value.strip('{}'))
except ValueError:
raise NotImplementedError('handler cannot deal with multi-value '
'cpu_sets: {}'
.format(syscall_object.args[2]))
cpu_set_addr = cint.peek_register(pid, cint.EDX)
logging.debug('cpu_set value: %d', cpu_set_val)
logging.debug('cpu_set address: %d', cpu_set_addr)
noop_current_syscall(pid)
cint.populate_cpu_set(pid, cpu_set_addr, cpu_set_val)
apply_return_conditions(pid, syscall_object)
def sigaltstack_entry_handler(syscall_id, syscall_object, pid):
# This madness is to deal with the fact that the omni-parser
# messes up argument positions when dealing with structures
if (syscall_object.args[0].value == 'NULL'
and syscall_object.args[1].value == 'NULL'):
have_ss = False
have_oss = False
elif (syscall_object.args[0].value == 'NULL'
and syscall_object.args[1].value != 'NULL'):
have_ss = False
have_oss = True
# Here, oss values are located at 1, 2, 3
ss_sp = syscall_object.args[1].value
ss_flags = syscall_object.args[2].value
ss_size = syscall_object.args[3].value
elif (syscall_object.args[0].value != 'NULL'
and syscall_object.args[3].value == 'NULL'):
have_ss = True
have_oss = False
elif (syscall_object.args[0].value != 'NULL'
and syscall_object.args[3].value != 'NULL'):
have_ss = True
have_oss = True
# here oss values are at 3, 4, 5
ss_sp = syscall_object.args[3].value
ss_flags = syscall_object.args[4].value
ss_size = syscall_object.args[5].value
else:
raise ReplayDeltaError('Invalid parse of syscall_object')
ss_from_execution = cint.peek_register(pid, cint.EBX)
oss_from_execution = cint.peek_register(pid, cint.ECX)
# Check for delta
if ((have_oss and (oss_from_execution == 0))
or not have_oss and (oss_from_execution != 0)):
print(oss_from_execution)
print(have_oss)
raise ReplayDeltaError('Got non-NULL trace oss and null execution '
'oss')
if ((have_ss and (ss_from_execution == 0))
or not have_ss and (ss_from_execution != 0)):
raise ReplayDeltaError('Got non-NULL trace ss and null execution '
'ss')
noop_current_syscall(pid)
if have_oss:
# We have an oss so we need to populate the output structure
# We've gathered the arguments required above but we need to clean them
# up before we can use them
ss_sp = int(ss_sp.split('=')[1])
ss_flags = ss_flags.split('=')[1]
ss_flags = _cleanup_ss_flags(ss_flags)
ss_size = int(ss_size.split('=')[1].strip('}'))
logging.debug('pid: %d', pid)
logging.debug('addr: %d', oss_from_execution)
logging.debug('ss_sp: %d', ss_sp)
logging.debug('ss_flags: %d', ss_flags)
logging.debug('ss_size: %d', ss_size)
cint.populate_stack_structure(pid,
oss_from_execution,
ss_sp,
ss_flags,
ss_size)
apply_return_conditions(pid, syscall_object)
def _cleanup_ss_flags(ss_flags):
if ss_flags == '0':
return 0
else:
return STACK_SS_TO_INT[ss_flags]
def brk_entry_debug_printer(pid, orig_eax, syscall_object):
logging.debug('This call tried to use address: %x',
cint.peek_register(pid, cint.EBX))
def mmap2_entry_debug_printer(pid, orig_eax, syscall_object):
logging.debug('This call tried to mmap2: %d',
cint.peek_register(pid, cint.EDI))
def munmap_entry_debug_printer(pid, orig_eax, syscall_object):
logging.debug('This call tried munmap address: %x length: %d',
cint.peek_register(pid, cint.EBX) & 0xFFFFFFFF,
cint.peek_register(pid, cint.ECX))
def ioctl_entry_debug_printer(pid, orig_eax, syscall_object):
logging.debug('This call used file descriptor: %d',
cint.peek_register(pid, cint.EBX))
logging.debug('This call used command: %s',
IOCTLS_INT_TO_IOCTL[
cint.peek_register(pid, cint.ECX)])
def rt_sigaction_entry_debug_printer(pid, orig_eax, syscall_object):
signum = cint.peek_register(pid, cint.EBX)
newact_addr = cint.peek_register(pid, cint.ECX)
oldact_addr = cint.peek_register(pid, cint.EDX)
ret = cint.peek_register(pid, cint.EAX)
logging.debug("This call has signum: %s", SIGNAL_INT_TO_SIG[signum])
logging.debug("New act address: 0x%x", newact_addr & 0xffffffff)
logging.debug("Old act address: 0x%x", oldact_addr & 0xffffffff)
logging.debug("Return value: %d, ret")
def rt_sigprocmask_entry_debug_printer(pid, orig_eax, syscall_object):
logging.debug('This call used command: %s',
SIGPROCMASK_INT_TO_CMD[
cint.peek_register(pid, cint.EBX)])