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權限

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章