逆向-内核-root方案

搬砖

root方案

1. magisk

2. kernelSu

2.1 gki kmi lkm 概念

**LKM(Linux Kernel Module)**实际上是一种用于在运行时动态加载到 Linux 内核中的代码块,通常用于添加设备驱动程序、文件系统等扩展内核功能。LKM 不一定是基于 KMI 开发的;它们可以是基于任何 Linux 内核版本开发的,用于扩展或添加到那个特定内核版本的功能。

在 Android 的 GKI(Generic Kernel Image) 系统中,**KMI(Kernel Module Interface)**是一系列稳定的 API 和 ABI(应用编程接口和应用二进制接口)的定义,这些接口被设计为在内核版本之间保持兼容性。

因此,在 Android GKI 的上下文中,设备制造商和硬件供应商可以开发LKM,这些模块符合KMI的规范,以保证它们的内核模块与当前和未来的 GKI 版本兼容。也就是说,LKM 是模块本身,而 KMI 是确保这些模块与 GKI 兼容所需遵循的一系列接口规范。

所以,可以这样理解:

设备制造商和硬件供应商基于 KMI 开发他们自己的 LKM。
这样开发的 LKM 可以在不同版本的 GKI 上加载而不会出现兼容性问题。
简而言之,LKM 是根据 KMI 规范开发的内核模块,它们依靠 KMI 的稳定性,使得它们与 GKI 的不同版本兼容。

2.2 Android编译

#export REPO_URL='https://mirrors.tuna.tsinghua.edu.cn/git/git-repo/'
#export REPO_URL='https://gerrit.googlesource.com/git-repo'

mkdir aosp14 && cd aosp14
repo init -u https://mirrors.tuna.tsinghua.edu.cn/git/AOSP/platform/manifest -b android14-release
repo init -u https://mirrors.tuna.tsinghua.edu.cn/git/AOSP/platform/manifest -b android-15.0.0_r8
repo init -u https://android.googlesource.com/platform/manifest -b android-14.0.0_r2
repo init -u https://android.googlesource.com/platform/manifest -b android-15.0.0_r8
repo sync -j16
source build/envsetup.sh
lunch XXX
emulator

遇到问题:
1. ipv6导致的黑屏

2.3 内核构建

  1. 官方文档

  2. kernelSu

  3. Cuttlefish 模拟器内核开发

    • 注意版本问题,通过 uname -a 查看内核版本
      “Linux localhost 6.1.23-android14-4-00257-g7e35917775b8-ab9964412 #1 SMP PREEMPT Mon Apr 17 20:50:58 UTC 2023 x86_64 Toybox”

      我当前编译分支
      aosp版本: repo init -u https://android.googlesource.com/platform/manifest -b android-14.0.0_r2
      kenel版本:repo init -u https://android.googlesource.com/kernel/manifest -b common-android14-6.1

    • 实战: 参考链接0 参考链接1 参考链接2

      1. 安装cuttlefish前端

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        grep -c -w "vmx\|svm" /proc/cpuinfo
        # 安装依赖
        sudo apt install -y git devscripts config-package-dev debhelper-compat curl
        # 下载代码
        git clone https://github.com/google/android-cuttlefish.git
        cd android-cuttlefish
        # 提起准备好go环境
        go version
        # 编译
        for dir in base frontend; do
        cd $dir
        debuild -i -us -uc -b -d
        cd ..
        done
        # 安装
        sudo apt install ./cuttlefish-base_*.deb ./cuttlefish-user_*.deb

      2. aosp 编译 lunch aosp_cf_x86_64_phone-userdebuge

        1
        2
        3
        4
        repo init -u https://android.googlesource.com/platform/manifest -b android-14.0.0_r2
        repo sync
        lunch aosp_cf_x86_64_phone-userdebuge
        m -jXX

      3. kenel 编译

        1
        2
        3
        4
        5
        6
        repo init -u https://android.googlesource.com/kernel/manifest -b common-android14-6.1
        repo sync
        tools/bazel run //common-modules/virtual-device:virtual_device_x86_64_dist
        // 注意两个编译产物,后面会用
        out/virtual_device_x86_64/dist/bzImage
        out/virtual_device_x86_64/dist/initramfs.img

      4. 启动

        1
        launch_cvd -kernel_path=/home/cozy/lang/media/lang/kernel_android14_6_1/out/virtual_device_x86_64/dist/bzImage -initramfs_path=/home/cozy/lang/media/lang/kernel_android14_6_1/out/virtual_device_x86_64/dist/initramfs.img 

      5. 接入kernelSu模块
        tools/bazel run //common-modules/virtual-device:virtual_device_x86_64_dist – –dist_dir=$DIST_DIR
        tools/bazel build //common:kernel_aarch64_dist
        tools/bazel run //common:kernel_aarch64_dist – –dist_dir=out

  4. 真机mi12-cupid内核开发github

    1. 第一阶段实践了下不行,放弃
    2. 第二阶段,直接通过https://clientinfra.com/android-kernel-build-and-debug 查找对应的gki 版本分支,通过替换被删掉分支后同步aosp,编译成功

3 KernelSu 构建

  1. gki编译 查找手机对应分支。找不到就放弃吧,一般直接到kernelsu github 找5.10.66(你的内核版本前缀)。没有就不要编译gki了,编译了内核版本还变了
    a. 查看内核版本 uname -r 比如:5.10.66-android12-9-gdc4677876dca
    b. 找分支。将“gdc4677876dca” 去掉 “g” 复制到链接。 如下
    https://android.googlesource.com/kernel/common/+/dc4677876dca

  2. 根据分支,拉取代码 参考:https://github.com/tiann/KernelSU/blob/main/.github/workflows/gki-kernel.yml

    1
    2
    3
    4
    5
    6
    7
    8
    repo init --depth=1 --u https://android.googlesource.com/kernel/manifest -b common-${{ inputs.tag }} --repo-rev=v2.16
    REMOTE_BRANCH=$(git ls-remote https://android.googlesource.com/kernel/common ${{ inputs.tag }})
    DEFAULT_MANIFEST_PATH=.repo/manifests/default.xml
    if grep -q deprecated <<< $REMOTE_BRANCH; then
    echo "Found deprecated branch: ${{ inputs.tag }}"
    sed -i 's/"${{ inputs.tag }}"/"deprecated\/${{ inputs.tag }}"/g' $DEFAULT_MANIFEST_PATH
    cat $DEFAULT_MANIFEST_PATH
    fi
  3. https://kernelsu.org/guide/how-to-build.html 编译并刷入
    a. gki 编译Image。 替换到 boot
    b. lkm 编译ko模块。使用 ksud patch
    ksud boot-patch -b init_boot.img -m android14-6.1_kernelsu.ko
    ksud boot-patch -b boot.img -m kernelsu.ko

  4. 编译ko 备份

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    pip install ast-grep-cli
    sudo apt-get install llvm-15 -y
    ast-grep -U -p '$$$ check_exports($$$) {$$$}' -r '' common/scripts/mod/modpost.c
    ast-grep -U -p 'check_exports($$$);' -r '' common/scripts/mod/modpost.c
    sed -i '/config KSU/,/help/{s/default y/default m/}' common/drivers/kernelsu/Kconfig
    echo "drivers/kernelsu/kernelsu.ko" >> common/android/gki_aarch64_modules

    # bazel build, android14-5.15, android14-6.1 use bazel
    if [ ! -e build/build.sh ]; then
    sed -i 's/needs unknown symbol/Dont abort when unknown symbol/g' build/kernel/*.sh || echo "No unknown symbol scripts found"
    if [ -e common/modules.bzl ]; then
    sed -i 's/_COMMON_GKI_MODULES_LIST = \[/_COMMON_GKI_MODULES_LIST = \[ "drivers\/kernelsu\/kernelsu.ko",/g' common/modules.bzl
    fi
    else
    TARGET_FILE="build/kernel/build.sh"
    if [ ! -e "$TARGET_FILE" ]; then
    TARGET_FILE="build/build.sh"
    fi
    sed -i 's/needs unknown symbol/Dont abort when unknown symbol/g' $TARGET_FILE || echo "No unknown symbol in $TARGET_FILE"
    sed -i 's/if ! diff -u "\${KERNEL_DIR}\/\${MODULES_ORDER}" "\${OUT_DIR}\/modules\.order"; then/if false; then/g' $TARGET_FILE
    sed -i 's@${ROOT_DIR}/build/abi/compare_to_symbol_list@echo@g' $TARGET_FILE
    sed -i 's/needs unknown symbol/Dont abort when unknown symbol/g' build/kernel/*.sh || echo "No unknown symbol scripts found"
    fi

3. Apatch

1
2
3
4
5
6
7
adb install apatch_patched_10763_0.10.7_hycc.img
adb shell 'echo "{\"serial\":\"$(getprop ro.serialno)\"}" > XXX
adb push worker-release-unsigned.apk XXX
adb push ROM.zip XXX
adb push install.sh XXX
adb shell su -c "XXX"
adb reboot

rom定制

  1. termux + ssh + ubuntu + clone TIK 项目
  2. 解包super.img system.img
  3. cp ../gauguin_rom/a_update/c8750f0d.0 system/system/etc/security/cacerts/
  4. cp ../gauguin_rom/a_update/com.android.adbd.apex system/system/apex/com.android.adbd.apex
  5. /system/system/etc/security/cacerts/c8750f0d.0 u:object_r:system_security_cacerts_file:s0
  6. 打包system.img super.img
  7. flash super

定制 adbd runtime

  1. bionic/linker/linker_main.cpp
    1
    2
    3
    4
    5
    6
    7
    void solist_add_soinfo(soinfo* si) {
    if(si !=nullptr && strstr(si->get_realpath(),"libxxx.so")){
    return;
    }
    sonext->next = si;
    sonext = si;
    }

adbd 这个apex是直接复制替换(TIK)
https://github.com/ColdWindScholar/TIK

  1. packages/modules/adb/daemon/main.cpp

    1
    2
    3
    4
    int port = xxx;
    addrs.push_back(android::base::StringPrintf("tcp:%d", port));
    addrs.push_back(android::base::StringPrintf("vsock:%d", port));
    setup_adb(addrs);
  2. packages/modules/adb/daemon/auth.cpp

    1
    2
    3
    bool authorized = false;
    // remove auth
    if(authorized == false){return true;}

先对runtime 解包,替换 linker 在打包回apex
https://github.com/wcedla/AndroidApexTools

替换组建,打包img

  1. 解包 小米直接下载线刷包,oplus只有卡刷包(7z 解压出playload.bin 在TIK 解压)