时时勤拂拭,勿使惹尘埃

TOC

Categories

Android(七)macOS平台编译Android源码



学习笔记,参考:通过 libFuzzer 进行模糊测试
Android默认支持libFuzzer,但需要编译插桩版本才能使用,而插桩版本需要以完整userdebug编译版本为起点继续编译,故需要编译两次。

0x1 编译环境搭建

系统:macOS 10.14
  1. 创建区分大小写的磁盘映像
    $ 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; }
    
  2. 安装xcode工具
    $ xcode-select --install
    
  3. 下载安装对应版本MacPort
    并添加环境变量
    export PATH=/opt/local/bin:$PATH
    
  4. 通过 MacPorts 获取 Make、Git 和 GPG 程序包
    $ POSIXLY_CORRECT=1 sudo port install gmake libsdl git gnupg
    
    macOS 10.4还需安装 bison
    POSIXLY_CORRECT=1 sudo port install bison
    
  5. 安装 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
      
  6. 安装Android SDK
    推荐使用homebrew安装
    $ brew cask install android-sdk
    
  7. 安装Android NDK
    $ brew cask install android-ndk
    
  8. 安装Android Studio(可选)
    $ brew cask install android-studio
    
  9. 设置文件描述符数量上限
    将下列行添加到 ~/.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源码

  1. 安装repo工具
    $ mkdir ~/bin
    $ export PATH=~/bin:$PATH
    $ curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo
    $ chmod a+x ~/bin/repo
    
  2. 进入项目目录
    $ cd /Volumes/android
    
  3. 初始化仓库
    $ 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
    
  4. 下载源码树
    源码有50g,下载时间较长
    $ repo sync -c -j8
    
  5. 下载获取对应设备的驱动文件:
    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

  1. 设置 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安装
  2. 执行完整的 Android 编译过程
    通过执行以下命令来执行初始编译,编译时间较长:
    $ make -j$(nproc)
    
    nproc是操作系统级别对每个用户创建的进程数的限制,要实现最快的编译速度,可以使用介于 make -j16 到 make -j32 之间的命令
  3. 将编译得到的版本刷入设备
    解锁引导加载程序,刷入新编译的映像(-w用于擦除用户数据)
    刷机时,除必需刷入的*.img文件,还需要android-info.txt,刷完后备份这几个文件即可
    $ export ANDROID_PRODUCT_OUT=/Volumes/android/out/target/product/salifish
    $ fastboot oem unlock
    $ fastboot flashall -w
    

0x23 编译AddressSanitizer版Android

  1. 在userdebug版本基础之上执行插桩编译,并将修改后的二进制文件刷入设备
    $ make -j$(nproc) SANITIZE_TARGET='address coverage'
    $ fastboot flash userdata
    $ fastboot flashall
    
  2. 检查插桩目录
    官方文档称插桩编译会有以下目录,但编译的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版本不匹配引起的
    • 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
      
  • 13、build/core/base_rules.mk: error: * already define by *
    删除提示中前者的Android.pbAndroid.mkMakefile,重构后再重新执行make
    $ rm -rf *
    $ rm out/soon/.bootstrap/bin/soong_build out/soong/build.ninja
    $ make -j8
    

0 评论:

发表评论