吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 7354|回复: 23
上一主题 下一主题
收起左侧

[Android 原创] android-pixel4a-刷机系列-(4)kernelsu整合内核

  [复制链接]
跳转到指定楼层
楼主
2016976438 发表于 2023-7-6 18:22 回帖奖励
本帖最后由 2016976438 于 2023-7-6 18:28 编辑

android-pixel4a-刷机系列-(4)kernelsu整合内核

你可以参考 debug选手大佬的 Pixel3编译的Kernel SU 内核,这也是提前替我们踩过坑的友人
地址来源: http://www.debuglive.cn/article/1091666763961073664

kernelSu 简介

KernelSU 是 Android GKI 设备的 root 解决方案,它工作在内核模式,并直接在内核空间中为用户空间应用程序授予 root 权限。

KernelSU 的主要特点是它是基于内核的。 KernelSU 运行在内核空间, 所以它可以提供我们以前从未有过的内核接口。 例如,我们可以在内核模式下为任何进程添加硬件断点;我们可以在任何进程的物理内存中访问,而无人知晓;我们可以在内核空间拦截任何系统调用; 等等。
KernelSU 还提供了一个基于 overlayfs 的模块系统,允许您加载自定义插件到系统中。它还提供了一种修改 /system 分区中文件的机制。

参考官方文档: https://kernelsu.org/zh_CN/guide/what-is-kernelsu.html

安装kernelSu

首先下载 kernelsu app 进行管理。 这个 app 在 酷安中可以找到 https://www.coolapk.com/apk/me.weishu.kernelsu

GKI 内核

在安装 kernelSu 后,你会发现它是这样的

GKI 内核是什么意思呢?
参考官方文档: https://source.android.com/docs/core/architecture/kernel/generic-kernel-image?hl=zh-cn

先说说以前的通用内核(ACK)的构造:

大概分为从上往下4个部分:
1.linux内核
2.aosp通用内核
3.供应商外围设备支持
4.Oem设备驱动

这就导致了一个问题,内核碎片化
通过官网解释来说,当供应商和Oem设备制造商对 3 和 4 部分的下游内核进行修改后
其官方对上游 1 和 2 内核进行修复更新后导致很难合并升级。
这样对已经在使用的设备就很难或者无法进行安全更新。

所以基于内核碎片化的问题,提供了一种解决方案 通用内核映像(GKI)。并提供了 KMI(内核模块接口),来实现内核模块的独立更新,并与
类似之前上游的内核抽离出来

(所以之前刷内核 必须同步 vendor 的 .ko 内核模块是因为 内核版本的问题???希望大佬解答)

这应该也是为什么 kernelSu 只提供 GKI 的内核镜像。 否则很难适配各自的 供应商内核模块对应的内核版本

下面是 GKI 通用内核镜像的架构图:

基于 GKI 通用内核的方便性,我们只需要 刷入修改过内核的 boot.img 即可。对于其内核模块 则应该无需考虑,应为按道理它是通过 KMI与GKI 内核交互的,而不需重建内核模块。当然 KMI 兼容性是和 GKI 内核版本挂钩的,还是稍微得注意下内核版本。

由于我并没有 GKI 内核的设备。 以上只是个人猜测。

下面是基于 GKI boot 分区的改动:

boot 分区

boot 分区包括头文件、内核以及内含启动 ramdisk 通用部分的 CPIO 归档。

boot 分区使用 v3 版启动头文件后,先前的 boot 分区的以下部分将不复存在:

第二阶段引导加载程序:如果设备具有第二阶段引导加载程序,则必须将相应引导加载程序存储在自己的分区中。
DTB:DTB 存储在供应商启动分区中。
boot 分区包含一个 CPIO 归档,内含以下 GKI 组件:

位于 /lib/modules/ 的 GKI 内核模块
first_stage_init 及其依赖的库
fastbootd 和 recovery(用于 A/B 和虚拟 A/B 设备)
GKI 启动映像由 Google 提供,必须用于 GKI 兼容性测试。

最新的 arm64 android11-5.4 boot.img 可以从 ci.android.com 中 aosp-master 分支的 aosp_arm64 构建工件中下载。

最新的 arm64 android11-5.4 内核映像 (Image.gz) 可以从 ci.android.com 中 aosp_kernel-common-android11-5.4 分支的 kernel_aarch64 构建工件中下载。

vendor_boot 分区

供应商启动分区

vendor_boot 分区随 GKI 引入。该分区是采用虚拟 A/B 的 A/B 分区,包含一个头文件、供应商 ramdisk 和设备树 Blob。供应商 ramdisk 是一个 CPIO 归档,其中包含设备启动所需的供应商模块。这包括用于启用关键 SoC 功能的模块,以及启动设备和显示启动画面所需的存储和显示驱动程序。

该 CPIO 归档包含:

第一阶段 init 供应商内核模块,位于 /lib/modules/
modprobe 配置文件,位于 /lib/modules
modules.load 文件,用于指示要在第一阶段 init 期间加载的模块
引导加载程序要求
引导加载程序必须在加载完供应商 ramdisk CPIO 映像(从 vendor_boot 分区)后,立即将通用 ramdisk CPIO 映像(从 boot 分区)加载到内存中。解压缩后,结果是通用 ramdisk 叠加在供应商 ramdisk 的文件结构之上。

到这里其实就能发现一点,供应商内核模块不仅仅可以在 vendor/lib/modules 中,还可以放在 vendor ramdisk 中的 /lib/modules 中,并通过 modules.load 指定加载,这应该可以解决上一篇 内核模块的问题。但这里是 gki 内核,拥有vendor_boot 分区,我们并没有。

GKI内核刷入KernelSu

您可以到他的github release 中下载对应内核的 boot.img 进行刷入(建议用AnyKernel3刷机包)。由于我并没有 基于 GKI 内核的
pixel 设备所以不方便展示。但理论GKI的内核设备,应该都很容易刷上去,注意下压缩格式即可。

Dessert 内核刷入

目前 dessert 内核最高支持到 android-4.19-stable
而 gki 内核 是从 android11-5.4开始
查看内核版本可以通过 kernelSu app 记录的信息,或者通过 cat /proc/version进行查看

非 GKI 内核设备 需要我们自己构建内核集成 kernelSu。所以下面的过程会比较麻烦。

构建KernelSu

如果您的是非 GKI 内核设备,那就老老实实手动编译吧。
当然也有些大佬自己编译好了,你可以参考: https://kernelsu.org/zh_CN/guide/unofficially-support-devices.html
或者靠运气去 github 上面搜搜

首先在你的 android kernel 的根目录下下载 kernelSu

# 进入到 内核根目录
cd  ~/android-kernel/private/msm-google
# 运行脚本  克隆 kernelSu main 分支代码 并处理
curl -LSs "https://raw.githubusercontent.com/tiann/KernelSU/main/kernel/setup.sh" | bash -s main

随后运行 build/build.sh 进行编译

但是你可能会出现下面的错误

....
--- private/msm-google/arch/arm64/configs/sunfish_defconfig        2023-06-27 15:56:28.068070234 +0800
+++ ~/aosp/android-kernel/out/android-msm-pixel-4.14/private/msm-google/defconfig        2023-06-27 22:37:59.857566122 +0800
@@ -685,7 +685,6 @@
 CONFIG_QUOTA_NETLINK_INTERFACE=y
 CONFIG_QFMT_V2=y
 CONFIG_FUSE_FS=y
-CONFIG_OVERLAY_FS=y
 CONFIG_INCREMENTAL_FS=m
 CONFIG_VFAT_FS=y
 CONFIG_TMPFS_POSIX_ACL=y
++ RES=1
++ '[' 1 -ne 0 ']'
++ echo ERROR: savedefconfig does not match private/msm-google/arch/arm64/configs/sunfish_defconfig
ERROR: savedefconfig does not match private/msm-google/arch/arm64/configs/sunfish_defconfig
++ return 1

大致意思是说 sunfish_defconfigsavedefconfig的输出产物 out/android-msm-pixel-4.14/private/msm-google/defconfig内容不匹配

这是什么意思呢?
哈哈哈,不懂呀不懂呀。
百度根本没有答案。

只能勉强说下我这几天看的资料
参考: https://blog.csdn.net/u011570492/article/details/55803327

大致能理解的是有几个配置文件分别是

# menuconfig 配置项
Kconfig
# 通过 .config 生成的选择指定架构的定义项 
xxx_defconfig
# 通过 menuconfig 配置后的 .config
.config

下面我将进行操作

配置KernelSu

Kconfig 在每个目录下都有,就比如你进入kernelsu 就会发现这个 Kconfig文件

cd private/msm-google/drivers/kernelsu
ls |grep config
Kconfig

查看 Kconfig中,发现他已经给我们定义好了OVERLAY_FS选项以及KSU_DEBUG

menu "KernelSU"

config KSU
        tristate "KernelSU function support"
        select OVERLAY_FS
        default y
        help
        Enable kernel-level root privileges on Android System.

config KSU_DEBUG
        bool "KernelSU debug mode"
        depends on KSU
        default n
        help
        Enable KernelSU debug mode

endmenu

我们可以在菜单配置选项界面进行配置

在内核源码根目录运行 make menuconfig
你会看到这种界面

然后输入 / 进入搜索界面,输入 ksu 也就是 KernelSu 中的 Kconfig配置

可以看道它位于 配置项

│   Location:                                                             │  
  │     -> Device Drivers                                                   │  
  │ (1)   -> KernelSU  

配置路径为 drivers/kernelsu/Kconfig:3  

我们跟到这个地方去

你就可以看到 tristate "KernelSU function support"选项

它对应着 KernelSu Kconfig

config KSU
        tristate "KernelSU function support"
    ....
`tristate` 是一个配置选项的类型,它表示可以有三个可能的值:`y`(yes)、`n`(no)和 `m`(module)。

在这个特定的配置选项中,`tristate "KernelSU function support"` 表示一个带有三个可能状态的选项,用于确定是否支持 "KernelSU" 功能。具体含义如下:

- `y`(yes):选择此选项表示启用 "KernelSU" 功能,并将其编译到内核中。
- `n`(no):选择此选项表示禁用 "KernelSU" 功能,并不将其编译到内核中。
- `m`(module):选择此选项表示将 "KernelSU" 功能编译为内核模块,可以在运行时加载和卸载。使用模块的方式可以在不重新编译整个内核的情况下启用或禁用 "KernelSU"。

因此,通过选择适当的值(`y`、`n` 或 `m`),可以决定是否启用 "KernelSU" 功能,并确定它是作为内核的一部分编译还是作为可加载的内核模块进行处理。

在回顾之前的错误

--- private/msm-google/arch/arm64/configs/sunfish_defconfig        2023-06-27 15:56:28.068070234 +0800
+++ ~/aosp/android-kernel/out/android-msm-pixel-4.14/private/msm-google/defconfig        2023-06-27 22:37:59.857566122 +0800
@@ -685,7 +685,6 @@
 CONFIG_QUOTA_NETLINK_INTERFACE=y
 CONFIG_QFMT_V2=y
 CONFIG_FUSE_FS=y
-CONFIG_OVERLAY_FS=y
 CONFIG_INCREMENTAL_FS=m
 CONFIG_VFAT_FS=y
 CONFIG_TMPFS_POSIX_ACL=y
++ RES=1
++ '[' 1 -ne 0 ']'
++ echo ERROR: savedefconfig does not match private/msm-google/arch/arm64/configs/sunfish_defconfig
ERROR: savedefconfig does not match private/msm-google/arch/arm64/configs/sunfish_defconfig
++ return 1

通过 savedefconfig 生成的 defconfigsunfish_defconfig 比对结果差异就在 -CONFIG_OVERLAY_FS=y

所以我把 select OVERLAY_FS注释掉后就成功编译了,如下:

menu "KernelSU"

config KSU
        tristate "KernelSU function support"
#        select OVERLAY_FS
        default y
        help
        Enable kernel-level root privileges on Android System.

原理我并不知道为什么,之后会不会有问题,不过还是先了解下 defconfig

defconfig

defconfig 按照解释是说 每个 架构设备 的 默认建议配置

一般是在 arch/xxx/configs
那么 arm64 我们查看一下:

发现我们编译使用到的 sunfish_defconfig,搜索的话也确实找到了 CONFIG_OVERLAY_FS=y

那么也就是说之前报错 saveconfig 出的 defconfigsunfish_defconfig 缺少的项就是这个了。

但是注释掉 kernelSu Kconfig 中的 select OVERLAY_FS 后 编译就不缺少了。

这是为什么呢?
这是为什么呢?
这是为什么呢?
这是为什么呢?
这是为什么呢?

刷入KernelSu 内核

编译后搜索一下

发现存在 kernelSu 模块,不是说 tristate类型是编译到内核里吗? 百思不得其解呀~

config KSU
        tristate "KernelSU function support"
#        select OVERLAY_FS
        default y
        help
        Enable kernel-level root privileges on Android System.

算了司马当活马医。 直接刷入看看

测试内核

kernelSu本身是使用kprobe hook 系统内核实现的功能,所以按道理我们不需要做其他更改了,直接测试就行了
当然我不敢保证,毕竟有的内核版本 连 kprobe都无法支持,我也对内核理解不多。

我们可以直接通过 fastboot 刷入内核启动文件Image.lz4-dtb 进行测试内核

adb reboot bootloader
fastboot boot Image.lz4-dtb

然后打开 kernelSu 的 app 进行查看

集成到 boot.img

重新编译 aosp过于麻烦,所以我们使用 aik 也就是 android image kitchen

网站介绍: https://forum.xda-developers.com/t/tool-android-image-kitchen-unpack-repack-kernel-ramdisk-win-android-linux-mac.2073775/

注意下载:AIK-Linux-v3.8-ALL.tar.gz 。当然它也有github https://github.com/osm0sis/Android-Image-Kitchen
你可以下载它的 linux 分支 或者 windows

下载完后解压你会发现有几个重要的脚本

# 清理解包数据
cleanup.sh
# 重打包
repackimg.sh
# 解包
unpackimg.sh

boot.img 放入到 aik目录中,直接运行 unpacking.sh
你会看到多出2个文件夹

主要注意 split_img 目录,将里面的 boot.img-kernel 替换成你的启动内核Image.lz4-dtb注意替换的时候名字要改成一样

接下来直接调用 repackimg.sh 它会重打包成 image-new.img

接下来执行下面的命令进行刷入

adb reboot bootloader
fastboot flash boot image-new.img``

kernelsu测试

刷入后你会发现用不了

如何排查呢?

要排查问题肯定离不开日志,在 kernelSu的源码中

几乎每个地方都有日志的输出

日志使用的是 内核中的printk

根据网上查的资料来说: https://www.cnblogs.com/ArsenalfanInECNU/p/16952781.html

可以使用

# 从kernel的ring buffer(环缓冲区)中读取信息
dmesg 
dmesg -w # 实时获取日志
dmesg -C # 清楚 ringbuf

# /proc/kmsg是专门输出内核信息的地方,为了能够方便的在 user space 读取 Kernel log,Kernel driver 里面将ring buffer映射到了 /proc 目录下的文件节点 /proc/kmsg。所以读取 /proc/kmsg 文件其实就是在访问 Kernel Log 的循环缓冲区。虽然 Log buffe的大小是固定的,但是可以通过不断的访问 /proc/kmsg 将所有的log都备份下来。

#实时显示内核打印信息并保存到android_kmsg.log文件中
adb shell cat /proc/kmsg |tee android_kmsg.log

所有按照 klog.h 覆盖的宏定义

我们可以直接搜索 KernelSu,使用命令dmesg -w|grep KernelSU进行实时跟踪

# dmesg -w|grep KernelSU              

[  749.835666] KernelSU: save allow list, name: bin.mt.plus uid :10107, allow: 1

[ 1311.425279] KernelSU: save allow list, name: bin.mt.plus uid :10107, allow: 0
[ 1312.981342] KernelSU: save allow list, name: bin.mt.plus uid :10107, allow: 1
[ 1313.578734] KernelSU: save allow list, name: bin.mt.plus uid :10107, allow: 0
[ 1314.041084] KernelSU: save allow list, name: bin.mt.plus uid :10107, allow: 1
[ 1376.168834] KernelSU: do_execveat_common su found
[ 1376.168876] KernelSU: error: 0, sid: 833
[ 1376.188984] KernelSU: do_execveat_common su found
[ 1376.189022] KernelSU: error: 0, sid: 833
[ 1417.165194] KernelSU: newfstatat su->sh!
[ 1417.165234] KernelSU: faccessat su->sh!
[ 1417.165927] KernelSU: do_execveat_common su found
[ 1417.165968] KernelSU: error: 0, sid: 833

当然我这里的日志是通过的,因为我解决了,但是难得重现问题记录笔记,但我可以明确告诉你是kprobe的配置问题。

下一节将正式告诉你如何正确配置defconfig并启用kprobe

免费评分

参与人数 13威望 +2 吾爱币 +112 热心值 +13 收起 理由
gaosld + 1 + 1 谢谢@Thanks!
Tianyi731 + 1 + 1 我很赞同!
fengbolee + 2 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
allspark + 1 + 1 用心讨论,共获提升!
syqc251 + 1 + 1 我很赞同!
T107 + 1 + 1 热心回复!
junjia215 + 1 + 1 用心讨论,共获提升!
qtfreet00 + 2 + 100 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
Ekolz + 1 我很赞同!
zhczf + 1 + 1 我很赞同!
yunkof + 1 + 1 我很赞同!
debug_cat + 2 + 1 用心讨论,共获提升!
waltzofjack + 1 希望前辈继续分享相关经验

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

推荐
timychen 发表于 2023-7-6 19:57
厉害,学习了
沙发
TheKingOfKiller 发表于 2023-7-6 19:38
3#
帅气的老赵啊 发表于 2023-7-6 19:52
5#
flyxxbird 发表于 2023-7-6 20:16
虽然看不懂,但是感觉好牛逼啊,希望大佬能出个面向小白的教程
6#
debug_cat 发表于 2023-7-6 20:29
,非常详细的方案~,大佬我申请转载
7#
AIIGE 发表于 2023-7-6 20:50
感谢分享
8#
kaijinaini 发表于 2023-7-6 20:55
细细打量
9#
 楼主| 2016976438 发表于 2023-7-6 22:23 |楼主
debug_cat 发表于 2023-7-6 20:29
,非常详细的方案~,大佬我申请转载

欢迎大佬
10#
goda 发表于 2023-7-6 23:15
感谢分享
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-21 16:50

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表