* Enable simple ARM register concretization for Unicorn * Add canonical_registers property to abstractcpu * cpu to self * Check for regs_access better * Emulate a single instruction * Bypass capstone 3.0.4 arm bug * Dealing with capstone * Temporary disable ASR and remobe BitVec.Bool from test * WIP WIP debug prints WIP WIP * Unicorn fallback working (using unicorn master) * HAck to support unicorn 1.0.0 * WIP * Unicorn hack to handle PC updates * [WIP] do not do anything with this commit; for debugging only * Adding before clean up * emulation more or less works; need to work out more unicorn bugs * clean up emulate() caller code * move hooks to methods; cleanup * Concretize memory when emulating * Re-add Bool() * Update tests to start at offset 4 When an instruction branches to the previous instruction, Unicorn attempts to dereference that memory. We'd like to use unit tests to also make sure Unicorn emulation is in line with our own semantics. If we start all tests at offset 4, we can jump to a previous instruction and not fault when Unicorn dereferences it. * Fix concretization * Clean up test imports; upper-case Cpu * Unicorn tests * Add tests for all the ARM semantics, but make sure they're equivalent on unicorn. * Add a few tests to make sure unicorn correctly concretizes the memory it references * Fix broken import * Add symbolic register tests * Re-introduce the unicorn hack * Add the 'ONE' concretization policy * Rm unused function * Update concretization; add comments * Add ONE policy test * Create a base class for all concretization exceptions * Remove Armv7Cpu._concretize_registers * Check for enabled logging in a more idiomatic way * [wip] intermediate testing commit * Reimplement hooks and execution with unicorn * Add a DMB (mem barrier) instruction; nop * simplify instruction resolution * improve unicorn error handling * explicitly delete emu * Handle ARM helpers inline * map fetched memory * Narrow exception handling * Update DMB docs; make __kuser_dmb match real implementation * Fix typo; add comment; remove extraneous parameter * typos++
Manticore
Manticore is a prototyping tool for dynamic binary analysis, with support for symbolic execution, taint analysis, and binary instrumentation.
Features
- Input Generation: Manticore automatically generates inputs that trigger unique code paths
- Crash Discovery: Manticore discovers inputs that crash programs via memory safety violations
- Execution Tracing: Manticore records an instruction-level trace of execution for each generated input
- Programmatic Interface: Manticore exposes programmatic access to its analysis engine via a Python API
Scope
Manticore supports binaries of the following formats, operating systems, and architectures. It has been primarily used on binaries compiled from C and C++.
- OS/Formats: Linux ELF, Windows Minidump
- Architectures: x86, x86_64, ARMv7 (partial)
Requirements
Manticore is officially supported on Linux and uses Python 2.7.
Installation
These install instructions require pip 7.1.0, due to --no-binary. If you have an older
pip version, you might be able to use --no-use-wheel instead.
We recommend the use of Manticore in a virtual environment, though this is optional. To manage this, we recommend installing virtualenvwrapper. Then, to set up a virtual environment, in the root of the Manticore repository, run
mkvirtualenv manticore
Then, from the root of the Manticore repository, run:
pip install --no-binary capstone .
or, if you didn't use a virtualenv and would like to do a user install:
pip install --user --no-binary capstone .
This installs the Manticore CLI tool manticore and the Python API.
Then, install the Z3 Theorem Prover. Download the latest release for your platform and place the z3 binary in your $PATH.
Note: The
--no-binaryflag is a workaround for a known Capstone issue that may occur.
For developers
For a dev install, run:
pip install -e --no-binary capstone --no-binary keystone-engine .[dev]
This installs a few other dependencies used for tests which you can run with some of the commands below:
cd /path/to/manticore/
# all tests
nosetests
# just one file
nosetests tests/test_armv7cpu.py
# just one test class
nosetests tests/test_armv7cpu.py:Armv7CpuInstructions
# just one test
nosetests tests/test_armv7cpu.py:Armv7CpuInstructions.test_mov_imm_min
Quick start
Install and try Manticore in a few shell commands:
# follow install instructions in README.md before beginning
cd /path/to/manticore/
cd examples/linux
make
manticore basic
cat mcore_*/*1.stdin | ./basic
cat mcore_*/*2.stdin | ./basic
cd ../script
python count_instructions.py ../linux/helloworld # ok if the insn count is different
Here's an asciinema of what it should look like: https://asciinema.org/a/567nko3eh2yzit099s0nq4e8z
Usage
$ manticore ./path/to/binary # runs, and creates a directory with analysis results
or
# example Manticore script
from manticore import Manticore
hook_pc = 0x400ca0
m = Manticore('./path/to/binary')
@m.hook(hook_pc)
def hook(state):
cpu = state.cpu
print 'eax', cpu.EAX
print cpu.read_int(cpu.SP)
m.terminate() # tell Manticore to stop
m.run()
FAQ
How does Manticore compare to angr?
Manticore is simpler. It has a smaller codebase, fewer dependencies and features, and an easier learning curve. If you come from a reverse engineering or exploitation background, you may find Manticore intuitive due to its lack of intermediate representation and overall emphasis on staying close to machine abstractions.