Summary of the use of libfuzzer for Fuzz testing
background
In the project, in order to test the robustness of the algorithm, fuzz testing is often used for stress testing. Fuzz testing is a fuzz testing method, which essentially traverses different function branches by injecting various mutated random data to expose possible problems in the program.
*
Next, this article takes the libFuzzer tool that comes with LLVM on the Android platform as an example to briefly introduce its usage.
Fundamental
Before learning how to use it, first understand its basic operation principle. In LLVM, first call the initialization interface once LLVMFuzzerInitialize
to set parameters, and then repeatedly call the interface LLVMFuzzerTestOneInput
to continuously pour in random data of different lengths until the program reaches the maximum operating limit or finds a bug in the middle before interrupting and exiting.
Instructions
required environment
- computer hardware
- NDK compilation software, using NDK-R20 and above versions, its clang compiler comes with address sanitization and fuzz test modules
- adb software, used for joint debugging of computer and mobile phone
- Android phone (with developer options available)
needed file
- CPP keynote:
- xx_fuzz.cc
- Compile the script:
- andriod.mk
- application.mk
- Algorithm source code to be tested
- xx.c
basic process
- The computer uses NDK to compile source files and generate executable files
- Added in andriod.mk
- Compile options:
LOCAL_CFLAGS += -fsanitize=fuzzer,address -fomit-frame-pointer
- Link options:
LOCAL_LDFLAGS += -fsanitize=fuzzer,address
- The address option is to open the asan address disinfection function, which can enhance the ability to find bugs
- Compile options:
- Add in application.mk
- Standard library:
APP_STL := c++_shared
- Because the scheduling code is written in CPP, the STL library is required
- Standard library:
- Open powershell, in the directory where the mk file is located,
ndk-build
compile the executable file through instructions
- Added in andriod.mk
- Push to the mobile phone folder through the ADB software push
- Copy the executable file and dynamic library file (such as:
libclang_rt.asan-aarch64-android.so
andlibc++_shared.so
) generated in the previous step - Push it into the phone, such as
/data/local/tmp/xx_fuzz/
- Command example:
adb push xx.so /data/local/tmp/xx_fuzz/
- Command example:
- Copy the executable file and dynamic library file (such as:
- Enter the relevant command through ADB to start the running program on the mobile phone
- Connect the computer to the Android phone, and the phone enters developer mode
- Computer command window, input
adb shell
, enter the mobile phone environment - Switch to the directory corresponding to the executable file, enter the following command, and run the program
LD_LIBRARY_PATH=./ ./demo_exe -max_len=65535 -len_control=0 -artifact_prefix=./corpus/ -detect_leaks=0 ./corpus
- Parse the error log
- According to the error information fed back by the mobile phone environment, such as offset address 0x226534
- Add the directory where the llvm-symbolizer.exe that comes with ndk is located to the path of the computer environment variable
- Enter the following commands in the command window to analyze the error-related code context, analyze the algorithm, and fix bugs
- instruction:
llvm-symbolizer -e=demo_exe 0x226534 --print-source-context-lines=3
- Mode: llvm-symbolizer -e=library name or EXE name error display offset address
- instruction:
- key steps
- Turn on the compilation option of the fuzz test and compile successfully
- LLVMFuzzerInitialize/LLVMFuzzerTestOneInput caller code writing
- Precautions
- There is no need to write the main function in the main demo, the main is provided by the libfuzzer framework
- When the c and cpp codes are jointly compiled, macros are required to distinguish function names
For specific MK file compilation script instructions, see " NDK Compilation Series: Building C/CPP Projects ".
Main tone DEMO
xx_fuzz.cc
The two interface functions in the main call used in the above process , the framework template is as follows:
#include <stddef.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <math.h>
#ifdef __cplusplus
extern "C" {
#endif
int LLVMFuzzerInitialize(int argc, char **argv)
{
// write your code
return 0;
}
int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len)
{
// write your code
return 0;
}
#ifdef __cplusplus
}
#endif
Further, for specific usage, please refer to: libfuzzer from getting started to giving up .