Fuzz测试之libfuzzer高频报错问题FAQ

Fuzz测试之libfuzzer高频报错问题FAQ

    • 场景问题
    • 报错解决
      • 编译阶段
      • 运行阶段
    • 进阶资料

本文小结fuzz测试遇到的高频问题及其解答。

场景问题


Q:fuzz主调函数OneInput/Initialize区别?
A:前者fuzz而框架的main函数中无限次循环,后者仅开始运行时调用初始化一次。

Q:如何调用手机当前fuzz目录下的动态库?

A:由于非系统路径动态库,每次运行的时候都需要提前手动配置下。解决方法如下

  • 法1:运行时链接当前xx目录下的动态库,指令:export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/data/local/tmp/xx
  • 法2:运行时链接指定xx.so动态库,指令:export LD_PRELOAD=/usr/lib/gcc/aarch64-linux-gnu/7.5.0/xx.so
  • 法3:运行可执行文件时指定链接动态库目录,指令:LD_LIBRARY_PATH=./lib/ ./demo_exe -max_len=65535 -len_control=0 -detect_leaks=0 ./corpus

Q:如何回归测试fuzz崩溃的某条码流?

A:末尾指定对应特定码流文件路径,指令:LD_LIBRARY_PATH=./lib/ ./demo_exe -max_len=65535 -len_control=0 -detect_leaks=0 ./crash-ce3xfaf6a5217xxxbf5f95fafa103

Q:如何保存测试崩溃的码流,并指定其文件名前缀?

A:prefix表示后面加的指定码流前缀文件名,./corpus表示保存到当前corpus目录下。指令:LD_LIBRARY_PATH=./lib/ ./demo_exe -max_len=65535 -len_control=0 -artifact_prefix=./corpus_crash -detect_leaks=1 ./corpus

Q:运行指令不同参数分别代表什么意思?

A:以当前指令为例,指令:LD_LIBRARY_PATH=./lib/ ./demo_exe -max_len=65535 -len_control=0 -artifact_prefix=./corpus_crash -detect_leaks=1 ./corpus

  • LD_LIBRARY_PATH,表示当前非系统动态库目录链接路径
  • max_len,设定输入的bytes乱流最大字节数
  • len_control,表示len的控制方式,默认为100,从小到大增长;为0,表示直接按最大len(max_len)来测试
  • -detect_leaks=0,不开启内存泄漏检测,加快fuzz速度
  • -rss_limit_mb=4096,给予4096M的内存使用空间
  • -corpus,存放当前的测试用例输入存放位置,本例中表示码流,对应oneinput中的data输入

Q:运行fuzz过程中的提示含义如何解读?

A:比如:\#52724 cov: 5041 ft: 24878 corp: 501/16Mb lim: 65535 exec/s: 4 rss: 97Mb L: 64554/65535 MS: 4 ChangeByte-CopyPart-CrossOver-ChangeBinInt,参数解读如下:

  • #52724:表示已经测试过52724个数据
  • cov:当前已经覆盖的代码块或边数
  • ft:尝试覆盖率的信号个数
  • corp:当前随机序列的入口个数,及其所占用的内存大小
  • lim:当前最大maxlen为65535字节,对应的oneinput函数中的size
  • exec/s:迭代速度,每秒xx次
  • rss:当前内存消耗
  • L:当前输入的实际所占字节

报错解决


编译阶段

报错:ld: error: undefined symbol: std::__ndk1::basic_string, std::__ndk1::allocator >::resize(unsigned long, char)

error:linker command failed with exit code 1

ld: error: undefined symbol: std::__ndk1::basic_streambuf::~basic_streambuf()

>>> FuzzerDataFlowTrace.cpp.o:(fuzzer::Command::toString() const) in archive D:/ProgramData/android-ndk-r23c/build//…/toolchains/llvm/prebuilt/windows-x86_64\lib64\clang\12.0.9\lib\linux\libclang_rt.fuzzer-aarch64-android.a

>>> referenced 18 more times

分析解决

  • 根因:未在application.mk中链接C++相关的基础库
  • 解决:在application.mk中,添加代码行:APP_STL := c++_shared

编译报错:无main函数等

ld: error: undefined symbol: LLVMFuzzerTestOneInput

>>> referenced by FuzzerMain.cpp:20 (out/llvm-project/compiler-rt/lib/fuzzer\FuzzerMain.cpp:20)

>>> FuzzerMain.cpp.o:(main) in archive D:/ProgramData/android-ndk-r23c/build//…/toolchains/llvm/prebuilt/windows-x86_64\lib64\clang\12.0.9\lib\linux\libclang_rt.fuzzer-aarch64-android.a

>>> did you mean to declare LLVMFuzzerTestOneInput(unsigned char const*, unsigned long) as extern “C”?【关键】【】【】

分析解决:

  1. andriod.mk中添加:cflags/ldflags要同时使用(以便于自动调用llvm的fuzzer main框架),这里可以解决无main问题,调用fuzzer框架里的main
LOCAL_CFLAGS += -fsanitize=fuzzer -fno-omit-frame-pointer
LOCAL_LDFLAGS += -fsanitize=fuzzer
  1. cc文件为CPP代码编译,其中C代码函数要用宏定义隔开,以免函数类型定义用cpp的方式导致无法
...cpp code

#ifdef __cplusplus

extern "C" {

#endif

...c code

#ifdef __cplusplus

}

#endif

参考:https://stackoverflow.com/questions/48699256/clang-libfuzzer-undefined-reference-to-sanitizer-cov-trace-const-cmp8

运行阶段

报错:无程序报错行的具体偏移地址,无法反解析。ERROR: AddressSanitizer: heap-buffer-overflow on address

=25006==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x0050af50e175 at pc 0x006fd1344550 bp 0x007ffb7aeb10 sp 0x007ffb7ae2a0

READ of size 8300 at 0x0050af50e175 thread T0

AddressSanitizer:DEADLYSIGNAL

AddressSanitizer: nested bug in the same thread, aborting.

分析解决:

  • 原因:手机运行缺乏clang生成的asan动态库,无法打桩得到具体出问题的函数信息
  • 解决:
    • 找到编译附带生成的库:libclang_rt.asan-aarch64-android.so,与libc++_shared.so和可执行文件同目录
    • 同时注意编译选项:-g, o0

报错:CANNOT LINK EXECUTABLE “./demo_exe”: cannot locate symbol “__emutls_get_address”

CANNOT LINK EXECUTABLE "./demo_exe: cannot locate symbol “__emutls_get_address” referenced by “/data/local/tmp/”…

分析解决:

  • 根因:无C++基础动态库:libc++_shared.so
  • 解决:
    • application.mk中添加:APP_STL := c++_shared
    • 推入生成的库文件libc++_shared.so到手机
    • 当前文件夹作为链接库,指令:export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/data/local/tmp/xx

进阶资料


  1. The Art of Fuzzing - Demo 3: LibFuzzer Demonstration
  2. llvm-symbolizer指令解析官方详解,link

你可能感兴趣的:(效率工具,linux,android,fuzz测试,libfuzzer)