Giter VIP home page Giter VIP logo

deepstate's Introduction

DeepState

Slack Chat

DeepState is a framework that provides C and C++ developers with a common interface to various symbolic execution and fuzzing engines. Users can write one test harness using a Google Test-like API, then execute it using multiple backends without having to learn the complexities of the underlying engines. It supports writing unit tests and API sequence tests, as well as automatic test generation. Read more about the goals and design of DeepState in our paper.

The 2018 IEEE Cybersecurity Development Conference included a full tutorial on effective use of DeepState.

Table of Contents

DeepState in a Nutshell

If you want to jump right in, or are having trouble with building DeepState, you can just use a Docker that is pre-built and has compiled versions of several of the easiest examples of DeepState in use:

docker pull agroce/deepstate_examples_aflpp
docker run -it agroce/deepstate_examples_aflpp

Then within the DeepState docker container, go to an example:

cd ~/examples/fuzz_tcas
deepstate-afl ./TCAS_AFL -o fuzz_afl --fuzzer_out --timeout 120
./TCAS_cov --input_test_files_dir fuzz_afl/the_fuzzer/queue/
llvm-cov-9 gcov TCAS_driver.cpp  -b

This runs the AFL++ fuzzer on the TCAS code (https://en.wikipedia.org/wiki/Traffic_collision_avoidance_system), a long-used example program in software testing. After two minutes of fuzzing, we run a version of the test driver that collects code coverage, and see how much of the code AFL has managed to cover in two minutes.

NOTE 1: The above docker is built using AFL++ instead of AFL for "AFL" fuzzing. You can use agroce/deepstate_examples instead if for some reason you prefer "classic" AFL.

NOTE 2: You may need to modify /proc/sys/kernel/core_pattern on your host for AFL to run properly, e.g.:

echo core | sudo tee /proc/sys/kernel/core_pattern

Finally, we can look at the failing tests AFL produces:

./TCAS --input_test_files_dir fuzz_afl/the_fuzzer/crashes/ --min_log_level=0

Inspecting TCAS_driver.cpp and Makefile will give a good idea of how DeepState can be used. The other examples, including the one in the original DeepState blog post, are similar in structure and usage.

Articles describing DeepState

Overview of Features

  • Tests look like Google Test, but can use symbolic execution/fuzzing to generate data (parameterized unit testing)
    • Easier to learn than binary analysis tools/fuzzers, but provides similar functionality
  • Already supports Manticore, Angr, libFuzzer, file-based fuzzing with e.g., AFL or Eclipser; more back-ends likely in future
    • Switch test generation tool without re-writing test harness
      • Work around show-stopper bugs
      • Find out which tool works best for your code under test
      • Different tools find different bugs/vulnerabilities
      • Fair way to benchmark/bakeoff tools
  • Provides test replay for regression plus effective automatic test case reduction to aid debugging
  • Supports API-sequence generation with extensions to Google Test interface
    • Concise readable way (OneOf) to say "run one of these blocks of code"
    • Same construct supports fixed value set non-determinism
    • E.g., writing a POSIX file system tester is pleasant, not painful as in pure Google Test idioms
  • Provides high-level strategies for improving symbolic execution/fuzzing effectiveness
    • Pumping (novel to DeepState) to pick concrete values when symbolic execution is too expensive
    • Automatic decomposition of integer compares to guide coverage-driven fuzzers
    • Strong support for automated swarm testing

To put it another way, DeepState sits at the intersection of property-based testing, traditional unit testing, fuzzing, and symbolic execution. It lets you perform property-based unit testing using fuzzing or symbolic execution as a back end to generate data, and saves the results so that what DeepState finds can easily be used in deterministic settings such as regression testing or CI.

Build'n'run

Supported Platforms

DeepState currently targets Linux, Windows, with macOS support in progress (the fuzzers work fine, but symbolic execution is not well-supported yet, without a painful cross-compilation process). No current support for ARM64 architecture, this includes Apple Silicon processors, as there is no support for multilib compilers.

Dependencies

Build:

  • CMake
  • GCC and G++ with multilib support
  • Python 3.6 (or newer)
  • Setuptools

Runtime:

  • Python 3.6 (or newer)
  • Z3 (for the Manticore backend)

Building on Ubuntu 18.04 (Bionic)

First make sure you install Python 3.6 or greater. Then use this command line to install additional requirements and compile DeepState:

Building Deepstate

sudo apt update && sudo apt-get install build-essential gcc-multilib g++-multilib cmake python3-setuptools python3-dev libffi-dev z3
sudo apt-add-repository ppa:sri-csl/formal-methods
sudo apt-get update
sudo apt-get install yices2
git clone https://github.com/trailofbits/deepstate deepstate
mkdir deepstate/build && cd deepstate/build
cmake ../
make
sudo make install

Changing file permissions

cd deepstate
sudo chmod -R 755 .
sudo chown -R username:groupname .

Installing Dependencies on Ubuntu if issues arise

CMake:

sudo apt install cmake

GCC & G++ with multilib support:

sudo apt-get install gcc-multilib
sudo apt-get install g++-multilib

Installing the latest version of Python via CLI:

sudo apt-get update && sudo apt upgrade
sudo apt install wget build-essential libncursesw5-dev libssl-dev \
libsqlite3-dev tk-dev libgdbm-dev libc6-dev libbz2-dev libffi-dev zlib1g-dev
sudo add-apt-repository ppa:deadsnakes/ppa
sudo apt install python3.11

Setup Tools:

Skip the first command below if pip is already installed.

sudo apt install python3-pip
pip3 install setuptools

Z3:

sudo apt install z3

Building on Windows 10

If you want to compile DeepState on Windows make sure to install MinGW with MSYS2 by following the installation instructions. After the installation is finished, select an environment and launch that version of the environment from the Windows programs menu(if in doubt, choose MINGW64 or UCRT64). Then, use the command below to install all of your environment's dependencies and compile DeepState:

pacman -Syyu
pacman -S mingw-w64-x86_64-python3 mingw-w64-x86_64-python-setuptools mingw-w64-x86_64-gcc mingw-w64-x86_64-cmake mingw-w64-x86_64-libffi mingw-w64-x86_64-make
pacman -S make git

git clone https://github.com/trailofbits/deepstate deepstate
mkdir deepstate/build && cd deepstate/build
cmake -G "Unix Makefiles" ../
make
make install

NOTE: If you decide to use UCRT64, keep in mind to change x86_64 to ucrt-x86_64 in the second pacman command, i.e. mingw-w64-x86_64-python3 gets replaced with mingw-w64-ucrt-x86_64-python3.

Installing

Assuming the DeepState build resides in $DEEPSTATE, run the following commands to install the DeepState python package:

virtualenv venv
. venv/bin/activate
python $DEEPSTATE/build/setup.py install

The virtualenv-enabled $PATH should now include two executables: deepstate and deepstate-angr. These are executors, which are used to run DeepState test binaries with specific backends (automatically installed as Python dependencies). The deepstate or deepstate-manticore executor uses the Manticore backend while deepstate-angr uses angr. They share a common interface where you may specify a number of workers and an output directory for saving backend-generated test cases.

If you try using Manticore, and it doesn't work, but you definitely have the latest Manticore installed, check the .travis.yml file. If that grabs a Manticore other than the master version, you can try using the version of Manticore we use in our CI tests. Sometimes Manticore makes a breaking change, and we are behind for a short time.

Installation testing

You can check your build using the test binaries that were (by default) built and emitted to deepstate/build/examples. For example, to use angr to symbolically execute the IntegerOverflow test harness with 4 workers, saving generated test cases in a directory called out, you would invoke:

deepstate-angr --num_workers 4 --output_test_dir out $DEEPSTATE/build/examples/IntegerOverflow

The resulting out directory should look something like:

out
└── IntegerOverflow.cpp
   ├── SignedInteger_AdditionOverflow
   │   ├── a512f8ffb2c1bb775a9779ec60b699cb.fail
   │   └── f1d3ff8443297732862df21dc4e57262.pass
   └── SignedInteger_MultiplicationOverflow
       ├── 6a1a90442b4d898cb3fac2800fef5baf.fail
       └── f1d3ff8443297732862df21dc4e57262.pass

To run these tests, you can just use the native executable, e.g.:

$DEEPSTATE/build/examples/IntegerOverflow --input_test_dir out

to run all the generated tests, or

$DEEPSTATE/build/examples/IntegerOverflow --input_test_files_dir out/IntegerOverflow.cpp/SignedInteger_AdditionOverflow --input_which_test SignedInteger_AdditionOverflow

to run the tests in one directory (in this case, you want to specify which test to run, also). You can also run a single test, e.g.:

$DEEPSTATE/build/examples/IntegerOverflow --input_test_file out/IntegerOverflow.cpp/SignedInteger_AdditionOverflow/a512f8ffb2c1bb775a9779ec60b699cb.fail--input_which_test SignedInteger_AdditionOverflow

In the absence of an --input_which_test argument, DeepState defaults to the first-defined test. Run the native executable with the --help argument to see all DeepState options.

Docker

You can also try out Deepstate with Docker, which is the easiest way to get all the fuzzers and tools up and running on any system.

The build may take about 40 minutes, because some fuzzers require us building huge projects like QEMU or LLVM.

Ensure that docker is installed:

  • Check out the docker website here for installation instructions.

Check if docker is installed correctly:

docker run hello-world

Run these commands to install deepstate via docker:

git clone https://github.com/trailofbits/deepstate deepstate
$ cd deepstate
$ docker build -t deepstate-base -f docker/base/Dockerfile docker/base
$ docker build -t deepstate --build-arg make_j=6 -f ./docker/Dockerfile .
$ docker run -it deepstate bash
user@a17bc44fd259:~/deepstate$ cd build/examples
user@a17bc44fd259:~/deepstate/build/examples$ deepstate-angr ./Runlen
user@a17bc44fd259:~/deepstate/build/examples$ mkdir tmp && deepstate-eclipser ./Runlen -o tmp --timeout 30
user@a17bc44fd259:~/deepstate/build/examples$ cd ../../build_libfuzzer/examples
user@a17bc44fd259:~/deepstate/build_libfuzzer/examples$ ./Runlen_LF -max_total_time=30
user@a17bc44fd259:~/deepstate/build_libfuzzer/examples$ cd ../../build_afl/examples
user@a17bc44fd259:~/deepstate/build_afl/examples$ mkdir foo && echo x > foo/x && mkdir afl_Runlen2
user@a17bc44fd259:~/deepstate/build_afl/examples$ $AFL_HOME/afl-fuzz -i foo -o afl_Runlen -- ./Runlen_AFL --input_test_file @@ --no_fork --abort_on_fail
user@a17bc44fd259:~/deepstate/build_afl/examples$ deepstate-afl -o afl_Runlen2 ./Runlen_AFL --fuzzer_out

How to use docker without sudo:

sudo groupadd docker
sudo gpasswd -a $USER docker
newgrp docker

If this error occurs:

ERROR: Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?

Run this command:

systemctl start docker

Documentation

Check out docs folder:

External Tools

DeepState can be used to test R packages written using the popular Rcpp package. The Rcppdeepstate tool is described in a paper presented at the 2021 IEEE International Symposium on Software Reliability Engineering.

Contributing

All accepted PRs are awarded bounties by Trail of Bits. Join the #deepstate channel on the Empire Hacking Slack to discuss ongoing development and claim bounties. Check the good first issue label for suggested contributions.

Trophy case

We have not yet applied DeepState to many targets, but it was responsible for finding the following confirmed bugs (serious faults are in bold):

License

DeepState is released under The Apache License 2.0.

deepstate's People

Contributors

aaron-junot avatar agroce avatar artemdinaburg avatar arunjohnkuruvilla avatar bostick avatar dguido avatar disconnect3d avatar fabriziosandri avatar ggrieco-tob avatar grosquildu avatar jscriven-digimarc avatar khorben avatar kosak avatar oldsj avatar pgoodman avatar ranweiler avatar shaynesellner avatar val06 avatar withzombies avatar woodruffw avatar yan avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

deepstate's Issues

Sort test cases by file name and line number before running them natively

It's helpful to run the test cases in a "logical" order. The order in which they are registered with DeepState is technically undefined, though one can expect it to be in reverse order of the appearance of the tests in the file, with the ordering across files as unspecified.

The Python symbolic executors sort tests before running them, which means that if only one process worker (the default) is used to run the test suite then that process then the ordering will look sane.

Add features to native test harness

Besides reading input from a directory as described in #3, how else can we enhance the native test harness? What is actually worth implementing?

Ideas:

  • Report discrepant runs of test input that has an implied expected outcome. For example, when replaying a test case with a suffix like .pass, but a failure is observed, flag and report to the user.
  • Permit passing individual test cases files directly, with desired test name, rather than just accepting an input directory.
  • Consider other kinds of structured test run reporting.
  • Add a flag that only runs tests whose name matches an expression.

Manticore crashes

Running DeepState's Manticore program raises several exception which shouldn't happen. One of the problems is somehow related to storing symbols in the globals dictionary, and perhaps improper deep copying of these values. If the usage is actually improper then my use case deserves a "gotcha" message on Manticore's docs.

pag@sloth:~/Code/deepstate/build$ deepstate ./examples/IntegerArtihmetic 
2017-11-06 13:57:48,362: [28658] m.manticore:INFO: Starting 1 processes.
2017-11-06 14:02:35,897: [28658] m.c.c.x86:WARNING: CPUID with EAX=80000000 not implemented @ 7fffff821c18
2017-11-06 14:02:45,696: [28658] deepstate.mcore:INFO: Running 3 tests across 1 workers
2017-11-06 14:02:45,970: [29017] m.manticore:INFO: Starting 1 processes.
2017-11-06 14:02:47,020: [29017] m.c.executor:ERROR: Exception: Error in smtlib: (error "line 377 column 43: invalid declaration, constant 'DEEP_INPUT_0_2' (with the given signature) already declared")

Traceback (most recent call last):
  File "/usr/local/lib/python2.7/dist-packages/manticore-0.1.5-py2.7.egg/manticore/core/executor.py", line 476, in run
    self._publish('will_terminate_state', current_state, current_state_id, e)
  File "/usr/local/lib/python2.7/dist-packages/manticore-0.1.5-py2.7.egg/manticore/utils/event.py", line 119, in _publish
    self._publish_impl(_name, *args, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/manticore-0.1.5-py2.7.egg/manticore/utils/event.py", line 135, in _publish_impl
    sink._publish_impl(_name, *args, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/manticore-0.1.5-py2.7.egg/manticore/utils/event.py", line 127, in _publish_impl
    callback(robj(), *args, **kwargs)
  File "build/bdist.linux-x86_64/egg/deepstate/main_manticore.py", line 218, in done_test
    mc.report()
  File "build/bdist.linux-x86_64/egg/deepstate/common.py", line 345, in report
    b = self.concretize(symbols[i], constrain=True)
  File "build/bdist.linux-x86_64/egg/deepstate/main_manticore.py", line 91, in concretize
    concrete_val = self.state.solve_one(val)
  File "/usr/local/lib/python2.7/dist-packages/manticore-0.1.5-py2.7.egg/manticore/core/state.py", line 309, in solve_one
    return self._solver.get_value(self._constraints, expr)
  File "/usr/local/lib/python2.7/dist-packages/manticore-0.1.5-py2.7.egg/manticore/core/smtlib/solver.py", line 490, in get_value
    if self._check() != 'sat':
  File "/usr/local/lib/python2.7/dist-packages/manticore-0.1.5-py2.7.egg/manticore/core/smtlib/solver.py", line 262, in _check
    _status = self._recv()
  File "/usr/local/lib/python2.7/dist-packages/manticore-0.1.5-py2.7.egg/manticore/core/smtlib/solver.py", line 253, in _recv
    raise Exception("Error in smtlib: {}".format(bufl[0]))
Exception: Error in smtlib: (error "line 377 column 43: invalid declaration, constant 'DEEP_INPUT_0_2' (with the given signature) already declared")


Exception: Error in smtlib: (error "line 377 column 43: invalid declaration, constant 'DEEP_INPUT_0_2' (with the given signature) already declared")

Traceback (most recent call last):
  File "/usr/local/lib/python2.7/dist-packages/manticore-0.1.5-py2.7.egg/manticore/core/executor.py", line 476, in run
    self._publish('will_terminate_state', current_state, current_state_id, e)
  File "/usr/local/lib/python2.7/dist-packages/manticore-0.1.5-py2.7.egg/manticore/utils/event.py", line 119, in _publish
    self._publish_impl(_name, *args, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/manticore-0.1.5-py2.7.egg/manticore/utils/event.py", line 135, in _publish_impl
    sink._publish_impl(_name, *args, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/manticore-0.1.5-py2.7.egg/manticore/utils/event.py", line 127, in _publish_impl
    callback(robj(), *args, **kwargs)
  File "build/bdist.linux-x86_64/egg/deepstate/main_manticore.py", line 218, in done_test
    mc.report()
  File "build/bdist.linux-x86_64/egg/deepstate/common.py", line 345, in report
    b = self.concretize(symbols[i], constrain=True)
  File "build/bdist.linux-x86_64/egg/deepstate/main_manticore.py", line 91, in concretize
    concrete_val = self.state.solve_one(val)
  File "/usr/local/lib/python2.7/dist-packages/manticore-0.1.5-py2.7.egg/manticore/core/state.py", line 309, in solve_one
    return self._solver.get_value(self._constraints, expr)
  File "/usr/local/lib/python2.7/dist-packages/manticore-0.1.5-py2.7.egg/manticore/core/smtlib/solver.py", line 490, in get_value
    if self._check() != 'sat':
  File "/usr/local/lib/python2.7/dist-packages/manticore-0.1.5-py2.7.egg/manticore/core/smtlib/solver.py", line 262, in _check
    _status = self._recv()
  File "/usr/local/lib/python2.7/dist-packages/manticore-0.1.5-py2.7.egg/manticore/core/smtlib/solver.py", line 253, in _recv
    raise Exception("Error in smtlib: {}".format(bufl[0]))
Exception: Error in smtlib: (error "line 377 column 43: invalid declaration, constant 'DEEP_INPUT_0_2' (with the given signature) already declared")


2017-11-06 14:02:47,021: [29017] deepstate.mcore:ERROR: State 2 terminated for unknown reason: Error in smtlib: (error "line 377 column 43: invalid declaration, constant 'DEEP_INPUT_0_2' (with the given signature) already declared")

2017-11-06 14:02:47,023: [29017] m.manticore:INFO: Results in /home/pag/Code/deepstate/build/mcore_7mKg5l
2017-11-06 14:02:47,023: [29017] m.manticore:INFO: Total time: 1.052973032
2017-11-06 14:02:47,345: [29017] m.manticore:INFO: Starting 1 processes.
2017-11-06 14:02:47,530: [29017] m.c.executor:ERROR: Exception: 
Traceback (most recent call last):
  File "/usr/local/lib/python2.7/dist-packages/manticore-0.1.5-py2.7.egg/manticore/core/executor.py", line 471, in run
    self.fork(current_state, e.expression, e.policy, e.setstate)
  File "/usr/local/lib/python2.7/dist-packages/manticore-0.1.5-py2.7.egg/manticore/core/executor.py", line 381, in fork
    solutions = state.concretize(expression, policy)
  File "/usr/local/lib/python2.7/dist-packages/manticore-0.1.5-py2.7.egg/manticore/core/state.py", line 291, in concretize
    silent=False)
  File "/usr/local/lib/python2.7/dist-packages/manticore-0.1.5-py2.7.egg/manticore/core/smtlib/solver.py", line 354, in get_all_values
    value = self._getvalue(var)
  File "/usr/local/lib/python2.7/dist-packages/manticore-0.1.5-py2.7.egg/manticore/core/smtlib/solver.py", line 293, in _getvalue
    assert ret.startswith('((') and ret.endswith('))')
AssertionError

Exception: 
Traceback (most recent call last):
  File "/usr/local/lib/python2.7/dist-packages/manticore-0.1.5-py2.7.egg/manticore/core/executor.py", line 471, in run
    self.fork(current_state, e.expression, e.policy, e.setstate)
  File "/usr/local/lib/python2.7/dist-packages/manticore-0.1.5-py2.7.egg/manticore/core/executor.py", line 381, in fork
    solutions = state.concretize(expression, policy)
  File "/usr/local/lib/python2.7/dist-packages/manticore-0.1.5-py2.7.egg/manticore/core/state.py", line 291, in concretize
    silent=False)
  File "/usr/local/lib/python2.7/dist-packages/manticore-0.1.5-py2.7.egg/manticore/core/smtlib/solver.py", line 354, in get_all_values
    value = self._getvalue(var)
  File "/usr/local/lib/python2.7/dist-packages/manticore-0.1.5-py2.7.egg/manticore/core/smtlib/solver.py", line 293, in _getvalue
    assert ret.startswith('((') and ret.endswith('))')
AssertionError

2017-11-06 14:02:47,531: [29017] deepstate.mcore:ERROR: State 0 terminated for unknown reason: 
2017-11-06 14:02:47,532: [29017] m.manticore:INFO: Results in /home/pag/Code/deepstate/build/mcore_yUsodU
2017-11-06 14:02:47,532: [29017] m.manticore:INFO: Total time: 0.187195062637
2017-11-06 14:02:47,790: [29017] m.manticore:INFO: Starting 1 processes.
2017-11-06 14:02:47,952: [29017] m.c.executor:ERROR: Exception: ((V_8194 #x0000000000402040))
Traceback (most recent call last):
  File "/usr/local/lib/python2.7/dist-packages/manticore-0.1.5-py2.7.egg/manticore/core/executor.py", line 471, in run
    self.fork(current_state, e.expression, e.policy, e.setstate)
  File "/usr/local/lib/python2.7/dist-packages/manticore-0.1.5-py2.7.egg/manticore/core/executor.py", line 381, in fork
    solutions = state.concretize(expression, policy)
  File "/usr/local/lib/python2.7/dist-packages/manticore-0.1.5-py2.7.egg/manticore/core/state.py", line 291, in concretize
    silent=False)
  File "/usr/local/lib/python2.7/dist-packages/manticore-0.1.5-py2.7.egg/manticore/core/smtlib/solver.py", line 353, in get_all_values
    while self._check() == 'sat':
  File "/usr/local/lib/python2.7/dist-packages/manticore-0.1.5-py2.7.egg/manticore/core/smtlib/solver.py", line 265, in _check
    raise SolverException(_status)
SolverException: ((V_8194 #x0000000000402040))

Exception: ((V_8194 #x0000000000402040))
Traceback (most recent call last):
  File "/usr/local/lib/python2.7/dist-packages/manticore-0.1.5-py2.7.egg/manticore/core/executor.py", line 471, in run
    self.fork(current_state, e.expression, e.policy, e.setstate)
  File "/usr/local/lib/python2.7/dist-packages/manticore-0.1.5-py2.7.egg/manticore/core/executor.py", line 381, in fork
    solutions = state.concretize(expression, policy)
  File "/usr/local/lib/python2.7/dist-packages/manticore-0.1.5-py2.7.egg/manticore/core/state.py", line 291, in concretize
    silent=False)
  File "/usr/local/lib/python2.7/dist-packages/manticore-0.1.5-py2.7.egg/manticore/core/smtlib/solver.py", line 353, in get_all_values
    while self._check() == 'sat':
  File "/usr/local/lib/python2.7/dist-packages/manticore-0.1.5-py2.7.egg/manticore/core/smtlib/solver.py", line 265, in _check
    raise SolverException(_status)
SolverException: ((V_8194 #x0000000000402040))

2017-11-06 14:02:47,952: [29017] deepstate.mcore:ERROR: State 0 terminated for unknown reason: ((V_8194 #x0000000000402040))
2017-11-06 14:02:47,953: [29017] m.manticore:INFO: Results in /home/pag/Code/deepstate/build/mcore_BkGWlh
2017-11-06 14:02:47,953: [29017] m.manticore:INFO: Total time: 0.162762880325

Make repo public

We in theory said the repo/tool would be public by BAR. Any chance we can do that?

Improve specificity of Manticore executor's crash detection

Right now, when detecting and saving crashes using the Manticore executor, if a state exploration was terminated by something other than a DeepState API hook, we call it a crash.

For example, if a Manticore SolverException caused us to stop exploring a state, then in the DeepState executor, that would be saved as a .crash file. Instead, we might prefer to only call a termination a crash if it were due to an exception of some special set of types (like InvalidMemoryAccess), and otherwise call the termination "abandoned", or something else.

There may already be a nice way to accomplish this with the existing Manticore API, or it may require some additional work in Manticore.

Fail informatively when Z3 not installed

If the user tries to merely run deepstate -h without having z3 installed, the Manticore backend throws an uncaught Z3NotFoundError. Instead, catch it, report the problem to the user, then exit cleanly with an error.

Manticore internal error

Running Klee and TakeOver examples causes an internal manticore error to be raised:

ERROR:deepstate.mcore:State 3 terminated due to internal error: Program finished with exit status: -1
INFO:deepstate:Running _takeover_test from _takeover_file(0)
INFO:deepstate:negative
INFO:deepstate:Input: 00 00 00 80
2018-07-14 13:49:25,730: [7597] m.manticore:INFO: Generated testcase No. 0 - Program finished with exit status: -1
ERROR:deepstate.mcore:State 4 terminated due to internal error: Program finished with exit status: 1
INFO:deepstate:Running _takeover_test from _takeover_file(0)
INFO:deepstate:positive
INFO:deepstate:Input: 00 00 00 01
2018-07-14 13:51:42,394: [7597] m.manticore:INFO: Generated testcase No. 1 - Program finished with exit status: 1
ERROR:deepstate.mcore:State 1 terminated due to internal error: Program finished with exit status: 0 (*)
INFO:deepstate:Running _takeover_test from _takeover_file(0)
INFO:deepstate:zero
INFO:deepstate:Input: 00 00 00 00
2018-07-14 13:53:48,869: [7597] m.manticore:INFO: Generated testcase No. 2 - Program finished with exit status: 0 (*)
2018-07-14 13:53:48,872: [7597] m.manticore:INFO: Results in /home/travis/build/trailofbits/deepstate/mcore_W5nsO9
2018-07-14 13:53:48,872: [7597] m.manticore:INFO: Total time: 363.605963945
2018-07-14 13:56:07,403: [7597] m.manticore:INFO: Generated testcase No. 0 - Program finished with exit status: 0
2018-07-14 13:58:41,037: [7597] m.manticore:INFO: Generated testcase No. 1 - Program finished with exit status: 1
2018-07-14 14:01:10,368: [7597] m.manticore:INFO: Generated testcase No. 2 - Program finished with exit status: -1
2018-07-14 14:01:10,371: [7597] m.manticore:INFO: Results in /home/travis/build/trailofbits/deepstate/mcore_2TWnqH
2018-07-14 14:01:10,372: [7597] m.manticore:INFO: Total time: 810.348953962

Right now, the tests flag this as a failure (since they flag any run that produces an internal error or throws an exception, even if it otherwise terminates with 0 exit code and produces correct results). Is this expected behavior?

Add explicit symbolic floating point support

Right now, we have some functions that check for symbolic floating-point values, such as DeepState_IsSymbolicFloat(). But, other than using DeepState_SymbolizeData() with the addr of a floating-point variable, we don't have any way to construct symbolic float/double values via the DeepState API.

DeepAngr in main_manticore?

I see a couple of references while looking at the code (to get started on some bigger enhancements) to DeepAngr in main_manticore. These look just wrong, copy/paste?

manticore failure on testfs example

Build https://github.com/agroce/testfs and run

> deepstate-manticore ./Tests 
INFO:deepstate.mcore:Running 1 tests across 1 workers
INFO:deepstate:Running TestFs_FilesDirs from /root/testfs/Tests.cpp(84)
INFO:deepstate:/root/testfs/RamInterface.cpp(149): Making super block
INFO:deepstate:/root/testfs/RamInterface.cpp(152): Making inode free map
INFO:deepstate:/root/testfs/RamInterface.cpp(155): Making block free map
INFO:deepstate:/root/testfs/RamInterface.cpp(158): Making checksum table
INFO:deepstate:/root/testfs/RamInterface.cpp(161): Making inode blocks
INFO:deepstate:/root/testfs/RamInterface.cpp(165): Done creating empty file system.
INFO:deepstate:/root/testfs/RamInterface.cpp(174): Created root directory; File system initialized
INFO:deepstate:nr of allocated inodes = 1

INFO:deepstate:nr of allocated blocks = 1

INFO:deepstate:PATH 0: foo

INFO:deepstate:NAME: foo

INFO:deepstate:nr of allocated inodes = 2

INFO:deepstate:nr of allocated blocks = 2

INFO:deepstate:PATH 0: foo

INFO:deepstate:PATH 1: foo

INFO:deepstate:NAME: foo

INFO:deepstate:nr of allocated inodes = 2

INFO:deepstate:nr of allocated blocks = 2

INFO:deepstate:Input: 00 00 00 06
2018-07-18 04:25:38,593: [18760] m.c.executor:ERROR: Exception: 
Traceback (most recent call last):
  File "/root/.local/lib/python2.7/site-packages/manticore-0.1.10-py2.7.egg/manticore/core/executor.py", line 461, in run
    if not current_state.execute():
  File "/root/.local/lib/python2.7/site-packages/manticore-0.1.10-py2.7.egg/manticore/core/state.py", line 127, in execute
    result = self._platform.execute()
  File "/root/.local/lib/python2.7/site-packages/manticore-0.1.10-py2.7.egg/manticore/platforms/linux.py", line 2216, in execute
    self.current.execute()
  File "/root/.local/lib/python2.7/site-packages/manticore-0.1.10-py2.7.egg/manticore/core/cpu/abstractcpu.py", line 839, in execute
    implementation(*insn.operands)
  File "/root/.local/lib/python2.7/site-packages/manticore-0.1.10-py2.7.egg/manticore/core/cpu/abstractcpu.py", line 937, in new_method
    return old_method(cpu, *args, **kw_args)
  File "/root/.local/lib/python2.7/site-packages/manticore-0.1.10-py2.7.egg/manticore/core/cpu/x86.py", line 5185, in MOVZX
    op0.write(Operators.ZEXTEND(op1.read(), op0.size))
  File "/root/.local/lib/python2.7/site-packages/manticore-0.1.10-py2.7.egg/manticore/core/cpu/x86.py", line 662, in read
    value = cpu.read_int(self.address(), self.size)
  File "/root/.local/lib/python2.7/site-packages/manticore-0.1.10-py2.7.egg/manticore/core/cpu/abstractcpu.py", line 606, in read_int
    data = self._memory.read(where, size / 8, force)
  File "/root/.local/lib/python2.7/site-packages/manticore-0.1.10-py2.7.egg/manticore/core/memory.py", line 931, in read
    assert solver.check(self.constraints)
AssertionError

ERROR:deepstate.mcore:State 6 terminated due to internal error: 
ERROR:deepstate.mcore:Uncaught exception: <class 'manticore.core.smtlib.solver.SolverException'>
Traceback (most recent call last):
  File "build/bdist.linux-x86_64/egg/deepstate/main_manticore.py", line 348, in run_test
    do_run_test(state, apis, test, hook_test)
  File "build/bdist.linux-x86_64/egg/deepstate/main_manticore.py", line 343, in do_run_test
    m.run()
  File "/root/.local/lib/python2.7/site-packages/manticore-0.1.10-py2.7.egg/manticore/manticore.py", line 638, in run
    self._start_workers(procs, profiling=should_profile)
  File "/root/.local/lib/python2.7/site-packages/manticore-0.1.10-py2.7.egg/manticore/manticore.py", line 419, in _start_workers
    target()
  File "/root/.local/lib/python2.7/site-packages/manticore-0.1.10-py2.7.egg/manticore/core/executor.py", line 503, in run
    self._publish('will_terminate_state', current_state, current_state_id, e)
  File "/root/.local/lib/python2.7/site-packages/manticore-0.1.10-py2.7.egg/manticore/utils/event.py", line 118, in _publish
    self._publish_impl(_name, *args, **kwargs)
  File "/root/.local/lib/python2.7/site-packages/manticore-0.1.10-py2.7.egg/manticore/utils/event.py", line 134, in _publish_impl
    sink._publish_impl(_name, *args, **kwargs)
  File "/root/.local/lib/python2.7/site-packages/manticore-0.1.10-py2.7.egg/manticore/utils/event.py", line 126, in _publish_impl
    callback(robj(), *args, **kwargs)
  File "build/bdist.linux-x86_64/egg/deepstate/main_manticore.py", line 291, in done_test
    mc.report()
  File "build/bdist.linux-x86_64/egg/deepstate/common.py", line 370, in report
    b = self.concretize_min(symbols[i], constrain=True)
  File "build/bdist.linux-x86_64/egg/deepstate/main_manticore.py", line 109, in concretize_min
    concrete_val = min(self.state.concretize(val, policy='MINMAX'))
  File "/root/.local/lib/python2.7/site-packages/manticore-0.1.10-py2.7.egg/manticore/core/state.py", line 277, in concretize
    vals = self._solver.minmax(self._constraints, symbolic)
  File "/root/.local/lib/python2.7/site-packages/manticore-0.1.10-py2.7.egg/manticore/core/smtlib/solver.py", line 107, in minmax
    m = self.min(constraints, x, iters)
  File "/root/.local/lib/python2.7/site-packages/manticore-0.1.10-py2.7.egg/manticore/core/smtlib/solver.py", line 102, in min
    return self.optimize(constraints, X, 'minimize')
  File "/root/.local/lib/python2.7/site-packages/manticore-0.1.10-py2.7.egg/manticore/core/smtlib/solver.py", line 444, in optimize
    raise SolverException("Optimizing error, unsat or unknown core")
SolverException: Optimizing error, unsat or unknown core

Add a DeepState_TakeOver API that treats the rest of the program as a test case

One use case that @artemdinaburg raised was that he'd like to be able to introduce symbols into an existing program execution. Right now DeepState is very unit test focused -- i.e. run to DeepState_Run, then change control to one of the unit test case entry-points. Ideally we'd like to be able to treat the "rest of the program" as the test case, and basically get to use the DeepState API.

This means changing DeepState's behaviour slighty:

  • If execution reaches DeepState_Run, then it will go and look for all the test cases.
  • If execution reaches DeepState_TakeOver then we add some fake TestInfo structure (or maybe DeepState_TakeOver is a macro that calls a lower level function and passes in an initialized struct DeepState_TestInfo), then return 1 when under symbolic execution (by being hooked) and 0 by default in a native execution.

Add basic documentation

  • Add top-level README
  • Document requirements (e.g. Python 2, not 3, multilib)
  • Build and installation, instructions (start with Ubuntu)
  • Usage with examples

Packaging

Let's find a way to avoid having every user build DeepState from scratch

Investigate performance of Manticore executor

The Manticore executor (currently the default) seems very slow compared to the angr executor, and slower than what I'd expect from Manticore generally. Is our executor implementation doing anything degenerate? If we can't do any better with Manticore as-is, are there upstream changes that would enable us to improve perf?

Compare the below (representative) runs against the IntegerOverflow example binary, which uses the DeepState unit test API.

Manticore executor:

$ time deepstate --output_test_dir=out examples/IntegerOverflow
...
real    16m33.590s
user    16m3.426s
sys     0m22.298s

angr executor:

$ time deepstate-angr --output_test_dir=out examples/IntegerOverflow
...
real    0m13.395s
user    0m13.360s
sys     0m0.246s

Add a usage guide

Most of the documentation focuses only on building and installing the library rather than how to write, run, and review tests.

Have native test harness able to read in auto-generated tests from a directory

The symbolic executors can spit out their solved tests to the --output_test_dir. For example:

pag@sloth:~/Code/deepstate/build$ deepstate-angr --output_test_dir /tmp/tests ./examples/IntegerOverflow
...
pag@sloth:~/Code/deepstate/build$ tree /tmp/tests/
/tmp/tests/
└── IntegerOverflow.cpp
    ├── SignedInteger_AdditionOverflow
    │   ├── a512f8ffb2c1bb775a9779ec60b699cb.fail
    │   └── f1d3ff8443297732862df21dc4e57262.pass
    └── SignedInteger_MultiplicationOverflow
        ├── 2654dd0d212652c13a36c471a19128aa.pass
        └── 941dd7c70fe9d411004aede4018fe446.fail

Individual files are stored in <output_test_dir>/<test case file base name>/<test name>/<hash of file contents>.<pass,fail,crash>.

Reading in generated tests case input files requires matching the file base names and the test names against the files. Perhaps we don't really need to match the file base names and we can just match up the test names against the test directory names.

One question is how to specify the actual test directory to the native version of the test suite. I might need to port a simple command-line argument parser that I have to DeepState for that, then we can also add things like --log_level, tell it where to log to, etc.

angr exception raised

Build https://github.com/agroce/testfs and run

deepstate-angr ./Tests

on Ubuntu, and it produces some reasonable output but also:

WARNING | 2018-07-18 01:28:47,394 | angr.analyses.disassembly_utils | Your version of capstone does not support MIPS instruction groups.
INFO    | 2018-07-18 01:29:49,446 | deepstate.angr | Running 1 tests across 1 workers
ERROR   | 2018-07-18 02:17:38,675 | deepstate.angr | Uncaught exception: 
Traceback (most recent call last):
  File "build/bdist.linux-x86_64/egg/deepstate/main_angr.py", line 290, in do_run_test
    test_manager.run()
  File "/root/.local/lib/python2.7/site-packages/angr-7.8.7.1-py2.7.egg/angr/misc/immutability.py", line 24, in _wrapper
    if method(self, *args, **kwargs) is not self:
  File "/root/.local/lib/python2.7/site-packages/angr-7.8.7.1-py2.7.egg/angr/sim_manager.py", line 260, in run
    self.step(stash=stash, **kwargs)
  File "/root/.local/lib/python2.7/site-packages/angr-7.8.7.1-py2.7.egg/angr/misc/immutability.py", line 24, in _wrapper
    if method(self, *args, **kwargs) is not self:
  File "/root/.local/lib/python2.7/site-packages/angr-7.8.7.1-py2.7.egg/angr/sim_manager.py", line 341, in step
    successors = self.step_state(state, successor_func, **run_args)
  File "/root/.local/lib/python2.7/site-packages/angr-7.8.7.1-py2.7.egg/angr/sim_manager.py", line 362, in step_state
    successors = self.successors(state, successor_func, **run_args)
  File "/root/.local/lib/python2.7/site-packages/angr-7.8.7.1-py2.7.egg/angr/sim_manager.py", line 401, in successors
    return self._project.factory.successors(state, **run_args)
  File "/root/.local/lib/python2.7/site-packages/angr-7.8.7.1-py2.7.egg/angr/factory.py", line 61, in successors
    return self.project.engines.successors(*args, **kwargs)
  File "/root/.local/lib/python2.7/site-packages/angr-7.8.7.1-py2.7.egg/angr/engines/hub.py", line 128, in successors
    r = engine.process(state, **kwargs)
  File "/root/.local/lib/python2.7/site-packages/angr-7.8.7.1-py2.7.egg/angr/engines/hook.py", line 51, in process
    return self.project.factory.procedure_engine.process(state, procedure, force_addr=force_addr, **kwargs)
  File "/root/.local/lib/python2.7/site-packages/angr-7.8.7.1-py2.7.egg/angr/engines/procedure.py", line 31, in process
    force_addr=force_addr)
  File "/root/.local/lib/python2.7/site-packages/angr-7.8.7.1-py2.7.egg/angr/engines/engine.py", line 55, in process
    self._process(new_state, successors, *args, **kwargs)
  File "/root/.local/lib/python2.7/site-packages/angr-7.8.7.1-py2.7.egg/angr/engines/procedure.py", line 65, in _process
    inst = procedure.execute(state, successors, ret_to=ret_to)
  File "/root/.local/lib/python2.7/site-packages/angr-7.8.7.1-py2.7.egg/angr/sim_procedure.py", line 169, in execute
    r = getattr(inst, inst.run_func)(*sim_args, **inst.kwargs)
  File "build/bdist.linux-x86_64/egg/deepstate/main_angr.py", line 157, in run
    DeepAngr(procedure=self).api_assume(arg, expr_ea, file_ea, line)
  File "build/bdist.linux-x86_64/egg/deepstate/common.py", line 438, in api_assume
    expr, _ = self.read_c_string(expr_ea, concretize=False)
  File "build/bdist.linux-x86_64/egg/deepstate/common.py", line 145, in read_c_string
    assert isinstance(ea, (int, long))
AssertionError

Investigate common usage patterns of strcmp, strlen, memcmp, and memcpy

Things to try.

String comparison

Make a symbolic-execution aware strcmp(a, b), but on the library side. What we're looking for is: is one or or both of a[0] and b[0] symbolic. In the case that one is, then I think what we want to try is produce two forks: one where the return value is 0 and we constrain the bytes of a to be the bytes of b. We probably need solver support here to ask questions like "can this range of memory be the same." The other fork will return a non-zero number in the range [CHAR_MIN, CHAR_MAX]. We can do this via the following pattern:

if (DeepState_Bool()) {
  int ret = DeepState_IntInRange(CHAR_MIN, CHAR_MAX);
  DeepState_Assume(ret != 0);
  // Assume they aren't different, but don't actually constraint the bytes
  // We want to experiment here to see if it's reasonable that program
  // behaviour, actually does the right thing. Perhaps we could also
  // provide a deferred assertion mechanism, e.g. `DeepState_AssumeLater`.
  return ret;
} else {
  // constrain the bytes of one of the sides to be equal to the other
  // then and provide a an interface to overwrite them in the backing
  // memory store, e.g. `DeepState_WriteByte(addr, 0)` to write `0` to
  // `addr`, ignoring any possible errors, and succeeding even if the
  // memory is read-only. 
  return 0;
}

Recall

It is potentially worth it to implement strcmp to have a record/recall mechanism, where we tell the runtime engine about each constant string, e.g. DeepState_RecordString(b) if b was non-symbolic above, then augment symbolic strcmps that forks by comparing against all prior recorded strings.

String lengths

Implement strlen(a) in terms of whether or not a[0] is symbolic. If it is, then provide an interface to get the minimum string length and the maximum string length, and then do a fork where we constrain the lengths, and use the DeepState_WriteByte interface to force in a NUL-terminator.

Lexers

Investigate the code patterns of lexers produced by lex/flex/ragel or yacc/bison/antlr, and perhaps also look into the lexers using by javascript or HTML parsing parsing engines. It's one thing to construct symbolic tokens and benefit from strcmp-like optimizations described above, but it's another to materialize tokens out of thing air based on one's progress in a state machine.

Perhaps one benefit of using C/C++ is that we can do things like: __attribute__((weak)) yylex, and use to give us possible access into the inner workings of parsers against which the program is linked.

Abandon semantics is wrong for assumption failure

DeepState_Abandon stops the current test completely. This is right in some circumstances, but wrong for assumption failure when fuzzing. For fuzzing, abandoning current path and restarting the test with a new input is the right behavior. Needs new function to call, with that behavior, plus logic to determine if fuzzing.

[Arguably, assumption failure during symbolic execution may correctly be a fatal, since it could indicate symbolic execution tool bug.]

Add default values for symbolic API functions

Being able to provide "sane" default values for functions returning symbolic values (e.g. DeepState_Int) may be worth it, both for getting a basic test suite working without any input from a runtime engine / fuzzer, as well as potentially for "guiding" a runtime engine toward a particular value. In the latter case, the return value from a symbolic function could be a sort of OneOf({default_val, symbol}).

Add deepstate-manticore entry point to match paper

Paper claims this works in intro, and it might be nice for those who always want to explicitly state engine used if using a specific one. deepstate might eventually use ML to choose, use a saved config of best methods, or run multiple engines...

deepstate-manticore fails on OneOf and Primes examples

> deepstate-manticore build/examples/Primes

...

INFO:deepstate.mcore:Running 2 tests across 1 workers
2018-07-13 18:19:48,561: [8028] m.c.executor:ERROR: Exception: 'State' object has no attribute 'solver'
Traceback (most recent call last):
  File "/root/.local/lib/python2.7/site-packages/manticore-0.1.10-py2.7.egg/manticore/core/executor.py", line 461, in run
    if not current_state.execute():
  File "/root/.local/lib/python2.7/site-packages/manticore-0.1.10-py2.7.egg/manticore/core/state.py", line 127, in execute
    result = self._platform.execute()
  File "/root/.local/lib/python2.7/site-packages/manticore-0.1.10-py2.7.egg/manticore/platforms/linux.py", line 2216, in execute
    self.current.execute()
  File "/root/.local/lib/python2.7/site-packages/manticore-0.1.10-py2.7.egg/manticore/core/cpu/abstractcpu.py", line 822, in execute
    self._publish('will_execute_instruction', self.PC, insn)
  File "/root/.local/lib/python2.7/site-packages/manticore-0.1.10-py2.7.egg/manticore/utils/event.py", line 118, in _publish
    self._publish_impl(_name, *args, **kwargs)
  File "/root/.local/lib/python2.7/site-packages/manticore-0.1.10-py2.7.egg/manticore/utils/event.py", line 134, in _publish_impl
    sink._publish_impl(_name, *args, **kwargs)
  File "/root/.local/lib/python2.7/site-packages/manticore-0.1.10-py2.7.egg/manticore/utils/event.py", line 134, in _publish_impl
    sink._publish_impl(_name, *args, **kwargs)
  File "/root/.local/lib/python2.7/site-packages/manticore-0.1.10-py2.7.egg/manticore/utils/event.py", line 132, in _publish_impl
    sink._publish_impl(_name, self, *args, **kwargs)
  File "/root/.local/lib/python2.7/site-packages/manticore-0.1.10-py2.7.egg/manticore/utils/event.py", line 126, in _publish_impl
    callback(robj(), *args, **kwargs)
  File "/root/.local/lib/python2.7/site-packages/manticore-0.1.10-py2.7.egg/manticore/manticore.py", line 486, in _hook_callback
    cb(state)
  File "build/bdist.linux-x86_64/egg/deepstate/main_manticore.py", line 255, in <lambda>
    return lambda state: state.invoke_model(func)
  File "/root/.local/lib/python2.7/site-packages/manticore-0.1.10-py2.7.egg/manticore/core/state.py", line 396, in invoke_model
    self._platform.invoke_model(model, prefix_args=(self,))
  File "/root/.local/lib/python2.7/site-packages/manticore-0.1.10-py2.7.egg/manticore/platforms/platform.py", line 35, in invoke_model
    self._function_abi.invoke(model, prefix_args)
  File "/root/.local/lib/python2.7/site-packages/manticore-0.1.10-py2.7.egg/manticore/core/cpu/abstractcpu.py", line 349, in invoke
    result = model(*arguments)
  File "build/bdist.linux-x86_64/egg/deepstate/main_manticore.py", line 155, in hook_IsSymbolicUInt
    return DeepManticore(state).api_is_symbolic_uint(arg)
  File "build/bdist.linux-x86_64/egg/deepstate/common.py", line 417, in api_is_symbolic_uint
    solutions = self.concretize_many(arg, 2)
  File "build/bdist.linux-x86_64/egg/deepstate/main_manticore.py", line 127, in concretize_many
    return self.state.solver.eval_upto(val, max_num)
AttributeError: 'State' object has no attribute 'solver'

ERROR:deepstate.mcore:State 1 terminated due to internal error: 'State' object has no attribute 'solver'

error does not terminate run, but results in missing failure case for PrimePolynomial_OnlyGeneratesPrimes_NoStreaming, etc.

Problem also appears (similar symptom) for OneOf example.

Properly save inputs on program exit from manticore

See: https://travis-ci.org/trailofbits/deepstate/jobs/407280601

angr:

INFO    | 2018-07-23 19:01:04,303 | deepstate | bye
INFO    | 2018-07-23 19:01:04,304 | deepstate | hi
INFO    | 2018-07-23 19:01:04,304 | deepstate | Input: 00 00 12 34 00 00 00 00
INFO    | 2018-07-23 19:01:04,304 | deepstate | Saving input to out/_takeover_file/_takeover_test/077a3cb23638c444e4947259154fe6ec.fail

manticore:

INFO:deepstate:bye
INFO:deepstate:hi
INFO:deepstate:Input: 00 00 12 34 00 00 00 00
2018-07-23 19:05:54,528: [7877] m.manticore:INFO: Generated testcase No. 0 - Program finished with exit status: 0 (*)
INFO:deepstate.mcore:State 6 terminated due to program exit: Program finished with exit status: 0 (*)

(the test is actually noticing we don't save the PASSING test, but it's probably even more important that we save failing tests, which seems to not be happening here due to the way manticore exits. This is related to issue #69 -- basically, some manticore exits just aren't handled properly, I think)

angr and manticore seem to fail the StreamingAndFormatting test

angr error:

ERROR   | 2018-07-19 12:12:06,465 | deepstate.angr | Uncaught exception: unsupported format character 'p' (0x70) at index 1
Traceback (most recent call last):
  File "build/bdist.linux-x86_64/egg/deepstate/main_angr.py", line 305, in run_test
    do_run_test(project, test, apis, run_state, should_call_state)
  File "build/bdist.linux-x86_64/egg/deepstate/main_angr.py", line 295, in do_run_test
    DeepAngr(state=state).report()
  File "build/bdist.linux-x86_64/egg/deepstate/common.py", line 376, in report
    logger(self._stream_to_message(stream))
  File "build/bdist.linux-x86_64/egg/deepstate/common.py", line 320, in _stream_to_message
    message.append(format_str % val)
ValueError: unsupported format character 'p' (0x70) at index 1

manticore error:

INFO:deepstate:/home/travis/build/trailofbits/deepstate/examples/StreamingAndFormatting.cpp(29): 97
INFO:deepstate:/home/travis/build/trailofbits/deepstate/examples/StreamingAndFormatting.cpp(30): 1
INFO:deepstate:/home/travis/build/trailofbits/deepstate/examples/StreamingAndFormatting.cpp(31): 1.000000
INFO:deepstate:/home/travis/build/trailofbits/deepstate/examples/StreamingAndFormatting.cpp(32): string
2018-07-19 12:12:30,812: [7679] m.c.executor:ERROR: Exception: unsupported format character 'p' (0x70) at index 1
Traceback (most recent call last):
  File "/home/travis/virtualenv/python2.7.14/lib/python2.7/site-packages/manticore-0.1.10-py2.7.egg/manticore/core/executor.py", line 479, in run
    self._publish('will_terminate_state', current_state, current_state_id, e)
  File "/home/travis/virtualenv/python2.7.14/lib/python2.7/site-packages/manticore-0.1.10-py2.7.egg/manticore/utils/event.py", line 118, in _publish
    self._publish_impl(_name, *args, **kwargs)
  File "/home/travis/virtualenv/python2.7.14/lib/python2.7/site-packages/manticore-0.1.10-py2.7.egg/manticore/utils/event.py", line 134, in _publish_impl
    sink._publish_impl(_name, *args, **kwargs)
  File "/home/travis/virtualenv/python2.7.14/lib/python2.7/site-packages/manticore-0.1.10-py2.7.egg/manticore/utils/event.py", line 126, in _publish_impl
    callback(robj(), *args, **kwargs)
  File "build/bdist.linux-x86_64/egg/deepstate/main_manticore.py", line 306, in done_test
    mc.report()
  File "build/bdist.linux-x86_64/egg/deepstate/common.py", line 376, in report
    logger(self._stream_to_message(stream))
  File "build/bdist.linux-x86_64/egg/deepstate/common.py", line 320, in _stream_to_message
    message.append(format_str % val)
ValueError: unsupported format character 'p' (0x70) at index 1

and the full log is here:
https://travis-ci.org/trailofbits/deepstate/jobs/405771433

Repo title

Probably just a quibble, but the "DeepState augments C/C++ Test-Driven Development with Symbolic Execution" title might turn off people who do unit testing but don't think of it as TDD, and hides the fact it also allows fuzzing (the first seems a bigger deal than the latter).

Add integration tests, CI hooks

It would be nice, say, if we had stderr/stdout/filesystem-based expectations for each executor, for each of the example binaries.

Fuzzing support

The source of symbolic bytes in DeepState is a static array of uint8_ts. This should be a pretty ideal setup to feed in fuzzed input, either via libFuzzer or something like Dr. Fuzz.

Execution never hit `DeepState_Setup` in binary `./Tests32`

WARNING | 2018-07-24 08:50:56,971 | angr.state_plugins.unicorn_engine | failed loading "angr_native.so", unicorn support disabled (/usr/local/lib/python2.7/dist-packages/angr-7.8.7.1-py2.7.egg/angr/lib/angr_native.so: cannot open shared object file: No such file or directory: /usr/local/lib/python2.7/dist-packages/angr-7.8.7.1-py2.7.egg/angr/lib/angr_native.so: cannot open shared object file: No such file or directory)
WARNING | 2018-07-24 08:50:57,224 | angr.analyses.disassembly_utils | Your version of capstone does not support MIPS instruction groups.
CRITICAL | 2018-07-24 08:51:00,081 | deepstate.angr | Execution never hit `DeepState_Setup` in binary `./Tests32`

Describe features and benefits in Readme

Before jumping into the building and installation instructions, we should be describing why someone would want to use DeepState and what specific features it provides. Algo does this well.

Handle Manticore's TooManySolutions exception

INFO:deepstate:Input: 00 00 00 00 00 00 00 11
.INFO:deepstate:Running Vector_DoubleReversal from /home/travis/build/trailofbits/deepstate/examples/Lists.cpp(24)
INFO:deepstate:Passed: Vector_DoubleReversal
INFO:deepstate:Input: 00 00 00 00 00 00 00 07
INFO:deepstate:Saving input to out/Lists.cpp/Vector_DoubleReversal/e3e13013b74d872953e2a1225c2b5cd0.pass
2018-07-23 16:15:47,531: [9659] m.c.executor:ERROR: Exception: Max number of different solutions hit
Traceback (most recent call last):
  File "/home/travis/virtualenv/python2.7.14/lib/python2.7/site-packages/manticore-0.1.10-py2.7.egg/manticore/core/executor.py", line 475, in run
    current_state = self.fork(current_state, e.expression, e.policy, e.setstate)
  File "/home/travis/virtualenv/python2.7.14/lib/python2.7/site-packages/manticore-0.1.10-py2.7.egg/manticore/core/executor.py", line 382, in fork
    solutions = state.concretize(expression, policy)
  File "/home/travis/virtualenv/python2.7.14/lib/python2.7/site-packages/manticore-0.1.10-py2.7.egg/manticore/core/state.py", line 292, in concretize
    silent=False)
  File "/home/travis/virtualenv/python2.7.14/lib/python2.7/site-packages/manticore-0.1.10-py2.7.egg/manticore/core/smtlib/solver.py", line 379, in get_all_values
    raise TooManySolutions(result)
TooManySolutions: Max number of different solutions hit

Formatting bug

Traceback (most recent call last):
  File "build/bdist.linux-x86_64/egg/deepstate/main_angr.py", line 297, in run_test
    do_run_test(project, test, apis, run_state)
  File "build/bdist.linux-x86_64/egg/deepstate/main_angr.py", line 287, in do_run_test
    DeepAngr(state=state).report()
  File "build/bdist.linux-x86_64/egg/deepstate/common.py", line 365, in report
    logger(self._stream_to_message(stream))
  File "build/bdist.linux-x86_64/egg/deepstate/common.py", line 309, in _stream_to_message
    message.append(format_str % val)
ValueError: unsupported format character 'p' (0x70) at index 1

We can probably convert this into a %x on the Python side.

Make useful travis tests

Should at minimum:

  • run angr and manticore (in individual tasks) on at least one example

  • check for output matching a template for failing/passing properties

Ideally run in a fuzzer, but we may need assumptions fixed for that.

Add mac OS X symbol support

Symbols are mangled to be prefixed with an _ on a mac, and so that's making DeepState unable to find things like DeepState_Setup. The way that deepstate goes and finds its initial symbols should be modified to also look for a _-prefixed variant.

Don't use exit codes for replayed take-over test cases

If we replay a take-over test case natively, and the forked take-over test case soft fails, we will fail to detect the soft failure in the parent process.

This is because we are communicating failure via exit codes, but soft failures only manifest via global variable updates in the child process. Really, for take-over tests, the "test case" is just some binary, which might correctly have a nonzero exit that we don't want to call a "failure".

Instead, we should do something like sharing memory between the child and parent process, and inspecting the child's shared memory when it exits.

api_assume read_c_string wrong type (file_ea)

root@f8e053de1581:~/testfs# deepstate-angr ./Tests
WARNING | 2018-07-23 18:39:58,191 | angr.state_plugins.unicorn_engine | failed loading "angr_native.so", unicorn support disabled (/root/.local/lib/python2.7/site-packages/angr-7.8.7.1-py2.7.egg/angr/lib/angr_native.so: cannot open shared object file: No such file or directory: /root/.local/lib/python2.7/site-packages/angr-7.8.7.1-py2.7.egg/angr/lib/angr_native.so: cannot open shared object file: No such file or directory)
WARNING | 2018-07-23 18:39:58,707 | angr.analyses.disassembly_utils | Your version of capstone does not support MIPS instruction groups.
INFO    | 2018-07-23 18:40:41,438 | deepstate.angr | Running 1 tests across 1 workers
ERROR   | 2018-07-23 19:34:04,389 | deepstate.angr | Uncaught exception: 
Traceback (most recent call last):
  File "build/bdist.linux-x86_64/egg/deepstate/main_angr.py", line 290, in do_run_test
    test_manager.run()
  File "/root/.local/lib/python2.7/site-packages/angr-7.8.7.1-py2.7.egg/angr/misc/immutability.py", line 24, in _wrapper
    if method(self, *args, **kwargs) is not self:
  File "/root/.local/lib/python2.7/site-packages/angr-7.8.7.1-py2.7.egg/angr/sim_manager.py", line 260, in run
    self.step(stash=stash, **kwargs)
  File "/root/.local/lib/python2.7/site-packages/angr-7.8.7.1-py2.7.egg/angr/misc/immutability.py", line 24, in _wrapper
    if method(self, *args, **kwargs) is not self:
  File "/root/.local/lib/python2.7/site-packages/angr-7.8.7.1-py2.7.egg/angr/sim_manager.py", line 341, in step
    successors = self.step_state(state, successor_func, **run_args)
  File "/root/.local/lib/python2.7/site-packages/angr-7.8.7.1-py2.7.egg/angr/sim_manager.py", line 362, in step_state
    successors = self.successors(state, successor_func, **run_args)
  File "/root/.local/lib/python2.7/site-packages/angr-7.8.7.1-py2.7.egg/angr/sim_manager.py", line 401, in successors
    return self._project.factory.successors(state, **run_args)
  File "/root/.local/lib/python2.7/site-packages/angr-7.8.7.1-py2.7.egg/angr/factory.py", line 61, in successors
    return self.project.engines.successors(*args, **kwargs)
  File "/root/.local/lib/python2.7/site-packages/angr-7.8.7.1-py2.7.egg/angr/engines/hub.py", line 128, in successors
    r = engine.process(state, **kwargs)
  File "/root/.local/lib/python2.7/site-packages/angr-7.8.7.1-py2.7.egg/angr/engines/hook.py", line 51, in process
    return self.project.factory.procedure_engine.process(state, procedure, force_addr=force_addr, **kwargs)
  File "/root/.local/lib/python2.7/site-packages/angr-7.8.7.1-py2.7.egg/angr/engines/procedure.py", line 31, in process
    force_addr=force_addr)
  File "/root/.local/lib/python2.7/site-packages/angr-7.8.7.1-py2.7.egg/angr/engines/engine.py", line 55, in process
    self._process(new_state, successors, *args, **kwargs)
  File "/root/.local/lib/python2.7/site-packages/angr-7.8.7.1-py2.7.egg/angr/engines/procedure.py", line 65, in _process
    inst = procedure.execute(state, successors, ret_to=ret_to)
  File "/root/.local/lib/python2.7/site-packages/angr-7.8.7.1-py2.7.egg/angr/sim_procedure.py", line 169, in execute
    r = getattr(inst, inst.run_func)(*sim_args, **inst.kwargs)
  File "build/bdist.linux-x86_64/egg/deepstate/main_angr.py", line 157, in run
    DeepAngr(procedure=self).api_assume(arg, expr_ea, file_ea, line)
  File "build/bdist.linux-x86_64/egg/deepstate/common.py", line 444, in api_assume
    file, _ = self.read_c_string(file_ea, concretize=False)
  File "build/bdist.linux-x86_64/egg/deepstate/common.py", line 149, in read_c_string
    assert isinstance(ea, (int, long))
AssertionError

After the fix for #72, running deepstate-angr on Tests in testfs produces this similar, but different error.

Detect crashes and save them with the .crash suffix in the --output_test_dir

DeepState currently outputs .pass and .fail files, but if a test case crashes, then that isn't distinguished, and probably isn't handled.

Action items:

  • Add a test cases that can crash
  • Add crash detection in main_angr.py; this might require going over the errored stash of states.
  • Add crash detection to main_manticore.py.
  • For detected crashes, mark a specific thing in the state as crashed so that it gets named accordingly.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.