把模块打包进 magisk
在 boot_patch.sh
里
magisk 是这样把 magisk 添加到内核里的
"$SKIP64 add 0644 overlay.d/sbin/magisk64.xz magisk64.xz" \
所以直接在它的下面加上
"add 0644 overlay.d/sbin/hello.ko hello.ko" \
这样就能把 hello.ko 添加进内核里,在启动后,这个文件会在 magisk --path
路径下。至于怎么过去的,可以看看 magiskinit 的代码.
为了把 magiskboot 和 hello.ko 放到同一路径下 ( /data/user_de/0/com.topjohnwu.magisk/install
), 还需要修改一些代码
首先要把 hello.ko 放到 tools 目录下。然后修改代码buildSrc/src/main/java/Setup.kt
val syncAssets = tasks.register("syncAssets", Sync::class.java){
.....
from(rootProject.file("tools")) {
include("hello.ko") // 把/tools/hello.ko放到assets文件里
}
.....
}
接下来这里app/src/main/java/com/topjohnwu/magisk/core/tasks/MagiskInstaller.kt
private fun extractFiles(): Boolean {
.......
// Extract scripts
for (script in listOf("util_functions.sh", "boot_patch.sh", "addon.d.sh","hello.ko")) {//从assets文件复制到install目录下,这样magiskboot就和hello.ko在同一目录下了
val dest = File(installDir, script)
context.assets.open(script).writeTo(dest)
}
......
}
修改之后,再次编译,安装到内核,就可以看到 hello.ko 出现在 magisk --path
路径里.
zeus:/dev/C1VQ # ls
hello.ko magisk magisk32 magisk64 magiskpolicy resetprop su supolicy
注入 init.rc
magisk 自带了注入 init.rc 的模板,在 native\jni\init\magiskrc.inc
里.
不过注入这个 rc 是不能执行 insmod 的。大家可以试一试.
需要注入 vendor 目录下的 rc 才行.
以 /vendor/etc/init/hw/init.qcom.rc
为例,注入方法类似注入 init.rc
native\jni\init\rootdir.cpp
void SARBase::patch_ro_root() {
......
// Patch init.rc
if (access(NEW_INITRC, F_OK) == 0) {
// Android 11's new init.rc
xmkdirs(dirname(ROOTOVL NEW_INITRC), 0755);
patch_init_rc(NEW_INITRC, ROOTOVL NEW_INITRC, tmp_dir.data());
} else {
patch_init_rc("/init.rc", ROOTOVL "/init.rc", tmp_dir.data());
}
// patch /vendor/etc/init/hw/init.qcom.rc
xmkdir(ROOTOVL "/vendor", 0755);
xmkdir(ROOTOVL "/vendor/etc", 0755);
xmkdir(ROOTOVL "/vendor/etc/init", 0755);
xmkdir(ROOTOVL "/vendor/etc/init/hw", 0755);
patch_vendor_init_rc("/vendor/etc/init/hw/init.qcom.rc",ROOTOVL "/vendor/etc/init/hw/init.qcom.rc",tmp_dir.data());
......
}
#include "magiskvendorc.inc"
static void patch_vendor_init_rc(const char *src, const char *dest, const char *tmp_dir) {
FILE *rc = xfopen(dest, "we");
if (!rc) {
PLOGE("%s: open %s failed", __PRETTY_FUNCTION__, src);
return;
}
file_readline(src, [=](string_view line) -> bool {
// Else just write the line
fprintf(rc, "%s", line.data());
return true;
});
fprintf(rc, "\n");
LOGD("Inject magisk vendor rc\n");
fprintf(rc, MAGISK_VENDOR_RC, tmp_dir);
fclose(rc);
clone_attr(src, dest);
}
native\jni\init\magiskvendorc.inc
#include <magisk.hpp>
#include <selinux.hpp>
#define quote(s) #s
#define str(s) quote(s)
constexpr char MAGISK_VENDOR_RC[] =
"\n"
"on post-fs-data\n"
" insmod %1$s/hello.ko\n" //直接载入magisk路径下的hello.ko
;
重新编译 magisk, 然后直接安装新的 magiskinit 到内核,重启
dmesg |grep hello.ko
[ 4.200993] type=1400 audit(19253364.167:64): avc: denied { read } for comm="init" name="hello.ko" dev="tmpfs" ino=17 scontext=u:r:vendor_init:s0 tcontext=u:object_r:system_file:s0 tclass=file permissive=0
修改 sepolicy
看到上面的日志就可知需要修改 sepolicy, 其实在 magiskinit 里,已经有修改 sepolicy 的实现
native\jni\sepolicy\rules.cpp
void sepolicy::magisk_rules() {
.......
set_log_level_state(LogLevel::Warn, true);
//添加vendor的sepolicy
allow("vendor_init", "system_file", "file", "read");
allow("vendor_init", "system_file", "file", "open");
allow("vendor_init", "system_file", "system", "module_load");
}
这里简单说明下
allow 的四个参数分别代表被 sepolicy 拒绝的 scontext,tcontext,tclass,action
再编译,安装。重启.
dmesg |grep hello.ko
[ 4.247766] hello_init
[ 4.247767] hello_init
[ 4.247769] hello_init
[ 4.247771] hello_init
[ 4.247773] hello_init
[ 4.247774] hello_init
[ 4.247776] hello_init
[ 4.247778] hello_init
[ 4.247779] hello_init
[ 4.247781] hello_init
[ 4.247783] hello_init
[ 4.247784] hello_init
[ 4.247786] hello_init
[ 4.247788] hello_init
[ 4.247789] hello_init
[ 4.247791] hello_init
[ 4.247793] hello_init
[ 4.247795] hello_init
[ 4.247796] hello_init
[ 4.247798] hello_init
[ 4.247800] hello_init
[ 4.247801] hello_init
可以看到,驱动已经成功加载.
2 条评论
看看了
感谢大佬分享!!!!!ヾ(≧∇≦*)ゝ