Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

System Call Audit #1384

Merged
merged 49 commits into from
May 16, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
0d79a21
Move unimplemented syscall logging to decorator
Mar 1, 2019
55398a5
Move unimplemented calls further down
Mar 2, 2019
0e05dd3
Add stubs for unimplemented system calls
Mar 6, 2019
6acaa7e
Move most stubs back to stub file
Mar 6, 2019
3147bdd
Merge branch 'master' into dev-syscall-audit
Mar 6, 2019
3dc02f4
Codeclimate
Mar 6, 2019
b709a69
Fix discrepancies in syscall ABI
Mar 25, 2019
a338b88
Add gettimeofday and directory handling
Mar 29, 2019
92746ee
Hacky pipe implementation
Mar 29, 2019
7536573
Better support for MSR writing
Apr 4, 2019
8fd42f1
Default to success on directory operations
Apr 15, 2019
00569a8
Codeclimate
Apr 15, 2019
84afdf0
More verbose unimplemented syscall printing
Apr 16, 2019
e5daf9d
Fix line overrun before CC calls me out
Apr 16, 2019
1349a69
Add ftruncate support
Apr 16, 2019
0841479
Add link, unlink, and nanosleep
Apr 16, 2019
901cf91
Add getdents
Apr 19, 2019
b2133ca
Add tests for mkdir and time functions
Apr 19, 2019
cac07b7
Fix codeclimate and force rebuild
Apr 25, 2019
1ff1e1a
Add pre and post hooks for syscalls
Apr 26, 2019
f0ed9d9
Merge branch 'master' into dev-syscall-audit
Apr 26, 2019
8d4e0d3
Fix lingering single quotes
Apr 26, 2019
8f9f79e
Handle dumb invocations
Apr 27, 2019
7e3c7d2
Type-o
Apr 27, 2019
25f542d
Make emulator follow logging behavior
May 6, 2019
0271688
CC
May 6, 2019
5b7049c
Fix pipe tests
May 7, 2019
ac36b12
Fix shadowed name
May 7, 2019
e8f78d1
Add test for ftruncate
May 9, 2019
57c1983
Add link tests
May 9, 2019
41135a5
Add chmod test
May 9, 2019
7221428
Rewrite docstrings
May 9, 2019
b3f814e
Replace with simple returns
May 9, 2019
5d4d35f
Strip out unique implementations
May 9, 2019
42200c3
Check that unimplemented syscalls exhibit the proper behavior
May 9, 2019
6b570b4
Merge branch 'master' into dev-syscall-audit
May 9, 2019
3bcc284
Fix missing keyword 'solver'
May 9, 2019
b8c1b87
Pass initial states to will_run callback
May 10, 2019
75784a9
Restore debug printouts after run
May 10, 2019
b05973e
Fix existing `init` calls
May 10, 2019
05e5ac7
Restore old exception behavior
May 10, 2019
b02dd81
Move save_run_data to manticore native
May 13, 2019
8e38d9b
CC
May 13, 2019
aa79b62
Refactor finalization call
May 14, 2019
e386c76
Fix save_run_data
May 15, 2019
541801c
Adjust expected output line counts
May 15, 2019
fdb74d8
CC [ci skip]
May 15, 2019
c05688a
Rename terminate state on exception to kill state
May 16, 2019
9a42527
Move time started to manticore_native
May 16, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions examples/script/aarch64/basic.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,9 @@


@m.init
def init(state):
state.platform.input.write(state.symbolicate_buffer(STDIN, label='STDIN'))
def init(m, ready_states):
for state in ready_states:
state.platform.input.write(state.symbolicate_buffer(STDIN, label='STDIN'))


# Hook the 'if' case.
Expand Down
15 changes: 4 additions & 11 deletions manticore/core/manticore.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ def newFunction(self, *args, **kw):
return newFunction

_published_events = {'run', 'start_worker', 'terminate_worker', 'enqueue_state', 'fork_state', 'load_state',
'terminate_state', 'execute_instruction'}
'terminate_state', 'kill_state', 'execute_instruction'}

def __init__(self, initial_state, workspace_url=None, policy='random', **kwargs):
"""
Expand Down Expand Up @@ -618,7 +618,7 @@ def register_plugin(self, plugin):
# Global enumeration of valid events
assert isinstance(plugin, Plugin)
assert plugin not in self.plugins, "Plugin instance already registered"
assert plugin.manticore is None, "Plugin instance already owned"
assert getattr(plugin, 'manticore', None) is None, "Plugin instance already owned"

plugin.manticore = self
self.plugins.add(plugin)
Expand Down Expand Up @@ -810,7 +810,7 @@ def run(self, timeout=None):
# User subscription to events is disabled from now on
self.subscribe = None

self._publish('will_run')
self._publish('will_run', self.ready_states)
self._running.value = True
# start all the workers!
for w in self._workers:
Expand Down Expand Up @@ -870,21 +870,14 @@ def finalize(self):
############################################################################
############################################################################

def _save_run_data(self):
def save_run_data(self):
with self._output.save_stream('command.sh') as f:
f.write(' '.join(map(shlex.quote, sys.argv)))

with self._output.save_stream('manticore.yml') as f:
config.save(f)
time_ended = time.time()

# time_elapsed = time_ended - self._last_run_stats['time_started']

logger.info('Results in %s', self._output.store.uri)
# logger.info('Total time: %s', time_elapsed)

# self._last_run_stats['time_ended'] = time_ended
# self._last_run_stats['time_elapsed'] = time_elapsed


class ManticoreSingle(ManticoreBase):
Expand Down
6 changes: 4 additions & 2 deletions manticore/core/worker.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,8 +148,8 @@ def run(self, *args):

except (Exception, AssertionError) as exc:
import traceback
traceback.print_exc()
logger.error("[%r] Exception %r. Current State %r", self.id, exc, current_state)
formatted = traceback.format_exc()
logger.error("Exception in state %r: %r\n%s ", self.id, exc, formatted)
# Internal Exception
# Add the state to the terminated state list
if current_state is not None:
Expand All @@ -158,8 +158,10 @@ def run(self, *args):
# Update the stored version of the current state
# Saved to a fresh id in case other worker have an old
# version this state cached over the old id
m._publish('will_kill_state', current_state, exc)
m._save(current_state, state_id=current_state.id)
m._kill_state(current_state.id)
m._publish('did_kill_state', current_state, exc)
current_state = None
break

Expand Down
2 changes: 1 addition & 1 deletion manticore/ethereum/manticore.py
Original file line number Diff line number Diff line change
Expand Up @@ -1478,7 +1478,7 @@ def worker_finalize(q):
global_findings_stream.write(' '.join(source_code_snippet.splitlines(True)))
global_findings_stream.write('\n')

self._save_run_data()
self.save_run_data()

with self._output.save_stream('global.summary') as global_summary:
# (accounts created by contract code are not in this list )
Expand Down
8 changes: 4 additions & 4 deletions manticore/native/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,12 @@ def native_main(args, _logger):
m.load_assertions(args.assertions)

@m.init
def init(initial_state):
def init(m, ready_states):
for file in args.files:
initial_state.platform.add_symbolic_file(file)
for state in ready_states:
state.platform.add_symbolic_file(file)

with m.kill_timeout():
m.run()

for state in m.all_states:
m.generate_testcase(state)
m.finalize()
32 changes: 23 additions & 9 deletions manticore/native/cpu/abstractcpu.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import io
import logging
import struct
import types
from functools import wraps
from itertools import islice

Expand Down Expand Up @@ -387,6 +388,14 @@ def invoke(self, model, prefix_args=None):
platform_logger = logging.getLogger('manticore.platforms.platform')


def unsigned_hexlify(i):
if type(i) is int:
if i < 0:
return hex((1 << 64) + i)
return hex(i)
return i


class SyscallAbi(Abi):
"""
A system-call specific ABI.
Expand All @@ -410,7 +419,11 @@ def invoke(self, model, prefix_args=None):
# invoke() will call get_argument_values()
self._last_arguments = ()

self._cpu._publish('will_execute_syscall', model)
ret = super().invoke(model, prefix_args)
self._cpu._publish('did_execute_syscall',
model.__func__.__name__ if isinstance(model, types.MethodType) else model.__name__,
self._last_arguments, ret)

if platform_logger.isEnabledFor(logging.DEBUG):
# Try to expand strings up to max_arg_expansion
Expand All @@ -420,22 +433,22 @@ def invoke(self, model, prefix_args=None):

args = []
for arg in self._last_arguments:
arg_s = f"0x{arg:x}"
if self._cpu.memory.access_ok(arg, 'r'):
arg_s = unsigned_hexlify(arg) if abs(arg) > min_hex_expansion else f'{arg}'
if self._cpu.memory.access_ok(arg, 'r') and \
model.__func__.__name__ not in {'sys_mprotect', 'sys_mmap'}:
try:
s = self._cpu.read_string(arg, max_arg_expansion)
arg_s = f'({s.rstrip()})' if s else arg_s
except UnicodeDecodeError:
s = s.rstrip().replace('\n', '\\n') if s else s
arg_s = (f'"{s}"' if s else arg_s)
except Exception:
pass
args.append(arg_s)

args_s = ', '.join(args)
ret_s = f'{unsigned_hexlify(ret)}' if abs(ret) > min_hex_expansion else f'{ret}'

ret_s = f'{ret}'
if ret > min_hex_expansion:
ret_s = ret_s + f'(0x{ret:x})'
platform_logger.debug('%s(%s) = %s', model.__func__.__name__, args_s, ret_s)

platform_logger.debug('%s(%s) -> %s', model.__func__.__name__, repr(args_s), ret_s)

############################################################################
# Abstract cpu encapsulating common cpu methods used by platforms and executor.
Expand All @@ -458,7 +471,8 @@ class Cpu(Eventful):
"""

_published_events = {'write_register', 'read_register', 'write_memory', 'read_memory', 'decode_instruction',
'execute_instruction', 'set_descriptor', 'map_memory', 'protect_memory', 'unmap_memory'}
'execute_instruction', 'set_descriptor', 'map_memory', 'protect_memory', 'unmap_memory',
'execute_syscall'}

def __init__(self, regfile, memory, **kwargs):
assert isinstance(regfile, RegisterFile)
Expand Down
26 changes: 26 additions & 0 deletions manticore/native/manticore.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@

import elftools
import os
import shlex
import time
import sys
from elftools.elf.elffile import ELFFile
from elftools.elf.sections import SymbolTableSection

Expand Down Expand Up @@ -276,6 +279,29 @@ def resolve(self, symbol):

raise ValueError(f"The {self.binary_path} ELFfile does not contain symbol {symbol}")

def run(self, timeout=None):
with self.locked_context() as context:
context['time_started'] = time.time()

super().run(timeout=timeout)

def finalize(self):
super().finalize()
self.save_run_data()

def save_run_data(self):
super().save_run_data()

time_ended = time.time()

with self.locked_context() as context:
time_elapsed = time_ended - context['time_started']

logger.info('Total time: %s', time_elapsed)

context['time_ended'] = time_ended
context['time_elapsed'] = time_elapsed


def _make_initial_state(binary_path, **kwargs):
with open(binary_path, 'rb') as f:
Expand Down
3 changes: 2 additions & 1 deletion manticore/native/memory.py
Original file line number Diff line number Diff line change
Expand Up @@ -380,7 +380,8 @@ def __reduce__(self):
return (self.__class__, (self.start, len(self), self.perms, self._filename, self._offset, self._overlay))

def __del__(self):
munmap(self._data, self._mapped_size)
if hasattr(self, '_data'):
munmap(self._data, self._mapped_size)

def __repr__(self):
return f'<{self.__class__.__name__} [{self._filename}+{self._offset:x}] 0x{self.start:016x}-0x{self.end:016x} {self.perms}>'
Expand Down
1 change: 0 additions & 1 deletion manticore/platforms/decree.py
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,6 @@ def BAD_ADDR(x):
assert status == 'Running'

logger.info("Setting initial cpu state")
# set initial CPU state
cpu.write_register('EAX', 0x0)
cpu.write_register('ECX', cpu.memory.mmap(CGC_PAGESTART(0x4347c000),
CGC_PAGEALIGN(4096 + CGC_PAGEOFFSET(0x4347c000)),
Expand Down
Loading