Skip to content

Commit

Permalink
add llvm instrumentation
Browse files Browse the repository at this point in the history
  • Loading branch information
spinpx committed Dec 5, 2023
1 parent e32bc80 commit ddfd466
Show file tree
Hide file tree
Showing 54 changed files with 1,881 additions and 932 deletions.
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ ENV HOPPER_BIN=/hopper/hopper \
RUN apt-get update \
&& apt-get -y upgrade \
&& apt-get -y install build-essential wget curl cmake git unzip xxd protobuf-compiler libprotobuf-dev \
&& apt-get -y install llvm-dev libclang-dev clang \
&& apt-get -y install llvm llvm-dev libclang-dev clang \
&& apt-get clean

# ENV RUSTUP_DIST_SERVER="https://mirrors.ustc.edu.cn/rust-static"
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ To learn more about Hopper, check out our [paper](https://arxiv.org/pdf/2309.034
```

The script will create a `install` directory in hopper's root directory, then you can use `hopper`.
To use the command anywhere, you can set your project directory in your PATH variable.
To use the command anywhere, you can set the project directory in your PATH variable.

### Using Docker
You can choose to use the Dockerfile, which build the requirements and Hopper.
Expand All @@ -38,7 +38,7 @@ hopper compile --header ./cJSON.h --library ./libcjson.so --output output

Use `hopper compile --help` to see detailed usage. If the compiling reports errors about header file, refer to the usage of [rust-bindgen](https://rust-lang.github.io/rust-bindgen/), which we used for parsing header file.
You may wrap the header file with the missing definitions.
Hopper uses [E9Patch](https://github.com/GJDuck/e9patch) to instrument binaries by default.
Hopper uses [E9Patch](https://github.com/GJDuck/e9patch) to instrument binaries by default. Optionally, you can use [LLVM](./hopper-instrument/llvm-mode/) for source code instrumentation.

After running `compile`, you will find that it generates the following files in the output directory:
- `bin/hopper-fuzzer`: generates inputs, maintatins states, and use `harness` to excuted the inputs.
Expand Down Expand Up @@ -97,7 +97,7 @@ echo core | sudo tee /proc/sys/kernel/core_pattern
```

### Function pattern
Hopper generates inputs for all functions in libiries by default. However, there are two ways to filter functions in Hopper: exlucding functions or including functions. This way, it can be focus on intersting functions.
Hopper generates inputs for all functions that appear in both headers and libiries by default. However, there are two ways to filter functions in Hopper: exlucding functions or including functions. This way, it can be focus on intersting functions.

#### `--func-pattern`
```
Expand Down
18 changes: 11 additions & 7 deletions build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -19,24 +19,28 @@ if [[ "$OSTYPE" == "linux-gnu"* ]]; then

if [ ! -x $INSTALL_DIR/patchelf ]; then
info "download patchelf ..."
cd install
cd $INSTALL_DIR
mkdir -p tmp
cd tmp
wget https://github.com/NixOS/patchelf/releases/download/${PATCHELF_VERSION}/patchelf-${PATCHELF_VERSION}-x86_64.tar.gz
tar -xvf patchelf-${PATCHELF_VERSION}-x86_64.tar.gz
cp bin/patchelf ../.
cd ../../
fi
fi

# info "start install hopper's llvm plugins ..."
# cd hopper-instrument/llvm-mode
# make PREFIX=$INSTALL_DIR
info "start install hopper's llvm plugins ..."
cd $INSTALL_DIR
rm -rf llvm_build
mkdir llvm_build && cd llvm_build
cmake -DHOPPER_BIN_DIR=$INSTALL_DIR $ROOT_DIR/hopper-instrument/llvm-mode
make
make install

BUILD_TYPE=${BUILD_TYPE:-debug}
# BUILD_TYPE=${BUILD_TYPE:-release}
# BUILD_TYPE=${BUILD_TYPE:-debug}
BUILD_TYPE=${BUILD_TYPE:-release}

info "start build and install hopper fuzzer ..."
cd $ROOT_DIR
if [[ "$BUILD_TYPE" == "debug" ]]; then
cargo build
else
Expand Down
5 changes: 2 additions & 3 deletions examples/re2/hopper.config
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ TEST_HEADER=/data/workspace/fuzzing_bench/re2/cre2.h

# Full path to shared library
TEST_LIB_DIR=/data/workspace/fuzzing_bench/re2/build/hopper_build/
TEST_LIBRARY=${TEST_LIB_DIR}/cre2/lib/libcre2.so ${TEST_LIB_DIR}/lib/libre2.so.10.0.0
TEST_LIBRARY=${TEST_LIB_DIR}/cre2/lib/libcre2.so ${TEST_LIB_DIR}/lib/libre2.so

# Output directory
OUT_DIR=output
Expand All @@ -19,8 +19,7 @@ HOPPER_MAP_SIZE_POW2=20
# set seeds for hopper
# HOPPER_SEED_DIR=seeds


# target library
HOPPER_TEST_LIBRARY=cre2/lib/libre2.so

HOPPER_CUSTOM_RULES=$SRC_DIR/../custom_rule
HOPPER_CUSTOM_RULES=$SRC_DIR/../custom_rule
15 changes: 15 additions & 0 deletions hopper
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ source ${ROOT_DIR}/tools/core_affinity.sh
if [[ -e "hopper.config" ]]; then
while IFS='=' read -r key value; do
if [[ $key && $value ]]; then
if [[ $key = \#* ]] ; then
continue
fi
declare -x "$key=$value"
echo "config file set: $key = $value"
fi
Expand Down Expand Up @@ -69,6 +72,14 @@ check_output() {
warn "$USAGE"
exit 1
fi
if [ "$OUTPUT_DIR" == "" ];then
error "output directory can't be empty!"
exit 1
fi
if [ "$OUTPUT_DIR" == "/" ];then
error "output directory can't be root directory '/'!"
exit 1
fi
}

[ ! -d "${ROOT_DIR}/install" ] && warn "Please run ./build.sh to build hopper's code"
Expand Down Expand Up @@ -183,6 +194,10 @@ clean)
find . -maxdepth 1 -type f ! -executable ! -name "test*" ! -name "*.log" ! -name "func_list" ! -name "custom_rule" ! -name "hopper.config" -delete
info "clean files in '$OUTPUT_DIR' directory"
;;
clang)
echo "CC=${ROOT_DIR}/install/hopper-clang"
echo "CXX=${ROOT_DIR}/install/hopper-clang++"
;;
help)
warn "$USAGE"
exit 0
Expand Down
2 changes: 2 additions & 0 deletions hopper-compiler/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ gimli = { version = "0.26", default-features = false, features = ["read"] }
object = { version = "0.28", default-features = false, features = ["read"] }
eyre = "0.6"
twoway = "0.2"
# NO GPL
# patchelf = "0.2.1"

[features]
default = ["elf", "dwarf"]
Expand Down
10 changes: 10 additions & 0 deletions hopper-compiler/src/binary_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ pub struct BinaryInfo {
pub str_list: Vec<String>,
// exported API in the symbol table
pub func_list: Vec<FuncInfo>,
// needed libraries
pub needed: Vec<String>
}

#[derive(Debug)]
Expand All @@ -29,6 +31,7 @@ impl BinaryInfo {
let lib_type;
let mut str_list = vec![];
let mut func_list = vec![];
let mut needed = vec![];
match result {
Object::Elf(elf) => {
lib_type = "elf";
Expand Down Expand Up @@ -67,6 +70,12 @@ impl BinaryInfo {
})
}
}
if let Some(dy) = elf.dynamic.as_ref() {
for name in dy.get_libraries(&elf.dynstrtab) {
needed.push(name.to_string());
}
}

}
Object::PE(pe) => {
lib_type = "pe";
Expand Down Expand Up @@ -112,6 +121,7 @@ impl BinaryInfo {
lib_type,
str_list,
func_list,
needed,
})
}

Expand Down
2 changes: 1 addition & 1 deletion hopper-compiler/src/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ pub fn output_lib_name(file: &str) -> String {
pub fn check_llvm_runtime(libraries: &[String]) -> bool {
libraries
.iter()
.any(|l| check_file_contains(l, "HOOPER_LLVM_MARK"))
.any(|l| check_file_contains(l, "__hopper_area_ptr"))
}

pub fn check_file_contains(target: &str, s: &str) -> bool {
Expand Down
6 changes: 5 additions & 1 deletion hopper-compiler/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,11 @@ fn instrument(library: &Path, output: &Path, config: &Config, lib_info: &BinaryI
}
}
#[cfg(target_os = "linux")]
patch::patchelf_set_so_name(&lib_name, output_lib.to_str().context("fail to be str")?)?;
{
let output_lib_path = output_lib.to_str().context("fail to be str")?;
patch::patchelf_set_so_name(&lib_name, output_lib_path)?;
patch::remove_prev_needed(&config.library, output_lib_path, lib_info)?;
}
Ok(output_lib)
}

Expand Down
Loading

0 comments on commit ddfd466

Please sign in to comment.