2017-08-15 18:15 来源:谷歌开发者 程序设计 /Android /操作系统 原标题:如何利用Sanitizer解决Android中的Bug? 文 / Google Android 安全团队 Dan Austin LLVM 是构建 Android 所使用的编译器基础架构,包含多个用于执行静态和动态分析的组件。在分析 Android 时,得到广泛使用的一组组件是擦除器,特别是 AddressSanitizer、UndefinedBehaviorSanitizer 和 SanitizerCoverage。 这些擦除器是包含在 compiler-rt 中的基于编译器的仪器测试组件,可在开发和测试过程中用于消除错误和优化 Android。Android 中当前提供的这些擦除器可以发现和诊断多种内存滥用错误和未定义的行为,还可以提供代码覆盖指标,确保您的测试套件尽可能面面俱到。 本文将详细介绍现有 Android 擦除器(AddressSanitizer、UndefinedBehaviorSanitizer 和 SanitizerCoverage)的内部结构,并演示可以如何在 Android 构建系统中使用它们。 Address Sanitizer AddressSanitizer (ASan) 是一项基于编译器的仪器测试功能,可在运行时检测 C/C++ 代码中的多种内存错误。在 Android 中,已经测试了对下列内存错误类型的检查功能: 堆、堆叠和全局变量的越界访问 释放后使用 返回后使用(运行时标志 ASAN_OPTIONS=detect_stack_use_after_return=1) 范围后使用(clang 标志 -fsanitize-address-use-after-scope) 重复释放,无效释放 Android 可通过 ASan 执行全面的构建仪器测试,还可以通过 asanwrapper 执行应用级的 ASan 仪器测试。关于这两种仪器测试技巧的说明均可在 source.android.com 中找到。 AddressSanitizer 基于以下两个高级概念。第一个概念是针对与内存有关的所有函数调用(包括 alloca、malloc 和 free 等)执行仪器测试并输出用于跟踪内存分配、释放和使用情况统计的信息。通过此仪器测试,j2直播,ASan 可检测无效的内存使用错误,包括重复释放、范围后使用、返回后使用和释放后使用等错误。ASan 还可以检测在定义的内存区域边界外发生的读写操作。为完成此检测,它填充所有分配的内存缓冲区和变量。如果对此填充区域进行读或写,直播,ASan 将捕获此操作,并输出有助于诊断内存违例的信息。在 ASan 术语中,此填充被称为中毒内存。 下面是包含堆叠分配变量的中毒内存填充布局示例: ▲ ASANified 堆叠变量示例,此变量包含一个由 8 个元素组成的 int8_t 数组、一个 uint32_t 数组和一个由 16 个元素组成的 int8_t 数组。右侧显示使用 ASAN 编译后的内存布局,其中每个变量之间插入填充。对于每个堆栈变量,变量前后有 32 个填充字节。如果一个变量的对象大小不是 32 个字节,则插入 32 - n 个额外的填充字节,其中 n 是对象大小。 ASan 使用影子内存跟踪哪些字节为正常内存,哪些字节为中毒内存。字节可以标记为完全正常(在影子内存中标记为 0)、完全中毒(设置对应影子字节的高位)或前面 k 个字节未中毒(影子字节值为 k)。如果影子内存显示某个字节中毒,则 ASan 会使程序崩溃,并输出有用的调试信息,包括调用堆栈、影子内存映射、内存违例类型、读取或写入的内容、导致违例的计算机以及内存内容。 AddressSanitizer: heap-buffer-overflow on address 0xe6146cf3 at pc 0xe86eeb3c bp 0xffe67348 sp 0xffe66f14WRITE of size 39 at 0xe6146cf3 thread T0 #0 0xe86eeb3b (/system/lib/libclang_rt.asan-arm-android.so+0x64b3b) #1 0xaddc5d27 (/data/simple_test_fuzzer+0x4d27) #2 0xaddd08b9 (/data/simple_test_fuzzer+0xf8b9) #3 0xaddd0a97 (/data/simple_test_fuzzer+0xfa97) #4 0xaddd0fbb (/data/simple_test_fuzzer+0xffbb) #5 0xaddd109f (/data/simple_test_fuzzer+0x1009f) #6 0xaddcbfb9 (/data/simple_test_fuzzer+0xafb9) #7 0xaddc9ceb (/data/simple_test_fuzzer+0x8ceb) #8 0xe8655635 (/system/lib/libc.so+0x7a635)0xe6146cf3 is located 0 bytes to the right of 35-byte region [0xe6146cd0,0xe6146cf3)allocated by thread T0 here: #0 0xe87159df (/system/lib/libclang_rt.asan-arm-android.so+0x8b9df) #1 0xaddc5ca7 (/data/simple_test_fuzzer+0x4ca7) #2 0xaddd08b9 (/data/simple_test_fuzzer+0xf8b9)SUMMARY: AddressSanitizer: heap-buffer-overflow (/system/lib/libclang_rt.asan-arm-android.so+0x64b3b) Shadow bytes around the buggy address: 0x1cc28d40: fa fa 00 00 00 00 07 fa fa fa fd fd fd fd fd fd 0x1cc28d50: fa fa 00 00 00 00 07 fa fa fa fd fd fd fd fd fd 0x1cc28d60: fa fa 00 00 00 00 00 02 fa fa fd fd fd fd fd fd 0x1cc28d70: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x1cc28d80: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa=>0x1cc28d90: fa fa fa fa fa fa fa fa fa fa 00 00 00 00[03]fa 0x1cc28da0: fa fa 00 00 00 00 07 fa fa fa 00 00 00 00 03 fa 0x1cc28db0: fa fa fd fd fd fd fd fa fa fa fd fd fd fd fd fa 0x1cc28dc0: fa fa 00 00 00 00 00 02 fa fa fd fd fd fd fd fd 0x1cc28dd0: fa fa 00 00 00 00 00 02 fa fa fd fd fd fd fd fd 0x1cc28de0: fa fa 00 00 00 00 00 02 fa fa fd fd fd fd fd fdShadow byte legend (one shadow byte represents 8 application bytes): Addressable: 00 Partially addressable: 01 02 03 04 05 06 07 Heap left redzone: fa Freed heap region: fd Stack left redzone: f1 Stack mid redzone: f2 Stack right redzone: f3 Stack after return: f5 Stack use after scope: f8 Global redzone: f9 Global init order: f6 Poisoned by user: f7 Container overflow: fc Array cookie: ac Intra object redzone: bb ASan internal: fe Left alloca redzone: ca Right alloca redzone: cb 有关报告各个部分的含义以及如何提高其易读性的更多信息,可查看 LLVM 网站: https://clang.llvm.org/docs/AddressSanitizer.html 和 Github: https://github.com/google/sanitizers/wiki/AddressSanitizer (责任编辑:本港台直播) |