Android(七)macOS平台编译Android源码
学习笔记,参考:通过 libFuzzer 进行模糊测试
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 程序包
macOS 10.4还需安装 bison$ POSIXLY_CORRECT=1 sudo port install gmake libsdl git gnupg
POSIXLY_CORRECT=1 sudo port install bison
- 安装 JDK
Java SE 8 Archive Downloads- Android 7.0 (Nougat) - Android 8.0 (O):Ubuntu - OpenJDK 8;Mac OS - jdk 8u45 或更高版本
- Android 5.x (Lollipop) - Android 6.0 (Marshmallow):Ubuntu - OpenJDK 7;Mac OS - jdk-7u71-macosx-x64.dmg
- Android 2.3.x (Gingerbread) - Android 4.4.x (KitKat):Ubuntu - Java JDK 6;Mac OS - Java JDK 6
- Android 1.5 (Cupcake) - Android 2.2.x (Froyo):Ubuntu - Java JDK 5
.bash_profile
添加环境变量$echo JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home >> ~/.bash_profile $ export JAVA_HOME >> ~/.bash_profile $ export PATH=$JAVA_HOME/bin:$PATH >> ~/.bash_profile $ source ~/.bash_profile
- 安装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)
使用调试模式 (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++ 的编译器缓存,有助于提高编译速度
在源代码树的根目录下执行以下命令
将以下内容添加到 .bashrc(或等同文件)中$ export USE_CCACHE=1 $ mkdir ccache $ export CCACHE_DIR=ccache $ prebuilts/misc/darwin-x86/ccache/ccache -M 50G
没有ccache可以brew安装export USE_CCACHE=1
- 执行完整的 Android 编译过程
通过执行以下命令来执行初始编译,编译时间较长:
nproc是操作系统级别对每个用户创建的进程数的限制,要实现最快的编译速度,可以使用介于 make -j16 到 make -j32 之间的命令$ make -j$(nproc)
- 将编译得到的版本刷入设备
解锁引导加载程序,刷入新编译的映像(-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"
or$ sed -i "_bak" "s/a/b/g" "example.txt"
推荐使用brew工具重新安装gnu-sed,并使用$ sed -i "" "s/a/b/g" "example.txt"
--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
文件,发现代码定义如下:
对比参考Google最新源码后,修改为:oneway onNoClients(interface registered);
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版本不匹配引起的- 1、去https://github.com/phracker/MacOSX-SDKs下载对应sdk版本,如
10.13
- 2、将下载的sdk解压后放在目录
/Applications/XCode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/
中 - 3、执行
$ sudo xcode-select -s /Applications/Xcode.app/Contents/Developer
- 1、去https://github.com/phracker/MacOSX-SDKs下载对应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
0 评论:
发表评论