| #!/bin/bash |
| |
| # Due to the complexity to android buile environment this script is created for |
| # development purpose to build, run and debug the fuzzers. It's not needed or |
| # required for official build and fuzzing. |
| |
| function init() { |
| if [ -z "$ANDROID_BUILD_TOP" ]; |
| then |
| echo "Did you forget lunch?" |
| exit 1 |
| fi |
| source $ANDROID_BUILD_TOP/build/envsetup.sh |
| |
| PROJ=$(basename $PWD) |
| FUZZER_NAME=nfc_${PROJ}_fuzzer |
| FUZZ_DIR=data/fuzz/$(get_build_var TARGET_ARCH)/$FUZZER_NAME |
| FUZZ_OPTIONS="$FUZZ_OPTIONS -close_fd_mask=3 -max_len=512 -artifact_prefix=/$FUZZ_DIR/crashes/" |
| } |
| |
| function run_once() { |
| if [ "$1" == "-c" ]; |
| then |
| adb shell rm -rf /$FUZZ_DIR/corpus /$FUZZ_DIR/crashes /$FUZZ_DIR/gcov |
| adb shell mkdir -p /$FUZZ_DIR/corpus /$FUZZ_DIR/crashes /$FUZZ_DIR/gcov |
| adb push ./corpus/* /$FUZZ_DIR/corpus/ >/dev/null 2>&1 |
| rm -rf ./logs ./coverage |
| |
| shift |
| fi |
| |
| adb logcat -c |
| if [ -z "$1" ]; |
| then |
| PAYLOAD=/$FUZZ_DIR/corpus |
| echo "Fuzzing with corpus from $PAYLOAD..." |
| else |
| PAYLOAD=$1 |
| echo "Verifying payload $PAYLOAD..." |
| fi |
| |
| adb shell mkdir -p /$FUZZ_DIR/corpus /$FUZZ_DIR/crashes /$FUZZ_DIR/gcov |
| adb shell LD_LIBRARY_PATH=/system/lib64/vndk-29 GCOV_PREFIX=/$FUZZ_DIR/gcov GCOV_PREFIX_STRIP=3 /$FUZZ_DIR/$FUZZER_NAME $FUZZ_OPTIONS $PAYLOAD |
| |
| echo "===========================================================================================" |
| adb logcat -d| $ANDROID_BUILD_TOP/external/compiler-rt/lib/asan/scripts/symbolize.py |
| } |
| |
| function run_fuzz() { |
| if [ "$1" == "-c" ]; |
| then |
| adb shell rm -rf /$FUZZ_DIR/corpus /$FUZZ_DIR/crashes /$FUZZ_DIR/gcov |
| adb shell mkdir -p /$FUZZ_DIR/corpus /$FUZZ_DIR/crashes /$FUZZ_DIR/gcov |
| adb push ./corpus/* /$FUZZ_DIR/corpus/ >/dev/null 2>&1 |
| rm -rf ./logs ./coverage |
| fi |
| |
| mkdir -p ./logs/ERROR ./logs/UNKNOWN ./coverage |
| while true |
| do |
| echo "Running ..." |
| TS=`date +"%m-%d-%Y-%H-%M-%S"` |
| run_once >./logs/fuzz.log 2>&1 |
| |
| echo "Fuzzer crashed, looking for crash input ..." |
| CRASH=$(grep -aoP "Test unit written to \K\S+" ./logs/fuzz.log) |
| if [ -z "$CRASH" ]; |
| then |
| echo "Error, crash not found!" |
| mv ./logs/fuzz.log ./logs/ERROR/run_$TS.log |
| continue |
| fi |
| |
| echo "Verifying crash ..." |
| run_once $CRASH >./logs/verify.log 2>&1 |
| SIG=$(grep -m 1 -aoP "#?? \S+ in \K\S+ system/nfc/src\S+:\S+" ./logs/verify.log) |
| if [ -z "$SIG" ]; |
| then |
| SIG='UNKNOWN' |
| cat ./logs/verify.log>>./logs/fuzz.log |
| else |
| cp ./logs/verify.log ./logs/fuzz.log |
| fi |
| |
| SIG_DIR=$(echo $SIG | tr " /:" '#@#') |
| if [ ! -d "./logs/$SIG_DIR" ]; |
| then |
| echo "New crash category found: $SIG" |
| mkdir -p ./logs/$SIG_DIR |
| else |
| echo "Known crash: $SIG" |
| fi |
| |
| mv ./logs/fuzz.log ./logs/$SIG_DIR/run_$TS.log |
| adb pull $CRASH ./logs/$SIG_DIR/crash_$TS.bin >/dev/null 2>&1 |
| adb rm $CRASH >/dev/null 2>&1 |
| done |
| } |
| |
| function build() { |
| pushd $ANDROID_BUILD_TOP |
| SANITIZE_HOST="address" \ |
| SANITIZE_TARGET="hwaddress fuzzer" \ |
| NATIVE_COVERAGE="true" \ |
| NATIVE_COVERAGE_PATHS="system/nfc/src" \ |
| make -j $FUZZER_NAME |
| popd |
| adb shell mkdir -p /$FUZZ_DIR |
| adb push $OUT/symbols/$FUZZ_DIR/$FUZZER_NAME /$FUZZ_DIR/ |
| } |
| |
| function run() { |
| if [ "$1" == "--once" ]; |
| then |
| shift |
| run_once $@ |
| else |
| echo "fuzzing..." |
| run_fuzz $@ |
| fi |
| } |
| |
| function debug() { |
| if [ -z "$1" ]; |
| then |
| echo "Which payload?" |
| exit |
| fi |
| |
| FUZZ_PAYLOAD=$1 |
| |
| adb forward tcp:5039 tcp:5039 |
| adb shell LD_LIBRARY_PATH=/system/lib64/vndk-29 gdbserver64 remote:5039 /$FUZZ_DIR/$FUZZER_NAME $FUZZ_OPTIONS $FUZZ_PAYLOAD 2>&1 >/dev/null& |
| sleep 5 |
| $ANDROID_BUILD_TOP/prebuilts/gdb/linux-x86/bin/gdb --directory=$ANDROID_BUILD_TOP -ex "target remote:5039" |
| } |
| |
| function get_cov() { |
| mkdir -p ./coverage && adb pull /$FUZZ_DIR/gcov/0/out/soong ./coverage |
| unzip -o $OUT/coverage/$FUZZ_DIR/$FUZZER_NAME.zip -d ./coverage |
| lcov --directory ./coverage --base-directory $ANDROID_BUILD_TOP --gcov-tool $(pwd)/../llvm-gcov --capture -o ./coverage/cov.info |
| TS=`date +"%m-%d-%Y-%H-%M-%S"` |
| genhtml ./coverage/cov.info -o ./coverage/report_$TS |
| xdg-open ./coverage/report_$TS/index.html |
| } |
| |
| function fuzz() { |
| init |
| action=$1 |
| shift |
| |
| case "$action" in |
| run) |
| run $@ |
| ;; |
| build) |
| build $@ |
| ;; |
| debug) |
| debug $@ |
| ;; |
| gcov) |
| get_cov $@ |
| ;; |
| *) |
| echo "Usage: $0 {run|build|debug|gcov}" |
| exit 1 |
| esac |
| } |
| |
| if [ "$0" == "${BASH_SOURCE[0]}" ]; |
| then |
| fuzz $@ |
| fi |
| |