1# Building the ART Fuzzer 2 3There are two ways to run one of the existing fuzzers: on host or on device. 4The building and running takes place in the full Android platform 5tree (aosp-main-with-phones). For host there's the possibility of using a 6smaller AOSP Android manifest (master-art). The latter is faster to build, 7because it only has the sources and dependencies required for the module. 8 9In the following tutorial we use the class verification fuzzer. We set a shell 10variable with the fuzzer's name for convenience. Their names can be found in 11the Android.bp file, under the cc_fuzz build rules. 12 13``` 14FUZZER_NAME=libart_verify_classes_fuzzer 15``` 16 17## Common steps for host and device 18 191. Navigate to the root directory of the android repository. 20 212. From the console, set up the development environment. 22 23 ``` 24 source build/envsetup.sh 25 ``` 26 273. Build the fuzzer for host/device 28 29 The command is composed of: 30 31 ``` 32 lunch <product>-trunk_staging-<variant> 33 SANITIZE_HOST=address make ${FUZZER_NAME} 34 ``` 35 36 For host you can use any valid lunch target, for example: 37 38 ``` 39 lunch silvermont-trunk_staging-eng 40 ``` 41 42 For device, you have to select your target according to the device 43 you are using it to run the fuzzer. 44 45 ``` 46 lunch aosp_husky-trunk_staging-userdebug 47 ``` 48 49## Host 50 514. Run the fuzzer 52 53 In this example we assume an x86_64 host architecture: 54 55 ``` 56 out/host/linux-x86/fuzz/x86_64/${FUZZER_NAME}/${FUZZER_NAME} \ 57 out/host/linux-x86/fuzz/x86_64/${FUZZER_NAME}/corpus 58 ``` 59 60 The first part of the command is the path to the fuzzer's binary, followed by the 61 corpus. See [llvm.org/docs/LibFuzzer](https://llvm.org/docs/LibFuzzer.html#options) 62 for more valid flags. For example, you can add the flag `-print_pcs=1` which makes 63 it more verbose. 64 65## Device 66 674. Add the fuzzer's files on the device 68 69 ``` 70 adb root 71 adb sync data 72 ``` 73 745. Run the fuzzer 75 76 Any supported architecture can be used. For example, for arm64: 77 78 ``` 79 adb shell /data/fuzz/arm64/${FUZZER_NAME}/${FUZZER_NAME} \ 80 /data/fuzz/arm64/${FUZZER_NAME}/corpus 81 ``` 82 83 The first part of the command is the path to the fuzzer's binary and the next 84 one is the corpus. 85 86## Corpus 87 88The fuzzer uses a corpus as a starting point in order to generate new inputs 89representing DEX files. Our current corpus contains a mix of hand-created DEX 90files, regression tests, and DEX files from our test suite. Also, when the fuzzer 91generates a new input and it proves that it offers more code coverage, 92it is added to the existing corpus as a DEX file. 93 94If you want to run with the initial corpus, it needs to be removed and built again. 95 96For host, assuming an x86_64 host architecture: 97 98``` 99rm -rf out/host/linux-x86/fuzz/x86_64/${FUZZER_NAME}/corpus 100SANITIZE_HOST=address make ${FUZZER_NAME} 101``` 102 103For device, you also need to sync the data. For example, for arm64: 104 105``` 106adb shell rm -rf /data/fuzz/arm64/${FUZZER_NAME}/corpus 107SANITIZE_HOST=address make ${FUZZER_NAME} 108adb sync data 109``` 110