之前写了一篇文章,是关于asan的使用:AddressSanitizer & UndefinedBehaviorSanitizer & BoundSanitizer在Android中的使用 实际这篇文章就是对aosp文档的翻译,在实际使用过程中,发现google的文档写的比较简单。
另外,可能是版本的原因,有些配置并不适合最新的Android系统,本文使用的Android版本为11和12,因此本文所述的内容大概适用于这两个版本,随着不断的版本升级,以后这篇文章大概也会过时吧
关于asan的介绍可以先看下上面的文章,本文主要总结一些经验
1.如何更方便的使用asan?
作为一个系统开发者,最简单的使用方式就是使用asan整编所有code,然后烧写所有image.方式如下:
source build/envsetup.sh
lunch xxx
make –jxx
SANITIZE_TARGET=address make –jxx
在实际使用过程中,asan对内存和CPU的影响开销还是比较大的,内存比较小的话,如1.5G内存,是无法亮屏的。
或者,有些模块开发者也不需要检查所有服务,只是关注于自己的服务,因此,我更推荐下面你的使用方式。
2. 整编于部分编译的结合,实际使用的方式?
请注意,使用asan编译的so不再生成到system或vendor下面,而是生成到userdata分区,因此,实际开发中,下面这种方式更方便:
- 正常编译一遍:source, lunch, make
- 使用asan完整编译一次:SANITIZE_TARGET=address make –jxx [可选,Android12遇到abi build error使用SKIP_ABI_CHECKS=true]
- 使用fastboot单独烧写userdata.img
- 修改指定bin文件的Android.bp或Android.mk
- 完成第4步后,正常编译
- 再单独烧写bin文件所在的分区,如vendor.img
- 如想检查其它的native bin,重复4-6步即可
这样做的优点,可以针对性调试特定 Native bin,而且不用关心需要打开哪些 lib 的 asan
3. 如何检查所有app?
ASan 无法检查 Java 代码,但可以检测 JNI 库中的错误。为此,您需要使用 ASan 构建可执行文件(在此情况下是 /system/bin/app_process(32|64))。这将在设备上的所有应用中同时启用 ASan,因而负载非常大,但 2 GB RAM 的设备应该能够从容应对。
4. 如何单独检查一个app?
这里发现使用aosp中文档的方法不太适用,实际像下面这样操作是可以的。
步骤1:使用asan编译app_process,并生成到system/bin/asan/app_process
command:按下面修改完成后,直接编译Android,make -jxx
步骤2:将asan下面的app_process push到开发板
command:使用adb sync或adb push,将asan编译的app_process,生成到system/bin/asan/app_process
注意:不要直接烧写system.img
步骤3:获取app的native lib path
Command:adb shell pm dump PACKAGE_NAME
对于 32 位程序需要在上面那个 path 后面加上一级 arm 目录,上面例子就是/product/app/xxxLauncherLite/lib/arm/
这个目录
步骤4:添加wrap.sh
脚本,并添加可执行权限
Command: mkdir&adb push
![](https://adtxl.com/usr/uploads/2022/05/108565465.png)#!/system/bin/sh
shift
set -- "/system/bin/asan/app_process $@"
exec $@
最终状态如下:
步骤5:关闭selinux,kill掉相关进程,结果验证
Command: setenforce 0
5. 不检查app,只想检查native bin
这个称为 asan lite 功能,因为 App 有虚拟机,如果打开 asan,内存需求明显,那么可以只打开 Native asan
1.正常编译一次:make –jxx
2.使用asan lite完整编译一遍:SANITIZE_LITE=true SANITIZE_TARGET=address make -jxx
3.烧写所有image
6. 如何确定进程是否使用了asan编译的so?
可以通过读取/proc/$PID/maps
,验证是否使用了asan编译的so
如果不是,可以尝试关闭selinux
adb root
adb shell setenforce 0
# restart the process with adb shell kill $PID # if it is a system service, or may be adb shell stop; adb shell start.
另一种方法,通过linker判断
linker 中会检查 bin 程序的 interpreter 是否如框内容,如果是的话,就使用 asan 的 namespace,从而会优先引用 /data/asan/ 下面的 lib.
程序的 interpreter 可以通过 readelf -e BIN_NAME 查看,类似下图
评论