Android U user+root实现方案

背景

由于项目(MTK平台)上要实现user+root的版本,供特殊用户使用。Android T上的方案无效,经历了各种搜索查看资料,和bsp大佬一起通宵奋战,整出了方案。梳理记录下,有需要的同学可以参考。

Root代码实现原理

系统判断是否有root权限的地方在system/packages/modules/adb/daemon/main.cpp里面,

should_drop_privileges()函数返回false,表明可以root。

复制代码
auth_required 是否需要adb鉴权(adb弹框确认),false时默认授权adb鉴权权限,不需要弹框确认。

userdebug 版本可以root是因为ro.secure = 0,代码路径build/core/main.mk 在should_drop_privileges()里面有判断

java 复制代码
else # !user_variant
   # Turn on checkjni for non-user builds.
   ADDITIONAL_SYSTEM_PROPERTIES += ro.kernel.android.checkjni=1
   # Set device insecure for non-user builds.
   ADDITIONAL_SYSTEM_PROPERTIES += ro.secure=0
java 复制代码
static bool should_drop_privileges() {
    // 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
    // particularly obvious.
    //
    // ro.debuggable:
    //   Allowed to become root, but not necessarily the default. Set to 1 on
    //   eng and userdebug builds.
    //
    // ro.secure:
    //   Drop privileges by default. Set to 1 on userdebug and user builds.
    bool ro_secure = android::base::GetBoolProperty("ro.secure", true);
    bool ro_debuggable = __android_log_is_debuggable();

    // Drop privileges if ro.secure is set...
    bool drop = ro_secure;

    // ... except "adb root" lets you keep privileges in a debuggable build.
    std::string prop = android::base::GetProperty("service.adb.root", "");
    bool adb_root = (prop == "1");
    bool adb_unroot = (prop == "0");
    if (ro_debuggable && adb_root) {
        drop = false;
    }
    // ... and "adb unroot" lets you explicitly drop privileges.
    if (adb_unroot) {
        drop = true;
    }

    return drop;
}

实现中遇到的问题

1,selinux问题(主要解决问题);

2,缺少su 和remount执行的bin文件;

具体实现方案和步骤

1),特殊版本标识,CUSTOM_ROOT_VERSION=yes,编译版本时需要export下该环境变量

2),添加flag,路径build/core/soong_config.mk

Go 复制代码
--- a/core/soong_config.mk
+++ b/core/soong_config.mk
@@ -58,6 +58,9 @@
 
 $(call add_json_bool, Debuggable,                        $(filter userdebug eng,$(TARGET_BUILD_VARIANT)))
 $(call add_json_bool, Eng,                               $(filter eng,$(TARGET_BUILD_VARIANT)))
+$(call add_json_bool, ROOTVersion,                         $(filter yes,$(CUSTOM_ROOT_VERSION)))
 $(call add_json_str,  DeviceName,                        $(TARGET_DEVICE))

3),添加root版本的数据声明,设置root相关的flag需要

Go 复制代码
--- a/android/variable.go
+++ b/android/variable.go
@@ -151,6 +151,14 @@
 			}
 		}

+		ROOTVersion struct {
+			Cflags          []string
+			Cppflags        []string
+			Init_rc         []string
+		}

 		Pdk struct {
 			Enabled *bool `android:"arch_variant"`
 		} `android:"arch_variant"`
@@ -315,6 +323,9 @@
 	UseRBED8                         *bool    `json:",omitempty"`
 	Debuggable                       *bool    `json:",omitempty"`
 	Eng                              *bool    `json:",omitempty"`
+	ROOTVersion                        *bool    `json:",omitempty"`
 	Treble_linker_namespaces         *bool    `json:",omitempty"`

4),添加su 和 remount 模块,在产品的mk文件中添加

PRODUCT_PACKAGES +=remount

PRODUCT_PACKAGES +=su

5),在文件系统模块fs_mgr中添加ROOTVersion相应的flag,property_service中设置ro.secure和ro.debuggable的值

Go 复制代码
--- a/fs_mgr/Android.bp
+++ b/fs_mgr/Android.bp
@@ -118,6 +118,14 @@
                 "-DALLOW_ADBD_DISABLE_VERITY=1",
             ],
         },
+        ROOTVersion: {
+            cppflags: [
+                "-UALLOW_ADBD_DISABLE_VERITY",
+                "-DALLOW_ADBD_DISABLE_VERITY=1",
+            ],
+        },
     },
     header_libs: [
         "libfiemap_headers",
@@ -248,6 +256,17 @@
                 "clean_scratch_files.rc",
             ],
         },
+        ROOTVersion: {
+            cppflags: [
+                "-UALLOW_ADBD_DISABLE_VERITY",
+                "-DALLOW_ADBD_DISABLE_VERITY=1",
+            ],
+            init_rc: [
+                "clean_scratch_files.rc",
+            ],
+        },
     },
     symlinks: [
         "clean_scratch_files",

--- a/init/Android.bp
+++ b/init/Android.bp
@@ -149,6 +149,13 @@
                 "-DSHUTDOWN_ZERO_TIMEOUT=1",
             ],
         },
+        ROOTVersion: {
+            cppflags: [
+                "-DROOT_VERSION",
+            ],
+        },
         uml: {
             cppflags: ["-DUSER_MODE_LINUX"],
         },

--- a/init/property_service.cpp
+++ b/init/property_service.cpp
@@ -1328,6 +1328,19 @@
         }
     }
 
+    bool adbAuthorized = false;
+#ifdef ROOT_VERSION
+    adbAuthorized = true;
+#endif
+    if (adbAuthorized) {
+        InitPropertySet("ro.adb.secure", "0");
+        InitPropertySet("ro.debuggable", "1");
+    }
+
     for (const auto& [name, value] : properties) {

6)adb模块添加权限的判断,和5)中设置属性的值有重复,此处是为了确保生效。有时间的同学可以验证下去掉这一步看是否生效。

should_drop_privileges()函数最后添加

java 复制代码
#ifdef CUSTON_ROOT_VERSION
   return false;
#endif

drop_privileges()函数最后添加

java 复制代码
#ifdef CUSTON_ROOT_VERSION
   auth_required=false;
#endif

7),最重要的一步,更换sepolicy文件为debug版本的

(1)添加sepolicy,src文件是debug版本的,修改路径system/sepolicy/android.bp
Go 复制代码
--- a/Android.bp
+++ b/Android.bp
     },
 }
 
+se_policy_cil {
+    name: "userdebug_plat_sepolicy_root.cil",
+    src: ":userdebug_plat_sepolicy.conf",
+    additional_cil_files: [":sepolicy_technical_debt{.plat_private}"],
+    dist: {
+        targets: ["droidcore"],
+    },
+}
+
 // A copy of the userdebug_plat_policy in GSI.
(2),同路径下mk文件加入编译
Go 复制代码
--- a/Android.mk
+++ b/Android.mk

 LOCAL_REQUIRED_MODULES += \
     userdebug_plat_sepolicy.cil \

+ifeq ($(strip $(CUSTOM_ROOT_VERSION)),yes)
+LOCAL_REQUIRED_MODULES += \
+    userdebug_plat_sepolicy_root.cil
+endif
(3)代码中加载sepolicy地方GetUserdebugPlatformPolicyFile()也使用上面生成的sepolicy文件,代码路径system/core/init/selinux.cpp
cpp 复制代码
 std::optional<const char*> GetUserdebugPlatformPolicyFile() {
+#ifdef DF_VERSION
+    return "/system/etc/selinux/userdebug_plat_sepolicy_root.cil";
+#endif

至此,Android U版本user+root+remount方案修改完成。

相关推荐
雨白8 小时前
Jetpack系列(二):Lifecycle与LiveData结合,打造响应式UI
android·android jetpack
kk爱闹10 小时前
【挑战14天学完python和pytorch】- day01
android·pytorch·python
每次的天空11 小时前
Android-自定义View的实战学习总结
android·学习·kotlin·音视频
恋猫de小郭12 小时前
Flutter Widget Preview 功能已合并到 master,提前在体验毛坯的预览支持
android·flutter·ios
断剑重铸之日13 小时前
Android自定义相机开发(类似OCR扫描相机)
android
随心最为安13 小时前
Android Library Maven 发布完整流程指南
android
岁月玲珑13 小时前
【使用Android Studio调试手机app时候手机老掉线问题】
android·ide·android studio
还鮟17 小时前
CTF Web的数组巧用
android
小蜜蜂嗡嗡18 小时前
Android Studio flutter项目运行、打包时间太长
android·flutter·android studio
aqi0018 小时前
FFmpeg开发笔记(七十一)使用国产的QPlayer2实现双播放器观看视频
android·ffmpeg·音视频·流媒体