内存检测_Android native内存检测工具介绍
点击上方蓝字关注我们噢~
检测工具不仅可以在验证时发现安全问题,也可以在运用场景中阻断安全问题的发生,对于安全问题检测和攻击拦截非常友好,当然安全检测功能会消耗一定的系统性能。本文将对已集成的部分检测工具进行介绍。
01
背景
Android系统添加了clang的编译特性,使C/C++代码编译时可以添加检测功能,针对内存安全问题进行检测。
Clang 12已经支持了很多类型的检测功能,包括Address Sanitizer、Thread Sanitizer、Memory Sanitizer、Undefined Behavior Sanitizer、Data Flow Sanitizer、Leak Sanitizer等。Android系统集成了部分检测工具能力。
02
检测工具介绍
1. Address Sanitizer
Address Sanitizer(ASan)用于检测代码中的内存错误,可以检测以下类型的错误:
1. 堆栈和全局变量的越界访问
2. 释放后使用
3. 返回后使用
4. 超出范围使用
5. 双重释放、错误释放
6. 内存泄露
下面通过一个示例来观察Address Sanitizer是如何检查内存错误的。下文中的代码是一个简单的内存释放后使用的案例:
int main(int argc,int char **argv) { int *array = new int[100]; delete [] array; return array[argc]; } |
创建UseAfterFree.cc文件,使用clang进行编译并且链接ASan参数-fsanitize=address。命令如下:
$clang++ -fsanitize=address UseAfterFree.cc -o AddressSanitizer.so
将未添加参数和添加参数的程序进行对比,可发现添加参数的程序插入了内存检查逻辑,如下所示:
添加参数的程序
未添加参数的程序
ASan的检测逻辑是通过内存映射进行的。其将内存分为两部分:主内存和影子内存,主内存是程序正常使用的,影子内存用于记录主内存是否可用。主内存每8个字节对应影子内存的一个字节。影子内存的地址是基于主内存计数的基础上偏移0x7FFF8000,计算方式如下:
64-bit:影子内存地址 = (主内存 >> 3) + 0x7FFF8000
32-bit:影子内存地址 = (主内存 >> 3) + 0x20000000
除了内存映射之外,ASan还在被保护的内存对象周围建立中毒状态的内存空间,并对中毒状态的影子内存做特殊标记。
如下图所示,主内存可全部访问,影子内存标记为00;主内存部分可访问,影子内存标记为可访问内存的大小:01-07;堆空间周围中毒状态内存标记为fa;释放后的堆空间标记为fd。还有很多其他的标记状态此处不详细列举。
内存标记示意图
对于检测原理和方式有了进一步的了解,下面对ASan在程序中的插桩代码进行分析。经过未添加参数和添加参数的程序的对比,可以观察到详细的区别。
首先在申请了内存空间后,添加了空间申请是否成功的检查。其次在内存释放后、内存访问前添加了检测逻辑。检测逻辑包含影子内存中的数值和最后一个双字内存空间的前k个字节是否可访问。
ASan检测逻辑说明
由于ASan检测工具性能影响较大,Android10和AArch64上的AOSP master分支已支持HWAddress Sanitizer(硬件辅助Address Sanitizer),此检测工具内存开销更小,代码空间也更小。
2. Bounds Sanitizer
Bounds Sanitizer (BoundSan) 用于对数组访问的边界检查。BoundSan是基于Undefined Behavior Sanitizer(UBSan)检测工具实现的,UBSan用于检查各种类型的未定义行为,例如使用空指针、有符号整数溢出、浮点类型转换溢出、数组索引边界溢出、枚举类型范围溢出等。
示例代码如下:
int main(int argc, char **argv) { int array[8]; int bound = 10 + argc; return array[bound]; } |
创建OutOfBounds.cc文件,使用clang编译并连接UBSan参数-fsanitize=bounds。编译命令如下:
clang++ -fsanitize=bounds OutOfBounds.cc -o BoundSan.exe
对比添加参数和未添加参数编译的程序,观察UBSan插入的检测逻辑,如下所示:
添加UBSan参数逻辑
未添加UBSan参数逻辑
相比于ASan提供的检测逻辑,UBSan提供的检测逻辑相对简单。在上图中可以观察到插桩代码仅仅检查了数组索引值是否超出了数组的最大长度,检测到问题后报告对应错误,如图所示:
3. Integer Overflow Sanitization
Integer Overflow Sanitization (IntSan)检测工具同样基于Undefined Behavior Sanitizer(UBSan)检测工具实现的,用于整数溢出检查,包括有符号和无符号整数溢出检查。
测试代码如下所示:
int sum(int input){ int k = 0x7fffffff; k += input; return k; } int main(int argc, char **argv){ int a = sum(argc); return a; } |
创建IntegerOverflow.cc,使用clang编译并连接UBSan参数-fsanitize=signed-integer-overflow。编译命令如下:
clang++ -fsanitize=signed-integer-overflow IntegerOverflow.cc -o IntSan.exe
若需要使用无符号溢出检查,则需要把参数变更为unsigned-integer-overflow,若有符号和无符号都需要,可以添加两个参数,用逗号隔开。
对比有无参数编译的程序,如下图所示,观察检测逻辑。
添加IntSan参数逻辑
未添加IntSan参数逻辑
图中红框标记的逻辑即为IntSan添加的溢出检测逻辑,其中if判断逻辑中__OFADD__()是IDA定义的宏,用于生成两数相加溢出的标记。
#define __OFADD__(x, y) invalid_operation // Generate overflow flag for (x+y)
03
总结
Android系统目前已支持了很多安全检测的工具或机制,除了本文介绍的三类,还包括:
堆分配器(Scudo):用于缓解堆相关的漏洞;
控制流完整性(CFI):用于保证程序的原始控制流图不被改变
只执行内存(XOM):用于缓解代码重用攻击;
影子调用堆栈(SCS):目前只支持aarch64,可保护程序返回地址被覆盖。
添加了安全检测功能后,对于系统的性能影响较大,所以在项目中实施安全检测功能时还需要验证和测试,android的配置参数支持黑名单或函数属性来停用安全检测功能,在不合理或者存在性能问题的代码谨慎使用。
参考:https://source.android.google.cn/devices/tech/debug/fuzz-sanitizehttps://clang.llvm.org/docs/index.htmlhttps://github.com/google/sanitizers/wiki
更多精彩阅读Soot在Android组件NPE拒绝服务检测中的应用如何用lint扫出不安全代码如何用OLLVM来保护你的关键代码
长按关注 更多安全技术干货等你发现
好文!在看吗?点一下鸭!
内存检测_Android native内存检测工具介绍相关推荐
- android native堆内存泄露,Android Native内存泄露检测
Android Studio没有提供直接的Native层的内存泄露检测工具,但我们仍可以通过开源工具进行动态检测和静态检测 动态检测 在APP运行时进行检测,就像LeakCanary Update: ...
- 如何排查Java内存泄露(内附各种排查工具介绍)
今天刚刚才加一个故障review会议, 故障非常典型, google下也可以找到相似案例介绍. 在排查问题的过程中,使用了大量的工具, 发现有问题的地方还不只一个,总结一下. (本篇文章不会重点描述案 ...
- java 匿名内部类内存泄露_Android 常见内存泄露 解决方案
前言 内存泄漏(Memory Leak)是指程序中己动态分配的堆内存由于某种原因程序未释放或无法释放,造成系统内存的浪费,导致程序运行速度减慢甚至系统崩溃 (OOM) 等严重后果. 那什么情况下不能被 ...
- android 内存分析工具_Android Camera内存问题剖析
本文通过一类 Android 机型上相机拍摄过程中的 native 内存 OOM 的问题展开,借助内存快照裁剪回捞和 Native 内存监控工具的赋能,来深入剖析此类问题. 背景 Raphael 是西 ...
- 我们有一个线上的项目,刚启动完就占用了超过 1.5G,一次大量 JVM Native 内存泄露的排查分析(64M 问题)
我们有一个线上的项目,刚启动完就占用了使用 top 命令查看 RES 占用了超过 1.5G,这明显不合理,于是进行了一些分析找到了根本的原因,下面是完整的分析过程,希望对你有所帮助. 会涉及到下面这些 ...
- Android C++ Native 内存泄露检查工具Raphael使用介绍
Android C++ Native 内存泄露检查工具使用介绍 实现原理 使用方法 Raphael添加到测试apk 添加项目依赖 同步gradle 启动泄露检测功能 直接使用boardcast功能控制 ...
- 计算机存储程序错误检验,内存错误怎么办?内存错误的修复与检测方法介绍
导语: 电脑具有存储功能,这点毋庸置疑,一款电脑的内存大小能够在一定程度上决定这款产品的性能.但是,我们电脑用户在使用电脑的过程中常常会遇到电脑内部才能错误的故障.那么,内存错误的原因是什么?电脑内存 ...
- java内存泄漏怎么检测_JAVA内存泄漏原因和内存泄漏检测工具
JAVA内存泄漏原因和内存泄漏检测工具 摘要 虽然Java 虚拟机(JVM)及其垃圾收 集器(garbage collector,GC)负责管理大多数的内存任务,Java 软件程序中还是有可能出现内 ...
- 使用Xcode7的Instruments检测解决iOS内存泄露
文/笨笨的糯糯(简书作者) 原文链接:http://www.jianshu.com/p/0837331875f0 著作权归作者所有,转载请联系作者获得授权,并标注"简书作者". 作 ...
最新文章
- folder ground 文件访问
- POJ_2104 K-th Number 【主席树】
- Master公式(计算递归复杂度)
- 初识NIO之Java小Demo
- VC创建DLL动态链接库及其调用
- Java 算法 质数的后代
- activitimq集群搭建_Spring-activiti
- mysql 体重 类型 身高_MySQL 数据类型
- ubuntu 14.04 64bit 安装 oracle 11g r2
- Python反向列表
- Markdown 写作类软件 MWeb 和 Ulysses谁更好
- ConcurrentLinkedQueue 的outofMemory错误解决方案
- WAP技术入门(下)
- HBase 数据库介绍
- Linux下载工具photon,不限速、免配置的 Aria2 免费开源下载软件 Photon,替代迅雷的...
- 冰山數據登榜《互联网周刊》2022数据标注公司排行
- 小冰岛——小户赛茶的特点
- synchdem matlab,数字高程模型(DEM)移动插值算法
- 蓝桥杯2020第二场JAVA C真题
- php if相关标签,dedecms模板中运用dede标签时使用php和if判断语句的方法