MTK 6735/6739/6755/6763 android8.1 user版本打开root权限(adb root权限和 apk root权限)

前言

一直对 root 这块比较感兴趣,正好最近客户有这么个需求,都说兴趣是最好的老师,但也抵不住任务来的快啊。临危受命,只能开搞了。

从 Android M 后 Google 对权限控制的越来越严,包括 root 也是,网上很多文章都是针对低版本的方法,偶尔有几篇写 8.1 的,

也根本没有真正实现完美 root。从 MTK Online 的官网也查阅到了,从 M 版本后已经不开放 root 权限了,这下麻烦了,MTK 的大腿是抱不动了,

只能自己摸黑瞎搞了,断断续续,耗时一个多月,各种查资料,期间踩了不少坑,特此记录一下。接下来就让各位见识一下 8.1 完美的 root 方案。

一图胜千言

QELehR.png

QELZN9.png

QELVAJ.png

修改方案

上面的图就不用我多说了吧,分别用了 ROOT检测工具、RE文件管理器测试,只要 root 成功都有明显的提示,

也可以用 AirDroid 来远程控制测试是否成功 root。

而且在 adb shell 下通过 ps -ef 命令,可以清楚的看到 su daemon 进程已经启动。

总共修改 18 个文件,新增 3 个文件,一共 21 个,是不是被吓到了,待我一一道来。

	modified:   build/make/core/main.mk
	modified:   build/make/target/product/verity.mk
	modified:   device/mediatek/mt6735/init.mt6735.rc
	modified:   device/mediatek/sepolicy/basic/non_plat/file_contexts
	modified:   device/mediateksample/k37tv1_64_bsp/ProjectConfig.mk
	modified:   device/mediateksample/k37tv1_64_bsp/device.mk
	modified:   device/mediateksample/k37tv1_64_bsp/init.project.rc
	modified:   kernel-3.18/arch/arm64/configs/k37tv1_64_bsp_defconfig
	modified:   kernel-3.18/security/commoncap.c
	modified:   system/core/adb/Android.mk
	modified:   system/core/adb/daemon/main.cpp
	modified:   system/core/init/init.cpp
	modified:   system/core/fs_mgr/Android.bp
	modified:   system/core/libcutils/fs_config.cpp
	modified:   system/sepolicy/Android.mk
	modified:   system/sepolicy/definitions.mk
	modified:   vendor/mediatek/proprietary/bootable/bootloader/lk/project/k37tv1_64_bsp.mk
	modified:   vendor/mediatek/proprietary/hardware/fstab/mt6735/fstab.in
	
	add device/mediatek/sepolicy/basic/non_plat/suproce.te
	add system/extras/su/su
	add system/extras/su/suproce.sh

1、让进程名称在 AS Logcat 中可见,通过修改 ro.adb.secure 和 ro.secure

ps:这步不是必须的,目的只是在 logcat 中可见进程 pid 和包名,而且打开 USB 调试时默认授权,不再弹授权框

build/make/core/main.mk

 tags_to_install :=
 ifneq (,$(user_variant))
   # Target is secure in user builds.
-  ADDITIONAL_DEFAULT_PROPERTIES += ro.secure=1
+  # ADDITIONAL_DEFAULT_PROPERTIES += ro.secure=1
+  ADDITIONAL_DEFAULT_PROPERTIES += ro.secure=0
   ADDITIONAL_DEFAULT_PROPERTIES += security.perf_harden=1
 
   ifeq ($(user_variant),user)
-    ADDITIONAL_DEFAULT_PROPERTIES += ro.adb.secure=1
+    # ADDITIONAL_DEFAULT_PROPERTIES += ro.adb.secure=1
+    ADDITIONAL_DEFAULT_PROPERTIES += ro.adb.secure=0
   endif
 
   ifeq ($(user_variant),userdebug)
@@ -251,7 +253,7 @@ ifneq (,$(user_variant))
     tags_to_install += debug
   else
     # Disable debugging in plain user builds.
-    enable_target_debugging :=
+    # enable_target_debugging :=
   endif
 
   # Disallow mock locations by default for user builds

2、修改 SELinux权限为 Permissive

SELinux 常用状态有两个 Permissive 和 Enforcing,通过 adb shell getenforce 可查看当前所处模式

system/core/init/init.cpp

static bool selinux_is_enforcing(void)
{
    +return false;

    if (ALLOW_PERMISSIVE_SELINUX) {
        return selinux_status_from_cmdline() == SELINUX_ENFORCING;
    }
    return true;
}

3、修改 system 分区权限为可读写

Dear customer,开启完整的root 权限需要开通SELinux 权限,这部分修改无法通过CTS 测试。

我司目前不会提供类似的方案给贵司。目前我们只支持USB adb权限。这是 MTK 的官方回复。

vendor/mediatek/proprietary/hardware/fstab/mt6735/fstab.in

 /dev/block/platform/mtk-msdc.0/11230000.msdc0/by-name/system     /            __MTK_SYSIMG_FSTYPE   ro                  wait,verify=/dev/block/platform/mtk-msdc.0/11230000.msdc0/by-name/metadata,slotselect,recoveryonly
 #else
 #ifdef __MTK_SEC_VERITY
-/dev/block/platform/mtk-msdc.0/11230000.msdc0/by-name/system     /system      __MTK_SYSIMG_FSTYPE   ro                 wait,verify,recoveryonly
+/dev/block/platform/mtk-msdc.0/11230000.msdc0/by-name/system     /system      __MTK_SYSIMG_FSTYPE   rw                 wait,verify,recoveryonly
 #else
-/dev/block/platform/mtk-msdc.0/11230000.msdc0/by-name/system     /system      __MTK_SYSIMG_FSTYPE   ro                 wait,recoveryonly
+/dev/block/platform/mtk-msdc.0/11230000.msdc0/by-name/system     /system      __MTK_SYSIMG_FSTYPE   rw                 wait,recoveryonly
 #endif
 #endif

4、关闭 DM-verity,确保 system 分区真正可读写

在我修改完其它编译烧写后,发现每次都是重启第一次 adb remount 可执行成功,

第一次也能 push 东西,再执行就不行了。remount of /system failed: Read-only file system remount failed。

后来这期间就一直停滞不前了,卡了一个周。巧的是刚好就开始搞 9.0 的源码,

发现工程版本的系统也不能直接 push,这什么鬼呀,后来经过各种搜素后发现更严格了,

需要进行 OEM 解锁,然后关闭 DM-verity。才能进行 push。这反倒提醒我了,

于是抱着试一试的心态来接着弄 8.1 root,在关闭 DM-verity 后,重新烧写还真的就 ok 了,adb 能完全控制。

build/make/target/product/verity.mk

 user_variant := $(filter user userdebug,$(TARGET_BUILD_VARIANT))
 ifneq (,$(user_variant))
     PRODUCT_SUPPORTS_BOOT_SIGNER := true
-    PRODUCT_SUPPORTS_VERITY := true
-    PRODUCT_SUPPORTS_VERITY_FEC := true
+    PRODUCT_SUPPORTS_VERITY := false
+    PRODUCT_SUPPORTS_VERITY_FEC := false
 
     # The dev key is used to sign boot and recovery images, and the verity
 

device/mediateksample/k37tv1_64_bsp/ProjectConfig.mk

@@ -267,7 +267,7 @@ MTK_DITHERING_SUPPORT = yes
 MTK_DMNR_TUNING_AT_MD = no
 MTK_DM_APP = no
 MTK_DM_ENTRY_DISPLAY = no
-MTK_DM_VERITY_OFF = no
+MTK_DM_VERITY_OFF = yes

kernel-3.18/arch/arm64/configs/k37tv1_64_bsp_defconfig

 CONFIG_BLK_DEV_DM=y
 CONFIG_DM_CRYPT=y
 CONFIG_DM_UEVENT=y
-CONFIG_DM_VERITY=y
+CONFIG_DM_VERITY=n
+CONFIG_MTK_DM_VERITY_OFF=y
 CONFIG_NETDEVICES=y

vendor/mediatek/proprietary/bootable/bootloader/lk/project/k37tv1_64_bsp.mk

 DEFINES += SWCHR_POWER_PATH
 MTK_GOOGLE_TRUSTY_SUPPORT = no
-MTK_DM_VERITY_OFF = no
+MTK_DM_VERITY_OFF = yes

system/core/fs_mgr/Android.bp

         "liblogwrap",
         "libfstab",
     ],
+    cppflags: ["-DALLOW_SKIP_SECURE_CHECK=1"],
     product_variables: {
         debuggable: {
             cppflags: ["-DALLOW_ADBD_DISABLE_VERITY=1"],


5、修改 adb root 权限,解除 zygote 和 adbd 对 Root Capabilities BoundSet 的限制

kernel-3.18/security/commoncap.c

@@ -890,10 +890,10 @@ static int cap_prctl_drop(unsigned long cap)
 {
        struct cred *new;
 
-       if (!ns_capable(current_user_ns(), CAP_SETPCAP))
+       /*if (!ns_capable(current_user_ns(), CAP_SETPCAP))
                return -EPERM;
        if (!cap_valid(cap))
-               return -EINVAL;
+               return -EINVAL;*/
 
        new = prepare_creds();
        if (!new)

system/core/adb/Android.mk

@@ -351,9 +351,9 @@ LOCAL_CFLAGS := \
     -D_GNU_SOURCE \
     -Wno-deprecated-declarations \
 
-LOCAL_CFLAGS += -DALLOW_ADBD_NO_AUTH=$(if $(filter userdebug eng,$(TARGET_BUILD_VARIANT)),1,0)
+LOCAL_CFLAGS += -DALLOW_ADBD_NO_AUTH=$(if $(filter user userdebug eng,$(TARGET_BUILD_VARIANT)),1,0)
 
-ifneq (,$(filter userdebug eng,$(TARGET_BUILD_VARIANT)))
+ifneq (,$(filter user userdebug eng,$(TARGET_BUILD_VARIANT)))
 LOCAL_CFLAGS += -DALLOW_ADBD_DISABLE_VERITY=1
 LOCAL_CFLAGS += -DALLOW_ADBD_ROOT=1
 endif

system/core/adb/daemon/main.cpp

@@ -59,6 +59,7 @@ static void drop_capabilities_bounding_set_if_needed(struct minijail *j) {
 }
 
 static bool should_drop_privileges() {
+    return false;
 #if defined(ALLOW_ADBD_ROOT)
     // The properties that affect `adb root` and `adb unroot` are ro.secure and
     // ro.debuggable. In this context the names don't make the expected behavior

system/sepolicy/Android.mk

@@ -518,7 +518,7 @@ $(LOCAL_BUILT_MODULE): $(HOST_OUT_EXECUTABLES)/secilc $(HOST_OUT_EXECUTABLES)/se
                echo "ERROR: permissive domains not allowed in user builds" 1>&2; \
                echo "List of invalid domains:" 1>&2; \
                cat $@.permissivedomains 1>&2; \
-               exit 1; \
+               # exit 1; \
                fi
        $(hide) mv $@.tmp $@
 
@@ -562,7 +562,7 @@ $(LOCAL_BUILT_MODULE): $(sepolicy.recovery.conf) $(HOST_OUT_EXECUTABLES)/checkpo
                echo "ERROR: permissive domains not allowed in user builds" 1>&2; \
                echo "List of invalid domains:" 1>&2; \
                cat $@.permissivedomains 1>&2; \
-               exit 1; \
+               # exit 1; \
                fi
        $(hide) mv $@.tmp $@
 

system/sepolicy/definitions.mk

@@ -4,7 +4,7 @@ define transform-policy-to-conf
 @mkdir -p $(dir $@)
 $(hide) m4 $(PRIVATE_ADDITIONAL_M4DEFS) \
        -D mls_num_sens=$(PRIVATE_MLS_SENS) -D mls_num_cats=$(PRIVATE_MLS_CATS) \
-       -D target_build_variant=$(TARGET_BUILD_VARIANT) \
+       -D target_build_variant=eng \
        -D target_with_dexpreopt=$(WITH_DEXPREOPT) \
        -D target_arch=$(PRIVATE_TGT_ARCH) \
        -D target_with_asan=$(PRIVATE_TGT_WITH_ASAN) \

6、增加 su 相关,确保 apk root 权限

上面修改完后,user 版本的 adb root 就已经 ok了。apk 获取 root 权限,需要内置 su 文件,

一般都搭配 SuperSU 来进行权限管理,也就是我们常见的那个弹框,上文的图中可见。

su 文件在工程版本是不会编译的,后来我参考资料去除了 su.cpp 中的权限判断,

编译出了 su 文件,本以为放进去就ok,但是根本不管用。就在我又陷入坑中时,

我找到了这篇 Android模拟器获取Root权限,是的你没看错,就是模拟器。

我照着文中一顿操作,下载 SuperSU2.7 和对应的 su 文件,我的设备架构是 arm64 的,就用 arm64 文件夹下的。

文中有提到重启后 root 权限会丢失,经我测试验证确实如此,重启后 su daemon 进程就没了,所以 root 权限也就不存在了。

而且千万不能更新 su 二进制文件,更新后重启就一直卡在开机动画界面了,所以我最终没装 SuperSU2.7。

通过 adb 命令行再执行一遍安装命令即可。这样一来有点美中不足,客户可不想每次重启还得来遍 adb 的操作。

于是我准备在 init.rc 中搞点事情,每次开机完成后执行脚本文件代替 adb 操作。

开始想的另一种方法在 SystemUI 中收到开机广播后,通过 Runtime.getRuntime().exec() 去执行,

尝试了半天后不见效果,才想到在 init.rc 中的方案。这也是个大坑,耗费我一天多时间才搞定。来吧,看看代码。

重启手动执行以下 sh 文件可测试,执行后 ps -ef 就能看到 su daemon 进程

#!/bin/bash

adb devices

adb shell mount -o rw,remount /system
adb shell chmod 06755 system/bin/su

adb shell system/bin/su --daemon

echo "done."

开机执行脚本的命令也可直接加在 system/core/rootdir/init.rc,我这里分开写在对应模块下,

开机脚本执行是否成功,可通过 adb shell dmesg > dmesg.txt 抓取 init 的日志,搜索是否报错,或者缺少权限。

我看日志我的貌似也缺少一些其它权限,但是能正常启动,进程也都ok,就没管了。

若有问题,可参考为 Android 8.0 添加开机启动脚本


	Line 173: [    3.447690] (1)[1:init]init: starting service 'suproce'...
	Line 177: [    3.450862] (2)[283:logd.auditd]type=1400 audit(1575268874.670:3): avc: denied { transition } for pid=353 comm="init" path="/system/bin/sh" dev="mmcblk0p23" ino=687 scontext=u:r:init:s0 tcontext=u:object_r:suproce_exec:s0 tclass=process permissive=1
	Line 179: [    3.451333] (2)[283:logd.auditd]type=1400 audit(1575268874.670:3): avc: denied { transition } for pid=353 comm="init" path="/system/bin/sh" dev="mmcblk0p23" ino=687 scontext=u:r:init:s0 tcontext=u:object_r:suproce_exec:s0 tclass=process permissive=1
	Line 180: [    3.451354] (2)[283:logd.auditd]type=1400 audit(1575268874.670:4): avc: denied { entrypoint } for pid=353 comm="init" path="/system/bin/sh" dev="mmcblk0p23" ino=687 scontext=u:object_r:suproce_exec:s0 tcontext=u:object_r:shell_exec:s0 tclass=file permissive=1
	Line 262: [    3.781012] (1)[283:logd.auditd]type=1400 audit(1575268874.670:4): avc: denied { entrypoint } for pid=353 comm="init" path="/system/bin/sh" dev="mmcblk0p23" ino=687 scontext=u:object_r:suproce_exec:s0 tcontext=u:object_r:shell_exec:s0 tclass=file permissive=1
	Line 263: [    3.781041] (1)[283:logd.auditd]type=1400 audit(1575268875.000:5): avc: denied { use } for pid=353 comm="sh" path="/dev/null" dev="tmpfs" ino=101 scontext=u:object_r:suproce_exec:s0 tcontext=u:r:init:s0 tclass=fd permissive=1
	Line 264: [    3.781393] (1)[283:logd.auditd]type=1400 audit(1575268875.000:5): avc: denied { use } for pid=353 comm="sh" path="/dev/null" dev="tmpfs" ino=101 scontext=u:object_r:suproce_exec:s0 tcontext=u:r:init:s0 tclass=fd permissive=1
	Line 265: [    3.781419] (1)[283:logd.auditd]type=1400 audit(1575268875.000:6): avc: denied { read write } for pid=353 comm="sh" path="/dev/null" dev="tmpfs" ino=101 scontext=u:object_r:suproce_exec:s0 tcontext=u:object_r:null_device:s0 tclass=chr_file permissive=1

	......

boot_completed 启动完成时,start suproce

device/mediatek/mt6735/init.mt6735.rc

@@ -669,6 +669,7 @@ service bugreport /system/bin/dumpstate -d -p -B -z \
 
 # end boot time fs tune
 on property:sys.boot_completed=1
+    start suproce
     write /sys/block/mmcblk0/queue/iostats 1
     write /sys/block/mmcblk0/queue/read_ahead_kb 128
     write /sys/block/mmcblk0/queue/nr_requests 128

device/mediateksample/k37tv1_64_bsp/init.project.rc

+service suproce /system/bin/sh /system/bin/suproce.sh
+    class main
+    user root
+    group root
+    oneshot
+    seclabel u:object_r:suproce_exec:s0

system/extras/su/suproce.sh

#!/system/bin/sh


mount -o rw,remount /system
chmod 06755 su
su --daemon

echo "su daemon done."

device/mediatek/sepolicy/basic/non_plat/file_contexts

 #hidl process merging
 /(system\/vendor|vendor)/bin/hw/merged_hal_service          u:object_r:merged_hal_service_exec:s0
+
+#suproce
+/(system\/vendor|vendor)/bin/suproce.sh          u:object_r:suproce_exec:s0

device/mediatek/sepolicy/basic/non_plat/suproce.te

type suproce, coredomain;
 
type suproce_exec, exec_type, vendor_file_type, file_type;
 
# permissive suproce;
# allow shell suproce_exec:file { read open getattr execute };
 
init_daemon_domain(suproce);

拷贝 su 文件和开机脚本 suproce.sh 到 system/bin 目录下
device/mediateksample/k37tv1_64_bsp/device.mk

@@ -19,6 +19,11 @@ PRODUCT_COPY_FILES += $(LOCAL_PATH)/sbk-kpd.kl:system/usr/keylayout/sbk-kpd.kl:m
                       $(LOCAL_PATH)/sbk-kpd.kcm:system/usr/keychars/sbk-kpd.kcm:mtk
 endif
 
+PRODUCT_COPY_FILES += \
+       system/extras/su/su:system/bin/su \
+       system/extras/su/suproce.sh:system/bin/suproce.sh
+

给 su 文件增加权限

system/core/libcutils/fs_config.cpp

@@ -166,7 +168,9 @@ static const struct fs_path_config android_files[] = {
     // the following two files are INTENTIONALLY set-uid, but they
     // are NOT included on user builds.
     { 06755, AID_ROOT,      AID_ROOT,      0, "system/xbin/procmem" },
-    { 04750, AID_ROOT,      AID_SHELL,     0, "system/xbin/su" },
+    { 06755, AID_ROOT,      AID_SHELL,     0, "system/bin/su" },
+    { 06755, AID_ROOT,      AID_SHELL,     0, "system/xbin/su" },
+    //{ 04750, AID_ROOT,      AID_SHELL,     0, "system/xbin/su" },
 
     // the following files have enhanced capabilities and ARE included
     // in user builds.

好了,终于大功告成,一时 root 一时爽,一直 root 一直爽。

su 和 apk下载

参考文章

Android开机启动shell脚本(Android 8.0测试OK)
为 Android 8.0 添加开机启动脚本
Android系统init进程启动及init.rc全解析
android文件系统挂载分析(1)—正常开机挂载
Android 8.1 启动篇(一) – 深入研究 init
SEAndroid
ANDROID权限说明 SYSTEM权限 ROOT权限
Android编译版本eng、user和userdebug的区别
Android模拟器获取Root权限
MTK android8.1添加root权限
MTK Android user版本如何打开root权限

发布了87 篇原创文章 · 获赞 157 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/u012932409/article/details/103353723
今日推荐