AOSP 编译及基础反调试


研究 Android ,从编译 AOSP 开始。

为了保证文章的时效性,一些操作可能会直接贴上教程的原地址。

https://wiki.archlinux.org/title/Android#Building

LineageOS

需要安装 17.1,因为逆向方便(

https://wiki.lineageos.org/devices/coral/build/ 其中需要提取私有驱动,而 17.1 的包难找,注意提取的时候,命令是

./extract-files.sh --coral adb

文档中没提到。

LineageOS Archive —— 包含所有历史版本的 LineageOS,不过不包含 Recovery,用 payload-dumper-goAUR 可以提取。(参考

root 方法:只需要用 Magisk patch Recovery 就行。 

breakfast lineage_coral-userdebug
# 也可以编译单独的模块
make snod # "System, NO Dependencies",用 make help 查看所有选项

编译好了之后,进入 fastbootd(fastboot reboot fastboot),然后 fastboot flashall -w

不过 /system/xbin/su 不见了,不懂什么情况,也没有编译出来,先了解下构建系统吧。不过目前也能用,因为开发者选项里面可以打开 adb root

 

依赖

需要一个 ttf,就用 ttf-firacode-nerd 了,还需要一个 aosp-develAUR

一些推荐的依赖

Optional dependencies for aosp-devel
- java-environment: required for building Android 8 and older [installed]
- ccache: used for caching build output at a compiler level
- wxgtk2: may be required for building old Android versions
- python2-virtualenv: used to make python2 the default for building Android 10 and older
 

硬件

在 16 core 32 GB RAM 下,测试结果如下:

  1. native 部分的增量编译只需要1分钟,java 部分的还没测。
  2. 如果修改了 Android.bp,就需要大概3分钟。

 

2025-05-06 更新

可以启动 ccache 以显著加速编译,见 Wiki

 

下载源码

repo init --partial-clone -b main -u https://android.googlesource.com/platform/manifest
repo sync -j8 -c

-j 选择下载线程数

-c 仅同步当前分支的源码

注意:如果想刷入物理设备,且物理设备不在 main 分支所支持的设备下 那就在 tags 列表 中找到设备所支持的 tag

我的设备为 Pixel 4 XL,最后支持的分支为 android-13.0.0_r31

 

修复 quota error

如果 sync 过程中多次报错 quota error 了,说明当前 IP 异常,访问被拦截,设置密钥以及修改 repo 链接以修复,如下。

https://source.android.com/docs/setup/download/troubleshoot-sync#fix-quota-barriers
 

 

更新

如需要更新

repo sync

 

编译

$ source build/envsetup.sh
$ lunch aosp_coral-userdebug
$ make -j4

如果 lunch 不加参数,会列出所有的对象

 

下载私有二进制以运行于物理设备

https://source.android.com/docs/setup/download#downloading-proprietary-binaries
 

解压之后,在 aosp 根目录执行即可。

 

打包和刷写

打包成可刷写的形式:

make -j8 updatepackage

 

flash 包生成在 out/target/product/coral (coral being the device name)

因为此时已经有环境变量了,所以不需要指定,直接执行

fastboot flashall -w

即可刷写所有的镜像

 

模拟器报错处理

在 source 和 lunch 之后,可以输入 emulator 进行模拟,如果无法启动,加上 -verbose 以查看详细日志

找不到 vulkan 设备

VERBOSE | Creating instance, asking for version 1.1.0 ...
VERBOSE | Found 0 Vulkan physical devices.
VERBOSE | No physical devices available.

好吧,是更新内核了,忘记重启了。

https://wiki.archlinux.org/title/Vulkan

 

Android Studio

参考:ArchWiki#AndroidStudio

使用内置的 SDK 下载器即可。

 

修改 aosp 绕过反调试

在大一研究 360 加固的时候,就遇上一位大佬,他说“因为我用的安卓系统是自己编译的,所以自带了很多反调试”,就觉得非常的牛。

如今我也到了这一步了,感慨万千。

反调试是 app 的基操,如果你的调试器连不上 app,不要怀疑调试器,就是被反调试了。调试的第一步就是过掉反调试

 

检测1:/proc/self/status

如果自己正在被调试,那么 /proc/self/statusTracerPid 值就不会是 0,一般检测就是通过加载该文件并读取 TracerPid 的值以检测调试器

这里可以通过修改 bionic's libc 中的 strcmp 函数,让其无法比较 TracerPid 即可,还有 strtol 也可以。

 

先修改源码,不过这里比较麻烦的是,strcmp 是直接用汇编写的,external/arm-optimized-routines/string/aarch64/strcmp.S 

介绍一下检索历程,先找到 bionic/libc,然后搜索 strcmp 之后,发现是定义为了 __strcmp_aarch64,再搜索就找不到了,回到 aosp 根目录搜索,才找到了这个汇编文件。

另外 bionic/libc/upstream-openbsd/lib/libc/string/strcmp.c 并不会被编译,不要被迷糊了)该文件在这里的作用目前未知

但是这样也太逆天了,改汇编可顶不住,我的建议是,改编译的文件,查看报错和检索,strcmp.S 定义在

external/arm-optimized-routines/Android.bp 

中,改成 strcmp.c 即可。编译完成之后,可以用 ida 看看 fd -H -I ‘^strcmp\.o$’ ,有没有编译成功。

 

adb reboot fastboot # or fastboot reboot fastboot
fastboot flash system # make sure you already source and lunch

注意这里是重启到 fastbootd ,因为 system 分区是 dynamic 的(警告是这样写的)

 

事实上,也可以跟踪 open 或 fopen 函数,检测到 status 就开始反反调试。

#include <stdio.h>

int main(int argc, char *argv[])
{
    printf("Hi!\n");
    FILE *s = fopen("/proc/self/status", "r");
    if (s == NULL) {
        perror("fopen");
        return -1;
    }
    char line[0x1000] = { 0 };
    while (fgets(line, sizeof(line), s) != NULL) {
        printf("%s", line);
    }
    fclose(s);
    printf("Done!\n");
    return 0;
}

 

 

关于 Git

目前已知的是,整个 aosp 由很多个 git 仓库组成,上一节修改的部分为安卓魔改的 ARM-software/optimized-routines,可以让其指向自己的仓库,不过目前仍需学习。

 

报错处理

没有提取私有驱动导致的,手动运行脚本提取一下。

 

下一步

[求助]AOSP10 ROM集成EdXposed或者lsposedLSPosed/SandHook

 


运行时间 20331 天 | 总访问量