Android默认支持libFuzzer,但需要编译插桩版本才能使用,而插桩版本需要以完整userdebug编译版本为起点继续编译,故需要编译两次。
0x1 编译环境搭建
系统:macOS 10.14
- 创建区分大小写的磁盘映像
$ hdiutil create -type SPARSE -fs 'Case-sensitive Journaled HFS+' -size 40g ~/android.dmg
以下命令可以用来调整映像大小$ hdiutil resize -size 80g ~/android.dmg.sparseimage
~/.bash_profile
中添加辅助函数
如果系统创建的是 .dmg.sparseimage 文件,将 ~/android.dmg 替换为 ~/android.dmg.sparseimage# mount the android file image
mountAndroid() { hdiutil attach ~/android.dmg -mountpoint /Volumes/android; }
# unmount the android file image
umountAndroid() { hdiutil detach /Volumes/android; }
- 安装xcode工具
$ xcode-select --install
- 下载安装对应版本MacPort
并添加环境变量export PATH=/opt/local/bin:$PATH
- 通过 MacPorts 获取 Make、Git 和 GPG 程序包
$ POSIXLY_CORRECT=1 sudo port install gmake libsdl git gnupg
macOS 10.4还需安装 bisonPOSIXLY_CORRECT=1 sudo port install bison
- 安装 JDK
Java SE 8 Archive Downloads
- 安装Android SDK
推荐使用homebrew安装$ brew cask install android-sdk
- 安装Android NDK
$ brew cask install android-ndk
- 安装Android Studio(可选)
$ brew cask install android-studio
- 设置文件描述符数量上限
将下列行添加到 ~/.bash_profile
or ~/.zshrc
中:# set the number of open files to be 1024
ulimit -S -n 1024
0x2 编译AddressSanitizer版Android
目标设备:pixel(sailfish)
使用调试模式 (aosp_sailfish-userdebug)
0x21 下载Android源码
- 安装repo工具
$ mkdir ~/bin
$ export PATH=~/bin:$PATH
$ curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo
$ chmod a+x ~/bin/repo
- 进入项目目录
$ cd /Volumes/android
初始化仓库
$ repo init -u https://android.googlesource.com/platform/manifest -b master
墙内可以使用清华源:
$ export REPO_URL='https://mirrors.tuna.tsinghua.edu.cn/git/git-repo/'
$ repo init -u https://aosp.tuna.tsinghua.edu.cn/platform/manifest -b master
下载源码树
源码有50g,下载时间较长
$ repo sync -c -j8
- 下载获取对应设备的驱动文件:
https://source.android.com/setup/build/requirements#binaries
master
分支选择预览Blob版本,其他分支从硬件支持二进制文件
选择对应版本
$ wget https://dl.google.com/dl/android/aosp/google_devices-sailfish-5057318-f64030a5.tgz
$ tar xvf google_devices-sailfish-5057318-f64030a5.tgz
$ ./extract-google_devices-sailfish.sh
$ wget https://dl.google.com/dl/android/aosp/qcom-sailfish-5057318-00f1c263.tgz
$ tar xvf qcom-sailfish-5057318-00f1c263.tgz
$ ./extract-qcom-sailfish.sh
$ . build/envsetup.sh
选择debug模式
$ lunch aosp_sailfish-userdebug
lunch不带任何参数会弹出选项,参考如下:
Buildtype |
用途 |
user |
有限的权限;适合一般用户 |
userdebug |
类似user模式,但有root权限和debug能力,适合debug |
eng |
带有额外的debug工具的开发配置。 |
网络问题
添加代理
$ export HTTP_PROXY=http://<proxy_user_id>:<proxy_password>@<proxy_server>:<proxy_port>
$ export HTTPS_PROXY=http://<proxy_user_id>:<proxy_password>@<proxy_server>:<proxy_port>
如果用的是ss代理
$ export ALL_PROXY=socks5://127.0.0.1:1080
取消代理
$ unset http_proxy
$ unset https_proxy
or
$ export HTTP_PROXY=""
$ export HTTPS_PROXY=""
0x22 编译userdebug版Android
- 设置 ccache优化编译环境(可选)
ccache 是适用于 C 和 C++ 的编译器缓存,有助于提高编译速度
在源代码树的根目录下执行以下命令$ export USE_CCACHE=1
$ mkdir ccache
$ export CCACHE_DIR=ccache
$ prebuilts/misc/darwin-x86/ccache/ccache -M 50G
将以下内容添加到 .bashrc(或等同文件)中export USE_CCACHE=1
没有ccache可以brew安装
- 执行完整的 Android 编译过程
通过执行以下命令来执行初始编译,编译时间较长:$ make -j$(nproc)
nproc是操作系统级别对每个用户创建的进程数的限制,要实现最快的编译速度,可以使用介于 make -j16 到 make -j32 之间的命令
- 将编译得到的版本刷入设备
解锁引导加载程序,刷入新编译的映像(-w
用于擦除用户数据)
刷机时,除必需刷入的*.img
文件,还需要android-info.txt
,刷完后备份这几个文件即可$ export ANDROID_PRODUCT_OUT=/Volumes/android/out/target/product/salifish
$ fastboot oem unlock
$ fastboot flashall -w
0x23 编译AddressSanitizer版Android
- 在userdebug版本基础之上执行插桩编译,并将修改后的二进制文件刷入设备
$ make -j$(nproc) SANITIZE_TARGET='address coverage'
$ fastboot flash userdata
$ fastboot flashall
- 检查插桩目录
官方文档称插桩编译会有以下目录,但编译的Android P和Android Q均无此目录$ adb root
$ adb shell ls -ld /data/asan/lib*
drwxrwx--x 6 system system 8192 2016-10-05 14:52 /data/asan/lib
drwxrwx--x 6 system system 8192 2016-10-05 14:52 /data/asan/lib64
编译时候遇到的坑
- 1、fatal error: linux/netfilter/xt_DSCP.h: No such file or directory
在对应目录下新建xt_DSCP.h文件:
/* based on ipt_FTOS.c (C) 2000 by Matthew G. Marsh <[email protected]>
* This software is distributed under GNU GPL v2, 1991
*
* See RFC2474 for a description of the DSCP field within the IP Header.
*
* xt_DSCP.h,v 1.7 2002/03/14 12:03:13 laforge Exp
*/
#ifndef _XT_DSCP_TARGET_H
#define _XT_DSCP_TARGET_H
#include <linux/netfilter/xt_dscp.h>
#include <linux/types.h>
/* target info */
struct xt_DSCP_info {
__u8 dscp;
};
struct xt_tos_target_info {
__u8 tos_value;
__u8 tos_mask;
};
#endif /* _XT_DSCP_TARGET_H */
- 2、sed: 1: “…”: invalid command code o
sed是linux命令,用于处理文件内容(修改,替换等),在mac下,sed -i
需要带一个字符串作为备份源文件的文件名称,如果这个字符串长度为0,则不备份。
如原指令,linux下可以执行成功,mac下会执行失败:$ sed -i "s/a/b/g" "example.txt"
指令修改如下:$ sed -i "_bak" "s/a/b/g" "example.txt"
or$ sed -i "" "s/a/b/g" "example.txt"
推荐使用brew工具重新安装gnu-sed,并使用--with-default-name
来覆盖原来的sed, 命令如下:$ brew install gnu-sed --with-default-names
- 3、dump process tree failed with: exit status 1
原因不明,重新执行make -j$(nproc)
即可
- 4、unknown type name ‘off64_t’; did you mean ‘off_t’?
将off64_t
修改为off_t
类似错误同理,macOS10.14默认只有64位,所以部分定义没有64标记
- 5、no member named ‘onClients’ in ‘android::hidl::manager::v1_2::IClentCallback’
打开./system/libhidl/+/master/transport/manager/1.2/IClientCallback.hal
文件,发现代码定义如下:oneway onNoClients(interface registered);
对比参考Google最新源码后,修改为:oneway onClients(interface registered, bool hasClients);
- 6、undefined reference to ‘android::base::MappedFile::FromFd(int,long long,unsigned int,int)’
提示的参数类型与源码不同,但本地与Google最新源码完全一致
应该是配置文件的问题,但检索不到文件,只好将本地代码参数修改为错误提示的类型,make通过
- 7、build/make/core/Makefile:28: error: overriding commands for target ‘out/target/product/sailfish/system/lib/libclcore_neon.bc’, previously defined at build/make/core/base_rules.mk:414
源码分支版本与驱动版本错误,换成对应版本
- 8、repo强制同步
强制与远程服务器同步,会删除对服务器文件的修改,但是不会删除添加到目录的新文件$ repo forall -c 'git reset --hard'
删除新添加的文件$ repo forall -c 'git clean -f -d'
- 9、ninja: ‘vender/qcom/marlin/······, missing and no know rule to make it
实际路径是vender/qcom/sailfish/
,未检索到相关配置文件,只好添加软链接:ln -s vender/qcom/sailfish/ vender/qcom/marlin/
- 10、unused parameter ‘time’ [-Werror,-Wunsed-parameter]
检索报错模块下的android.bp和Android.mk文件,删除编译标志-Werror
或者在Android.mk中添加标志禁用指定的Werror类型:LOCAL_CFLAGS += -Wno-error=format-security
- 11、当前shell关闭or重挂载
android.dmg
后,编译模式等参数会被修改,需重新配置
- 12、Could not find a supported mac sdk: [“10.10” “10.11” “10.12” “10.13”]
当前mac sdk版本不匹配引起的
- 13、
build/core/base_rules.mk: error: * already define by *
删除提示中前者的Android.pb
、Android.mk
、Makefile
,重构后再重新执行make$ rm -rf *
$ rm out/soon/.bootstrap/bin/soong_build out/soong/build.ninja
$ make -j8