├── .dockerignore ├── BUILD_TARGET.md ├── Cargo.lock ├── Cargo.toml ├── Dockerfile ├── LICENSE ├── README.md ├── angora.env ├── build ├── build.sh ├── build_diff_tool.sh ├── install_llvm.sh ├── install_pin_mode.sh ├── install_rust.sh └── install_tools.sh ├── common ├── Cargo.toml └── src │ ├── cond_stmt_base.rs │ ├── config.rs │ ├── defs.rs │ ├── lib.rs │ ├── log_data.rs │ ├── shm.rs │ └── tag.rs ├── docs ├── build_target.md ├── configuration.md ├── coverage.md ├── environment_variables.md ├── example.md ├── exploitation.md ├── lava-who-fix.md ├── lava.md ├── overview.md ├── pin_mode.md ├── running.md ├── troubleshoot.md ├── ui.md └── usage.md ├── fuzzer ├── Cargo.toml └── src │ ├── bin │ ├── fuzzer.rs │ ├── parse_track_file.rs │ └── speed_test.rs │ ├── bind_cpu.rs │ ├── branches.rs │ ├── check_dep.rs │ ├── command.rs │ ├── cond_stmt │ ├── cond_state.rs │ ├── cond_stmt.rs │ ├── mod.rs │ ├── output.rs │ └── shm_conds.rs │ ├── depot │ ├── depot.rs │ ├── depot_dir.rs │ ├── dump.rs │ ├── file.rs │ ├── mod.rs │ ├── qpriority.rs │ └── sync.rs │ ├── dyncfg │ ├── cfg.rs │ ├── fparse.rs │ └── mod.rs │ ├── executor │ ├── executor.rs │ ├── forksrv.rs │ ├── limit.rs │ ├── mod.rs │ ├── pipe_fd.rs │ └── status_type.rs │ ├── fuzz_loop.rs │ ├── fuzz_main.rs │ ├── fuzz_type.rs │ ├── lib.rs │ ├── mut_input │ ├── mod.rs │ ├── mut_input.rs │ ├── offsets.rs │ ├── rw.rs │ └── serialize.rs │ ├── search │ ├── Readme.md │ ├── afl.rs │ ├── cbh.rs │ ├── cmpfn.rs │ ├── det.rs │ ├── exploit.rs │ ├── gd.rs │ ├── grad.rs │ ├── handler.rs │ ├── interesting_val.rs │ ├── len.rs │ ├── mb.rs │ ├── method.rs │ ├── mod.rs │ ├── one_byte.rs │ └── random.rs │ ├── stats │ ├── bunny.rs │ ├── chart.rs │ ├── entry.rs │ ├── format.rs │ ├── fuzz.rs │ ├── local.rs │ ├── mod.rs │ ├── search.rs │ ├── show.rs │ └── state.rs │ ├── tmpfs.rs │ └── track │ ├── filter.rs │ ├── fparser.rs │ ├── load_pin_data.rs │ └── mod.rs ├── llvm_mode ├── CMakeLists.txt ├── compiler │ ├── CMakeLists.txt │ └── angora_clang.c ├── dfsan_rt │ ├── CMakeLists.txt │ ├── abilibstdc++.txt │ ├── build_lib.py │ ├── cmake │ │ ├── AddCompilerRT.cmake │ │ ├── BuiltinTests.cmake │ │ ├── CompilerRTCompile.cmake │ │ ├── CompilerRTDarwinUtils.cmake │ │ ├── CompilerRTLink.cmake │ │ ├── CompilerRTUtils.cmake │ │ ├── HandleCompilerRT.cmake │ │ └── SanitizerUtils.cmake │ ├── common_interface_defs.h │ ├── dfsan │ │ ├── .clang-format │ │ ├── CMakeLists.txt │ │ ├── dfsan.cc │ │ ├── dfsan.cc.bak │ │ ├── dfsan.h │ │ ├── dfsan.syms.extra │ │ ├── dfsan_custom.cc │ │ ├── dfsan_flags.inc │ │ ├── dfsan_interceptors.cc │ │ ├── dfsan_platform.h │ │ ├── done_abilist.txt │ │ ├── libc_ubuntu1404_abilist.txt │ │ └── scripts │ │ │ ├── build-libc-list.py │ │ │ └── check_custom_wrappers.sh │ ├── dfsan_interface.h │ ├── interception │ │ ├── .clang-format │ │ ├── CMakeLists.txt │ │ ├── interception.h │ │ ├── interception_linux.cc │ │ ├── interception_linux.h │ │ ├── interception_mac.cc │ │ ├── interception_mac.h │ │ ├── interception_win.cc │ │ └── interception_win.h │ ├── libclang_rt.dfsan-x86_64.a.syms │ └── sanitizer_common │ │ ├── .clang-format │ │ ├── .clang-tidy │ │ ├── CMakeLists.txt │ │ ├── assembly.h │ │ ├── sanitizer_addrhashmap.h │ │ ├── sanitizer_allocator.cc │ │ ├── sanitizer_allocator.h │ │ ├── sanitizer_allocator_bytemap.h │ │ ├── sanitizer_allocator_combined.h │ │ ├── sanitizer_allocator_interface.h │ │ ├── sanitizer_allocator_internal.h │ │ ├── sanitizer_allocator_local_cache.h │ │ ├── sanitizer_allocator_primary32.h │ │ ├── sanitizer_allocator_primary64.h │ │ ├── sanitizer_allocator_secondary.h │ │ ├── sanitizer_allocator_size_class_map.h │ │ ├── sanitizer_allocator_stats.h │ │ ├── sanitizer_asm.h │ │ ├── sanitizer_atomic.h │ │ ├── sanitizer_atomic_clang.h │ │ ├── sanitizer_atomic_clang_other.h │ │ ├── sanitizer_atomic_clang_x86.h │ │ ├── sanitizer_atomic_msvc.h │ │ ├── sanitizer_bitvector.h │ │ ├── sanitizer_bvgraph.h │ │ ├── sanitizer_common.cc │ │ ├── sanitizer_common.h │ │ ├── sanitizer_common_interceptors.inc │ │ ├── sanitizer_common_interceptors_format.inc │ │ ├── sanitizer_common_interceptors_ioctl.inc │ │ ├── sanitizer_common_libcdep.cc │ │ ├── sanitizer_common_nolibc.cc │ │ ├── sanitizer_common_syscalls.inc │ │ ├── sanitizer_coverage_libcdep.cc │ │ ├── sanitizer_coverage_mapping_libcdep.cc │ │ ├── sanitizer_deadlock_detector.h │ │ ├── sanitizer_deadlock_detector1.cc │ │ ├── sanitizer_deadlock_detector2.cc │ │ ├── sanitizer_deadlock_detector_interface.h │ │ ├── sanitizer_flag_parser.cc │ │ ├── sanitizer_flag_parser.h │ │ ├── sanitizer_flags.cc │ │ ├── sanitizer_flags.h │ │ ├── sanitizer_flags.inc │ │ ├── sanitizer_freebsd.h │ │ ├── sanitizer_interface_internal.h │ │ ├── sanitizer_internal_defs.h │ │ ├── sanitizer_lfstack.h │ │ ├── sanitizer_libc.cc │ │ ├── sanitizer_libc.h │ │ ├── sanitizer_libignore.cc │ │ ├── sanitizer_libignore.h │ │ ├── sanitizer_linux.cc │ │ ├── sanitizer_linux.h │ │ ├── sanitizer_linux_libcdep.cc │ │ ├── sanitizer_linux_mips64.S │ │ ├── sanitizer_linux_s390.cc │ │ ├── sanitizer_linux_x86_64.S │ │ ├── sanitizer_list.h │ │ ├── sanitizer_mac.cc │ │ ├── sanitizer_mac.h │ │ ├── sanitizer_malloc_mac.inc │ │ ├── sanitizer_mutex.h │ │ ├── sanitizer_persistent_allocator.cc │ │ ├── sanitizer_persistent_allocator.h │ │ ├── sanitizer_placement_new.h │ │ ├── sanitizer_platform.h │ │ ├── sanitizer_platform_interceptors.h │ │ ├── sanitizer_platform_limits_linux.cc │ │ ├── sanitizer_platform_limits_posix.cc │ │ ├── sanitizer_platform_limits_posix.h │ │ ├── sanitizer_posix.cc │ │ ├── sanitizer_posix.h │ │ ├── sanitizer_posix_libcdep.cc │ │ ├── sanitizer_printf.cc │ │ ├── sanitizer_procmaps.h │ │ ├── sanitizer_procmaps_common.cc │ │ ├── sanitizer_procmaps_freebsd.cc │ │ ├── sanitizer_procmaps_linux.cc │ │ ├── sanitizer_procmaps_mac.cc │ │ ├── sanitizer_quarantine.h │ │ ├── sanitizer_report_decorator.h │ │ ├── sanitizer_stackdepot.cc │ │ ├── sanitizer_stackdepot.h │ │ ├── sanitizer_stackdepotbase.h │ │ ├── sanitizer_stacktrace.cc │ │ ├── sanitizer_stacktrace.h │ │ ├── sanitizer_stacktrace_libcdep.cc │ │ ├── sanitizer_stacktrace_printer.cc │ │ ├── sanitizer_stacktrace_printer.h │ │ ├── sanitizer_stoptheworld.h │ │ ├── sanitizer_stoptheworld_linux_libcdep.cc │ │ ├── sanitizer_suppressions.cc │ │ ├── sanitizer_suppressions.h │ │ ├── sanitizer_symbolizer.cc │ │ ├── sanitizer_symbolizer.h │ │ ├── sanitizer_symbolizer_internal.h │ │ ├── sanitizer_symbolizer_libbacktrace.cc │ │ ├── sanitizer_symbolizer_libbacktrace.h │ │ ├── sanitizer_symbolizer_libcdep.cc │ │ ├── sanitizer_symbolizer_mac.cc │ │ ├── sanitizer_symbolizer_mac.h │ │ ├── sanitizer_symbolizer_posix_libcdep.cc │ │ ├── sanitizer_symbolizer_win.cc │ │ ├── sanitizer_syscall_generic.inc │ │ ├── sanitizer_syscall_linux_aarch64.inc │ │ ├── sanitizer_syscall_linux_x86_64.inc │ │ ├── sanitizer_termination.cc │ │ ├── sanitizer_thread_registry.cc │ │ ├── sanitizer_thread_registry.h │ │ ├── sanitizer_tls_get_addr.cc │ │ ├── sanitizer_tls_get_addr.h │ │ ├── sanitizer_unwind_linux_libcdep.cc │ │ ├── sanitizer_win.cc │ │ ├── scripts │ │ ├── check_lint.sh │ │ ├── cpplint.py │ │ ├── gen_dynamic_list.py │ │ ├── litlint.py │ │ ├── litlint_test.py │ │ └── sancov.py │ │ └── symbolizer │ │ ├── sanitizer_symbolize.cc │ │ ├── sanitizer_wrappers.cc │ │ └── scripts │ │ ├── build_symbolizer.sh │ │ └── global_symbols.txt ├── external_lib │ ├── CMakeLists.txt │ ├── io_func.c │ ├── stdalloc.c │ ├── zlib_abilist.txt │ └── zlib_func.c ├── include │ ├── abilist.h │ ├── alloc_inl.h │ ├── debug.h │ ├── defs.h │ └── version.h ├── libcxx │ ├── CMakeLists.txt │ ├── build_fast │ │ └── lib │ │ │ ├── libc++.a │ │ │ └── libc++abi.a │ ├── build_track │ │ └── lib │ │ │ ├── libc++.a │ │ │ └── libc++abi.a │ └── compile.sh ├── pass │ ├── AngoraPass.cc │ ├── CMakeLists.txt │ ├── DFSanPass.cc │ └── UnfoldBranchPass.cc └── rules │ ├── CMakeLists.txt │ ├── angora_abilist.txt │ └── exploitation_list.txt ├── misc ├── build_objdump.sh ├── paper.png └── screenshot.png ├── pin_mode ├── Makefile ├── cond_stmt.h ├── logger.h ├── makefile.rules ├── pin_stub.c ├── pin_track.cpp └── run_pin.sh ├── runtime ├── Cargo.toml ├── include │ ├── ffds.h │ ├── heapmap.h │ ├── len_label.h │ ├── log_collect.h │ └── tag_set.h └── src │ ├── ffds.rs │ ├── heapmap.rs │ ├── len_label.rs │ ├── lib.rs │ ├── logger.rs │ ├── tag_set.rs │ ├── tag_set_wrap.rs │ └── track.rs ├── runtime_fast ├── Cargo.toml ├── build.rs └── src │ ├── context.c │ ├── context.rs │ ├── fast.rs │ ├── forkcli.rs │ ├── lib.rs │ ├── shm_branches.rs │ └── shm_conds.rs ├── rust-toolchain ├── rustfmt.toml ├── tests ├── alloca │ ├── alloca.c │ └── args ├── asan │ ├── args │ └── asan.c ├── bitflip │ ├── args │ └── bitflip.c ├── bool │ ├── args │ └── bool.c ├── call_fn │ ├── args │ └── call_fn.c ├── call_fn2 │ ├── args │ └── call_fn2.c ├── call_fn3 │ ├── args │ └── call_fn3.c ├── cf1 │ ├── args │ └── cf1.c ├── cf2 │ ├── args │ └── cf2.c ├── cf3 │ ├── args │ └── cf3.c ├── context │ ├── args │ └── context.c ├── cpp_string │ ├── args │ └── cpp_string.cpp ├── fcmp │ ├── args │ └── fcmp.c ├── fstream │ ├── args │ └── fstream.cpp ├── gep │ ├── args │ └── gep.c ├── gep2 │ ├── args │ └── gep2.c ├── if_eq │ ├── args │ └── if_eq.c ├── infer_type │ ├── args │ └── infer_type.c ├── input │ └── 1.txt ├── loop │ ├── args │ └── loop.c ├── memcmp │ ├── args │ └── memcmp.c ├── mini │ ├── args │ └── mini.c ├── mini2 │ ├── args │ └── mini2.c ├── pointer │ ├── args │ └── pointer.c ├── recursion │ ├── args │ └── recursion.c ├── shift_and │ ├── args │ └── shift_and.c ├── sign │ ├── args │ └── sign.c ├── stat │ ├── args │ └── stat.c ├── stdin │ ├── args │ └── stdin.c ├── strcmp │ ├── args │ └── strcmp.c ├── strcmp2 │ ├── args │ └── strcmp2.c ├── switch │ ├── args │ └── switch.c ├── switch2 │ ├── args │ └── switch2.c ├── test.sh ├── testcpp.sh └── timeout │ ├── args │ └── timeout.c └── tools ├── compare_callstack.sh ├── compile_bc.py ├── gen_abilist_from_error.sh ├── gen_library_abilist.sh ├── lava_validation.py ├── llvm-diff-parmesan ├── CMakeLists.txt ├── DiffConsumer.cpp ├── DiffConsumer.h ├── DiffLog.cpp ├── DiffLog.h ├── DifferenceEngine.cpp ├── DifferenceEngine.h ├── id-assigner-pass │ ├── .clang-format │ ├── .clang-tidy │ ├── .gitignore │ ├── CMakeLists.txt │ ├── include │ │ ├── CMakeLists.txt │ │ └── parmesan │ │ │ └── IDAssigner.h │ └── src │ │ ├── CMakeLists.txt │ │ └── IDAssigner.cpp └── llvm-diff.cpp ├── log_reader ├── Cargo.toml └── src │ └── main.rs └── prune.py /.dockerignore: -------------------------------------------------------------------------------- 1 | target/ 2 | llvm_mode/build 3 | tools/llvm-diff-parmesan/build 4 | tools/llvm-diff-parmesan/build-pass 5 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [workspace] 2 | members = [ 3 | "common", 4 | "fuzzer", 5 | "runtime_fast", 6 | "runtime", 7 | "tools/log_reader", 8 | ] 9 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:20.04 2 | 3 | RUN echo 'debconf debconf/frontend select Noninteractive' | debconf-set-selections 4 | RUN DEBIAN_FRONTEND=noninteractive apt-get update && \ 5 | apt-get -y upgrade && \ 6 | apt-get install -y git build-essential wget zlib1g-dev golang-go python3-pip python3-dev python-is-python3 build-essential cmake && \ 7 | #apt-get install -y git build-essential wget zlib1g-dev golang-go python-pip python-dev build-essential cmake && \ 8 | apt-get clean 9 | 10 | 11 | ENV RUSTUP_HOME=/usr/local/rustup \ 12 | CARGO_HOME=/usr/local/cargo \ 13 | PIN_ROOT=/pin-3.7-97619-g0d0c92f4f-gcc-linux \ 14 | GOPATH=/go \ 15 | PATH=/clang+llvm/bin:/usr/local/cargo/bin:/parmesan/bin/:/go/bin:$PATH \ 16 | LD_LIBRARY_PATH=/clang+llvm/lib:$LD_LIBRARY_PATH 17 | 18 | RUN mkdir -p parmesan 19 | COPY . parmesan 20 | WORKDIR parmesan 21 | 22 | RUN ./build/install_rust.sh 23 | RUN PREFIX=/ ./build/install_llvm.sh 24 | RUN ./build/install_tools.sh 25 | RUN ./build/build.sh 26 | #RUN ./build/install_pin_mode.sh 27 | # ParmeSan does not support PIN atm 28 | 29 | VOLUME ["/data"] 30 | WORKDIR /data 31 | #ENTRYPOINT [ "/opt/env.init" ] 32 | -------------------------------------------------------------------------------- /angora.env: -------------------------------------------------------------------------------- 1 | export PATH=/opt/clang-angora/clang+llvm/bin:$PATH 2 | export LD_LIBRARY_PATH=/opt/clang-angora/clang+llvm/lib:$LD_LIBRARY_PATH 3 | -------------------------------------------------------------------------------- /build/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | BIN_PATH=$(readlink -f "$0") 3 | ROOT_DIR=$(dirname $(dirname $BIN_PATH)) 4 | 5 | set -euxo pipefail 6 | 7 | if ! [ -x "$(command -v llvm-config)" ]; then 8 | ${ROOT_DIR}/build/install_llvm.sh 9 | export PATH=${HOME}/clang+llvm/bin:$PATH 10 | export LD_LIBRARY_PATH=${HOME}/clang+llvm/lib${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH} 11 | export CC=clang 12 | export CXX=clang++ 13 | fi 14 | 15 | PREFIX=${PREFIX:-${ROOT_DIR}/bin/} 16 | 17 | cargo build 18 | cargo build --release 19 | 20 | rm -rf ${PREFIX} 21 | mkdir -p ${PREFIX} 22 | mkdir -p ${PREFIX}/lib 23 | cp target/release/fuzzer ${PREFIX} 24 | cp target/release/*.a ${PREFIX}/lib 25 | cp target/release/log_reader ${PREFIX} 26 | 27 | cd llvm_mode 28 | rm -rf build 29 | mkdir -p build 30 | cd build 31 | cmake -DCMAKE_INSTALL_PREFIX=${PREFIX} -DCMAKE_BUILD_TYPE=Release .. 32 | make # VERBOSE=1 33 | make install # VERBOSE=1 34 | 35 | #llvm-diff-parmesan 36 | (cd ${ROOT_DIR}/tools/llvm-diff-parmesan && mkdir -p build && cd build && cmake .. && cmake --build . && cp llvm-diff-parmesan ../../../bin/) 37 | #id-assigner-standalone (HACK) 38 | (cd ${ROOT_DIR}/tools/llvm-diff-parmesan && mkdir -p build-pass && cd build-pass && cmake -DBUILD_STANDALONE_PASS=1 ../id-assigner-pass && cmake --build . && cp src/*.so ../../../bin/pass/) 39 | -------------------------------------------------------------------------------- /build/build_diff_tool.sh: -------------------------------------------------------------------------------- 1 | #llvm-diff-parmesan 2 | (cd tools/llvm-diff-parmesan && mkdir -p build && cd build && cmake .. && cmake --build . && cp llvm-diff-parmesan ../../../bin/) 3 | -------------------------------------------------------------------------------- /build/install_llvm.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -eux 3 | 4 | LINUX_VER=${LINUX_VER:-ubuntu-16.04} 5 | LLVM_VER=${LLVM_VER:-7.0.0} 6 | PREFIX=${PREFIX:-${HOME}} 7 | 8 | LLVM_DEP_URL=https://releases.llvm.org/${LLVM_VER} 9 | TAR_NAME=clang+llvm-${LLVM_VER}-x86_64-linux-gnu-${LINUX_VER} 10 | 11 | wget -q ${LLVM_DEP_URL}/${TAR_NAME}.tar.xz 12 | tar -C ${PREFIX} -xf ${TAR_NAME}.tar.xz 13 | rm ${TAR_NAME}.tar.xz 14 | mv ${PREFIX}/${TAR_NAME} ${PREFIX}/clang+llvm 15 | 16 | set +x 17 | echo "Please set:" 18 | echo "export PATH=\$PREFIX/clang+llvm/bin:\$PATH" 19 | echo "export LD_LIBRARY_PATH=\$PREFIX/clang+llvm/lib:\$LD_LIBRARY_PATH" 20 | 21 | ## Write the same info to a file 22 | echo "export PATH=\$PREFIX/clang+llvm/bin:\$PATH" > parmesan.env 23 | echo "export LD_LIBRARY_PATH=\$PREFIX/clang+llvm/lib:\$LD_LIBRARY_PATH" >> parmesan.env 24 | -------------------------------------------------------------------------------- /build/install_pin_mode.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -euxo pipefail 4 | 5 | # install pin mode 6 | git init && git submodule update --init --recursive 7 | cd pin_mode/libdft64 8 | PREFIX=/ ./install_pin.sh 9 | make 10 | cp env.init /opt/ 11 | cd .. 12 | make OBJDIR=../bin/lib/ -------------------------------------------------------------------------------- /build/install_rust.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -euxo pipefail 4 | 5 | # from https://github.com/rust-lang-nursery/docker-rust-nightly/blob/master/nightly/Dockerfile 6 | 7 | url="https://static.rust-lang.org/rustup/dist/x86_64-unknown-linux-gnu/rustup-init" 8 | wget "$url" 9 | chmod +x rustup-init 10 | # RUSTUP_DIST_SERVER="https://mirrors.ustc.edu.cn/rust-static" RUSTUP_UPDATE_ROOT="https://mirrors.ustc.edu.cn/rust-static/rustup" 11 | ./rustup-init -y --no-modify-path --default-toolchain stable 12 | # ./rustup-init -y --no-modify-path --default-toolchain nightly 13 | 14 | rm rustup-init 15 | chmod -R a+w $RUSTUP_HOME $CARGO_HOME 16 | rustup --version 17 | cargo --version 18 | rustc --version 19 | -------------------------------------------------------------------------------- /build/install_tools.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -euxo pipefail 4 | 5 | #wllvm and gllvm 6 | pip3 install --upgrade pip==9.0.3 7 | pip3 install wllvm 8 | mkdir ${HOME}/go 9 | go get github.com/SRI-CSL/gllvm/cmd/... 10 | 11 | #llvm-diff-parmesan 12 | #(cd tools/llvm-diff-parmesan && mkdir build && cd build && cmake .. && cmake --build . && cp llvm-diff-parmesan ../../../bin/) 13 | -------------------------------------------------------------------------------- /common/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "angora_common" 3 | version = "1.2.2" 4 | authors = ["sp1npx "] 5 | edition = "2018" 6 | 7 | [dependencies] 8 | serde="1.0" 9 | serde_derive = "1.0" 10 | bincode = "1.0" 11 | libc = "0.2" 12 | -------------------------------------------------------------------------------- /common/src/cond_stmt_base.rs: -------------------------------------------------------------------------------- 1 | use crate::defs::*; 2 | use serde_derive::{Deserialize, Serialize}; 3 | 4 | #[derive(Debug, Clone, Default, Copy, Serialize, Deserialize)] 5 | #[repr(C)] // It should be repr C since we will used it in shared memory 6 | pub struct CondStmtBase { 7 | pub cmpid: u32, 8 | pub context: u32, 9 | pub last_callsite: u32, 10 | pub order: u32, 11 | pub belong: u32, 12 | 13 | pub condition: u32, 14 | pub level: u32, 15 | pub op: u32, 16 | pub size: u32, 17 | 18 | pub lb1: u32, 19 | pub lb2: u32, 20 | 21 | pub arg1: u64, 22 | pub arg2: u64, 23 | } 24 | 25 | /* 26 | #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] 27 | pub struct CondStmtMb { 28 | pub base: CondStmtBase, 29 | pub magic_bytes: Option<(Vec, Vec)>, 30 | } 31 | */ 32 | 33 | impl PartialEq for CondStmtBase { 34 | fn eq(&self, other: &CondStmtBase) -> bool { 35 | self.cmpid == other.cmpid && self.context == other.context && self.order == other.order 36 | } 37 | } 38 | 39 | impl Eq for CondStmtBase {} 40 | 41 | impl CondStmtBase { 42 | pub fn flip_condition(&mut self) { 43 | if self.condition == COND_FALSE_ST { 44 | self.condition = COND_TRUE_ST; 45 | } else { 46 | self.condition = COND_FALSE_ST; 47 | } 48 | } 49 | pub fn is_explore(&self) -> bool { 50 | self.op <= COND_MAX_EXPLORE_OP 51 | } 52 | 53 | pub fn is_exploitable(&self) -> bool { 54 | self.op > COND_MAX_EXPLORE_OP && self.op <= COND_MAX_EXPLOIT_OP 55 | } 56 | 57 | pub fn is_signed(&self) -> bool { 58 | (self.op & COND_SIGN_MASK) > 0 59 | || ((self.op & COND_BASIC_MASK) >= COND_ICMP_SGT_OP 60 | && (self.op & COND_BASIC_MASK) <= COND_ICMP_SLE_OP) 61 | } 62 | 63 | pub fn is_afl(&self) -> bool { 64 | self.op == COND_AFL_OP 65 | } 66 | 67 | pub fn may_be_bool(&self) -> bool { 68 | // sign or unsigned 69 | self.op & 0xFF == COND_ICMP_EQ_OP && self.arg1 <= 1 && self.arg2 <= 1 70 | } 71 | 72 | pub fn is_float(&self) -> bool { 73 | (self.op & COND_BASIC_MASK) <= COND_FCMP_TRUE 74 | } 75 | 76 | pub fn is_switch(&self) -> bool { 77 | (self.op & COND_BASIC_MASK) == COND_SW_OP 78 | } 79 | 80 | pub fn is_done(&self) -> bool { 81 | self.condition == COND_DONE_ST 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /common/src/config.rs: -------------------------------------------------------------------------------- 1 | // ************ Switches ************** 2 | // length 3 | pub const ENABLE_INPUT_LEN_EXPLORATION: bool = true; 4 | pub const ENABLE_RANDOM_LEN: bool = false; 5 | pub const ENABLE_MICRO_RANDOM_LEN: bool = true; 6 | 7 | // other 8 | pub const DISABLE_INFER_SHAPE_IF_HAS_AND_OP: bool = true; 9 | pub const PREFER_FAST_COND: bool = true; 10 | 11 | // ************ Resources **************** 12 | pub const MAX_INPUT_LEN: usize = 15000; 13 | 14 | // branch.rs 15 | pub const MAP_SIZE_POW2: usize = 20; 16 | pub const BRANCHES_SIZE: usize = 1 << MAP_SIZE_POW2; 17 | 18 | // executor.rs: 19 | pub const TMOUT_SKIP: usize = 3; 20 | pub const TIME_LIMIT: u64 = 1; 21 | pub const MEM_LIMIT: u64 = 200; // MB 22 | pub const TIME_LIMIT_TRACK: u64 = 12; 23 | pub const MEM_LIMIT_TRACK: u64 = 0; 24 | pub const LONG_FUZZ_TIME: usize = 8; 25 | pub const MAX_INVARIABLE_NUM: usize = 16; 26 | pub const MAX_NUM_MINIMAL_OPTIMA_ALL: usize = 28; 27 | // based the bit bucket: [1], [2], [3], [4, 7], [8, 15], [16, 31], [32, 127], [128, infinity] 28 | pub const MAX_COND_ORDER: u32 = 16; 29 | 30 | // ************ Mutation **************** 31 | // SEARCH 32 | pub const ENABLE_DET_MUTATION: bool = true; 33 | pub const MAX_SEARCH_EXEC_NUM: usize = 376; 34 | pub const MAX_EXPLOIT_EXEC_NUM: usize = 66; 35 | pub const MAX_NUM_MINIMAL_OPTIMA_ROUND: usize = 8; 36 | pub const MAX_RANDOM_SAMPLE_NUM: usize = 10; 37 | pub const GD_MOMENTUM_BETA: f64 = 0.0; 38 | pub const GD_ESCAPE_RATIO: f64 = 1.0; 39 | pub const BONUS_EXEC_NUM: usize = 66; 40 | 41 | // AFL 42 | pub const MUTATE_ARITH_MAX: u32 = 30; 43 | pub const RANDOM_LEN_NUM: usize = 30; 44 | pub const MAX_HAVOC_FLIP_TIMES: usize = 45; // for all bytes 45 | pub const MAX_SPLICE_TIMES: usize = 45; 46 | -------------------------------------------------------------------------------- /common/src/lib.rs: -------------------------------------------------------------------------------- 1 | pub mod cond_stmt_base; 2 | pub mod config; 3 | pub mod defs; 4 | pub mod log_data; 5 | pub mod shm; 6 | pub mod tag; 7 | 8 | 9 | // void __unfold_branch_fn(uint32_t) {} 10 | 11 | #[no_mangle] 12 | pub fn __unfold_branch_fn(_x: u32) { 13 | 14 | } 15 | -------------------------------------------------------------------------------- /common/src/log_data.rs: -------------------------------------------------------------------------------- 1 | use crate::{cond_stmt_base::CondStmtBase, tag::TagSeg}; 2 | use serde_derive::{Deserialize, Serialize}; 3 | use std::collections::HashMap; 4 | 5 | #[derive(Serialize, Deserialize, PartialEq, Debug)] 6 | pub struct LogData { 7 | pub cond_list: Vec, 8 | pub tags: HashMap>, 9 | pub magic_bytes: HashMap, Vec)>, 10 | } 11 | 12 | impl LogData { 13 | pub fn new() -> Self { 14 | Self { 15 | cond_list: vec![], 16 | tags: HashMap::new(), 17 | magic_bytes: HashMap::new(), 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /common/src/tag.rs: -------------------------------------------------------------------------------- 1 | use serde_derive::{Deserialize, Serialize}; 2 | 3 | #[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Clone, Copy, Hash)] 4 | #[repr(C)] 5 | pub struct TagSeg { 6 | pub sign: bool, 7 | pub begin: u32, 8 | pub end: u32, 9 | } 10 | 11 | // impl TagSeg { 12 | // pub fn slice_from<'a>(&self, v: &'a [u8]) -> &'a [u8] { 13 | // &v[(self.begin as usize)..(self.end as usize)] 14 | // } 15 | 16 | // pub fn slice_from_mut<'a>(&self, v: &'a mut [u8]) -> &'a mut [u8] { 17 | // &mut v[(self.begin as usize)..(self.end as usize)] 18 | // } 19 | // } 20 | -------------------------------------------------------------------------------- /docs/configuration.md: -------------------------------------------------------------------------------- 1 | # Configuration Files 2 | 3 | - `llvm_mode/include/defs.h`: Configuration and definition file for llvm pass. 4 | - `llvm_mode/rules/angora_abilist.txt` : Taint propagation rules for functions in libraries in llvm mode. 5 | - `llvm_mode/rules/exploitation_list.txt` : Security sensitive functions or instructions in llvm mode. 6 | - `common/src/config.rs`: Configuration file for fuzzer. 7 | -------------------------------------------------------------------------------- /docs/coverage.md: -------------------------------------------------------------------------------- 1 | # Evaluate coverage 2 | - tool: [afl-cov](https://github.com/mrash/afl-cov) 3 | 4 | # Install gcov and genhtml 5 | ``` 6 | sudo apt-get install lcov 7 | 8 | ``` 9 | 10 | # build 11 | - make 12 | ``` 13 | CC=gcc CFLAGS="-fprofile-arcs -ftest-coverage -g -O0" LFLAGS="-lgcov --coverage" make 14 | ``` 15 | 16 | - autoconf 17 | ``` 18 | CFLAGS="-fprofile-arcs -ftest-coverage -g -O0" LIBS=-lgcov ../src/configure --prefix=`pwd`/install --disable-shared 19 | ``` 20 | 21 | - cmake 22 | ``` 23 | cmake -DENABLE_GCOV -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=Debug ../src 24 | 25 | option(ENABLE_GCOV "Enable gcov." Off) 26 | if (ENABLE_GCOV) 27 | SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fprofile-arcs -ftest-coverage") 28 | SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -fprofile-arcs -ftest-coverage") 29 | SET(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} -fprofile-arcs -ftest-coverage -lgcov") 30 | endif() 31 | ``` 32 | -------------------------------------------------------------------------------- /docs/environment_variables.md: -------------------------------------------------------------------------------- 1 | # Environment variables for compiling 2 | 3 | - `USE_FAST=1`: use fast mode to compile the program. It includes branch counting, getting the feedback of the fuzzing constraint (the output of its function). 4 | - `USE_TRACK=1`: use taint tracking and collect all constraints. 5 | - `USE_DFSAN=1`: use taint tracking. 6 | - `ANGORA_CUSTOM_FN_CONTEXT=k` : Use only the last k ( 0 <= k <= 32) function call location as the context, e.g. `ANGORA_CUSTOM_FN_CONTEXT=8`. Angora disables context if k is 0. 7 | - `ANGORA_GEN_ID_RANDOM=1` : Generate ids for predicates randomly instead of the hash of their locations. 8 | - `ANGORA_OUTPUT_COND_LOC=1` : (Debug option) Output the location of each predicate during compiling. 9 | - `ANGORA_TAINT_CUSTOM_RULE=/path/to/object` : object contains those proxy function (how to propagate taints), e.g. `ANGORA_TAINT_CUSTOM_RULE=~/angora/bin/lib/zlib-func.o` . You should add it as custom type in the file passed by `ANGORA_TAINT_RULE_LIST` first. 10 | - `ANGORA_TAINT_RULE_LIST=/path/to/list` : DataFlowSanitizer’s [ABI list](https://clang.llvm.org/docs/DataFlowSanitizer.html), e.g. `ANGORA_TAINT_RULE_LIST=~/angora/bin/rules/zlib_abilist.txt`. 11 | - `ANGORA_INST_RATIO`: 12 | 13 | # Environment variables for running 14 | 15 | - `RUST_LOG=trace`: enable tracing output 16 | - `RUST_LOG=debug`: enable debugging output 17 | - `ANGORA_DISABLE_CPU_BINDING=1`: Disable cpu binding. 18 | 19 | -------------------------------------------------------------------------------- /docs/exploitation.md: -------------------------------------------------------------------------------- 1 | # Exploitation 2 | 3 | As BuzzFuzz, Angora supports finding which input bytes were processed by "attack point" we defined by taint tracking. You can add your custom "attack point" in `llvm_mode/rules/exploitation_list.txt`, and then recompile the tested program. 4 | 5 | ``` 6 | # the 2th(start from 0) argument of function memeset is an attack point 7 | fun:memset:i2 8 | # the 0th argument of instruction (LLVM IR) inttoptr is an attack point 9 | ins:inttoptr=i0 10 | ``` 11 | 12 | ## Reference 13 | - Vijay Ganesh, Tim Leek, and Martin Rinard. “Taintbased directed whitebox fuzzing”. In: Proceedings of the 31st International Conference on Software Engineering. 2009, pp. 474–484. -------------------------------------------------------------------------------- /docs/overview.md: -------------------------------------------------------------------------------- 1 | # Angora Overview 2 | 3 | Angora consists of a fuzzer, instrumenting compilers and runtime libraries. 4 | Target programs should be compiled with instrumentation in order to collect 5 | runtime information. 6 | 7 | Two copies of the target program should be prepared, specifically one with 8 | taint tracking instrumentation and the other with branch and constraint 9 | instrumentation. This ensures a reasonable amount of efficiency when fuzzing 10 | due to taint tracking being resource demanding. 11 | 12 | Similar to AFL, Angora mutates a set of seeds to increase program coverage. 13 | Inputs that trigger new explored branches will be appended to the queue. 14 | Angora implements a wide selection of strategies to solve branch constraints. 15 | For each new seed, taint tracking will be applied to learn which part of the 16 | input will affect which branch constraint. Then mutations will be applied to 17 | the input with the tainted parts in consideration. This allows for efficient 18 | and precise input generation which significantly increases input coverage. 19 | 20 | **More details are available in the published works** 21 | 22 | ## Directory Structure 23 | 24 | - `build`: Scripts for building Angora components. 25 | - `common`: Common constants and data structures. 26 | - `fuzzer`: Contains the source code for the fuzzer. The fuzzer runs the target program and repeatedly mutates the input attempting to increase its code coverage statistics. 27 | - `src/bin`: Source files for the executable binaries. 28 | - `src/depot`: Depot module for input/output file management. 29 | - `src/executor`: Executor module for managing target program runs. 30 | - `src/search`: Exploration strategies. You are free to implement and integrate your own strategy with Angora. 31 | - `src/cond_stmt`: Conditional statement module for constraints. 32 | - `src/mut_input`: Input bytes for conditional statements. 33 | - `src/track`: Parse taint analysis result. 34 | - `src/stats`: Statistical chart. 35 | - `src/branches`: Branch counting. 36 | - `llvm_mode`: Includes source code for instrumenting compilers and DFSan, the taint tracking framework. 37 | - `pin_mode`: Includes source code for instrumenting based on Intel Pin. 38 | - `runtime`: Taint tracking runtime library for target program. 39 | - `runtime_fast`: Branch and constraint information collection library for target program. 40 | - `tests`: Sample tests to evaluate fuzzer performance. 41 | - `tools`: Some scripts. 42 | - `docs`: Documentation. 43 | 44 | -------------------------------------------------------------------------------- /docs/pin_mode.md: -------------------------------------------------------------------------------- 1 | # Angora's Pin mode - Use libdft64 for taint tracking 2 | 3 | Angora now supports using [libdft64](https://github.com/AngoraFuzzer/libdft64) for taint anlysis instead of DFSan (LLVM mode). 4 | The feature is still experimental. 5 | 6 | ## Build requirements 7 | 8 | - [libdft64](https://github.com/AngoraFuzzer/libdft64) 9 | 10 | ### Environment Variables 11 | ``` 12 | export LIBDFT_PATH=/path-to-libdft64 13 | ``` 14 | 15 | ## Build Pin mode 16 | ``` 17 | cd pin_mode 18 | make OBJDIR=../bin/lib/ 19 | ``` 20 | 21 | ## Build a target program 22 | 23 | As [Build a target program](./build_target.md) mentioned, Angora uses two variables `USE_FAST` and `USE_TRACK` to compile two different version programs respectively. In Pin mode, Angora uses variable `USE_PIN` to compile the one with taint tracking instead of `USE_TRACK`. 24 | 25 | ``` 26 | USE_PIN=1 CC=/path-to-angora/bin/angora-clang CXX=/path-to-angora/bin/angora-clang++ make 27 | ``` 28 | 29 | ## Run Angora in Pin mode 30 | 31 | Command line options `-m` is used to set which mode you are using in fuzzing. We have "llvm" and "pin" modes. 32 | 33 | ``` 34 | ./angora_fuzzer -m pin -i input -o output -t path-to-taint-program-pin -- program args(..) 35 | ``` -------------------------------------------------------------------------------- /docs/running.md: -------------------------------------------------------------------------------- 1 | # Running Angora 2 | 3 | ## Run in Docker Container 4 | 5 | The Dockerfile provided allows Angora to run in a container. 6 | 7 | *Caution: Angora assigns different threads with specific process affinity levels. 8 | Running multiple Angora instances in different containers can result in decreased 9 | efficiency.* 10 | 11 | ``` 12 | echo core | sudo tee /proc/sys/kernel/core_pattern 13 | docker build -t angora ./ 14 | docker run --privileged -v /path-to-code-and-seed:/data -it --rm angora /bin/bash 15 | ``` 16 | 17 | 18 | ## Tests 19 | 20 | A number of tests have been provided. Feel free to add your own to test the 21 | capabilities of Angora. 22 | 23 | ``` 24 | cd tests 25 | ./test.sh 26 | ``` 27 | 28 | ## Run alongside AFL 29 | 30 | If you are running AFL and its output directory is `output`, run 31 | ``` 32 | ./angora_fuzzer -i input -o output -t path-to-taint-program --sync_afl -- program args(..) 33 | ``` 34 | 35 | Since the implementation of AFL mutation approach in Angora is too simple, the best practice is run it together with AFL, and use `-A` to disable Angora's AFL approach. 36 | -------------------------------------------------------------------------------- /docs/troubleshoot.md: -------------------------------------------------------------------------------- 1 | # Troubleshoot 2 | 3 | ## Target program compilation errors 4 | 5 | - `dfs$***` undefined errors in compiling: See *Model external library* section. 6 | 7 | - Can't find xlocal.h while compiling C++ with Angora. 8 | 9 | ``` 10 | ln -s /usr/include/locale.h /usr/include/xlocale.h 11 | ``` 12 | 13 | - `*scanf()` functions not modelled: Replace `*scanf()` functions. 14 | 15 | ## Runtime errors 16 | 17 | - Failed to find any branches during dry run: Ensure the binary is instrumented and the input 18 | directory is populated. Otherwise no branches can be found. 19 | 20 | - Multiple inconsistent warnings. It caused by the fast and track programs has different behaviors. If most constraints are inconsistent, ensure they are compiled with the same environment. Otherwise, report us. 21 | 22 | - Density is too large (> 10%). Please increase `MAP_SIZE_POW2` in `common/src/config.rs`. Or disable function-call context(density > 50%) by compiling with `ANGORA_CUSTOM_FN_CONTEXT=k` (k is an integer and 0 <= k <= 32) environment variable. Angora disables context if k is 0. 23 | -------------------------------------------------------------------------------- /docs/usage.md: -------------------------------------------------------------------------------- 1 | # Angora usage 2 | ``` 3 | # /path-to-angora/angora_fuzzer --help 4 | angora-fuzzer 1.2.2 5 | fuzz some program 6 | 7 | USAGE: 8 | fuzzer [FLAGS] [OPTIONS] --input --output [--] ... 9 | 10 | FLAGS: 11 | -A, --disable_afl_mutation Disable the fuzzer to mutate inputs using AFL's mutation strategies 12 | -E, --disable_exploitation Disable the fuzzer to mutate sensitive bytes to exploit bugs 13 | -h, --help Prints help information 14 | -S, --sync_afl Sync the seeds with AFL. Output directory should be in AFL's directory structure. 15 | -V, --version Prints version information 16 | 17 | OPTIONS: 18 | -i, --input Sets the directory of input seeds, use "-" to restart with existing output directory 19 | -M, --memory_limit Memory limit for programs, default is 200(MB) 20 | -m, --mode Which binary instrumentation framework are you using? [possible values: llvm, pin] 21 | -o, --output Sets the directory of outputs 22 | -r, --search_method Which search method to run the program in? [possible values: gd, random, mb] 23 | -j, --jobs Sets the number of thread jobs, default is 1 24 | -T, --time_limit