Android 系统开放Root权限给APK

Android 5.0 Lollipop 如何像4.2.2一样通过su命令获取root权限

4.2.2(Jelly Bean)上root的方法比较简单,调用su命令就可以获取到root权限并执行一些命令。但是在Android 4.3+到5.0,Google为这种root方法设置了层层障碍:

  1. su命令源码中添加了uid检验,只允许shell/root用户进行调用
  2. Zygote源码中添加了添加DropCapabilitiesBoundingSet屏蔽APP了setuid的功能
  3. adb源码中添加了添加should_drop_privileges屏蔽adb了setuid的功能(对于userdebug/eng版本该函数未被调用)
  4. 开启了SELinux安全模块,1,2条都满足情况下也会被中断su。
    具体解决方法:

针对前三项的解决方法是按照以下diff文件进行修改代码并重新编译Android系统:

1 su命令源码中添加了uid检验,只允许shell/root用户进行调用 
2 Zygote源码中添加了添加DropCapabilitiesBoundingSet屏蔽APP了setuid的功能
3 adb源码中添加了添加should_drop_privileges屏蔽adb了setuid的功能(对于userdebug/eng版本该函数未被调用)

以上三项需要改动代码并重新编译Android系统。
1,2,3代码修改的diff文件:

frameworks/base/cmds/app_process/app_main.cpp

project frameworks/base/
diff --git a/cmds/app_process/app_main.cpp b/cmds/app_process/app_main.cpp
index 1bb28c3..3e69750 100644
--- a/cmds/app_process/app_main.cpp
+++ b/cmds/app_process/app_main.cpp
@@ -185,6 +185,7 @@ static const char ZYGOTE_NICE_NAME[] = "zygote";

 int main(int argc, char* const argv[])
 {
+/*
     if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) < 0) {
         // Older kernels don't understand PR_SET_NO_NEW_PRIVS and return
         // EINVAL. Don't die on such kernels.
@@ -193,6 +194,7 @@ int main(int argc, char* const argv[])
             return 12;
         }
     }
+*/

     AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));
     // Process command line arguments

frameworks/base/core/jni/com_android_internal_os_Zygote.cpp

diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp
index 4f5e08b..8b136bd 100644
--- a/core/jni/com_android_internal_os_Zygote.cpp
+++ b/core/jni/com_android_internal_os_Zygote.cpp
@@ -208,6 +208,7 @@ static void EnableKeepCapabilities(JNIEnv* env) {
 }

 static void DropCapabilitiesBoundingSet(JNIEnv* env) {
+/*
   for (int i = 0; prctl(PR_CAPBSET_READ, i, 0, 0, 0) >= 0; i++) {
     int rc = prctl(PR_CAPBSET_DROP, i, 0, 0, 0);
     if (rc == -1) {
@@ -220,6 +221,7 @@ static void DropCapabilitiesBoundingSet(JNIEnv* env) {
       }
     }
   }
+*/
 }

 static void SetCapabilities(JNIEnv* env, int64_t permitted, int64_t effective) {

这个应该不用改 无论是5.1 或者6.0
system/core/adb/adb.c

project system/core/
diff --git a/adb/adb.c b/adb/adb.c
index 10a1e0d..2cd4f97 100644
--- a/adb/adb.c
+++ b/adb/adb.c
@@ -1261,6 +1261,7 @@ static void drop_capabilities_bounding_set_if_needed() {
 }

 static int should_drop_privileges() {
+    return 0;
 #ifndef ALLOW_ADBD_ROOT
     return 1;
 #else /* ALLOW_ADBD_ROOT */

增加su 的segid 和 setuid的权限

5.1 的情况可能是在如下文件中

diff --git a/include/private/android_filesystem_config.h b/include/private/android_filesystem_config.h
index 2f528b9..1223b45 100644
--- a/include/private/android_filesystem_config.h
+++ b/include/private/android_filesystem_config.h
@@ -244,7 +244,7 @@ static const struct fs_path_config android_files[] = {

     /* the following five files are INTENTIONALLY set-uid, but they
      * are NOT included on user builds. */
-    { 04750, AID_ROOT,      AID_SHELL,     0, "system/xbin/su" },
+    { 06755, AID_ROOT,      AID_SHELL,     0, "system/xbin/su" },
     { 06755, AID_ROOT,      AID_ROOT,      0, "system/xbin/librank" },
     { 06755, AID_ROOT,      AID_ROOT,      0, "system/xbin/procrank" },
     { 06755, AID_ROOT,      AID_ROOT,      0, "system/xbin/procmem" },
@@ -255,6 +255,7 @@ static const struct fs_path_config android_files[] = {

     { 00750, AID_ROOT,      AID_ROOT,      0, "system/bin/uncrypt" },
     { 00750, AID_ROOT,      AID_ROOT,      0, "system/bin/install-recovery.sh" },
+    { 06755, AID_ROOT,      AID_ROOT,      0, "system/bin/su" },
     { 00755, AID_ROOT,      AID_SHELL,     0, "system/bin/*" },
     { 00755, AID_ROOT,      AID_ROOT,      0, "system/lib/valgrind/*" },
     { 00755, AID_ROOT,      AID_ROOT,      0, "system/lib64/valgrind/*" },

6.0 的应该在如下的文件中改变

~/base/code/s905x-vega/s912_0907/system $ git diff core/libcutils/fs_config.c
diff --git a/s912_0907/system/core/libcutils/fs_config.c b/s912_0907/system/core/libcutils/fs_config.c
index 9a1ad19..1e52b08 100644
--- a/s912_0907/system/core/libcutils/fs_config.c
+++ b/s912_0907/system/core/libcutils/fs_config.c
@@ -123,7 +123,8 @@ static const struct fs_path_config android_files[] = {

     /* the following five files are INTENTIONALLY set-uid, but they
      * are NOT included on user builds. */
-    { 04750, AID_ROOT,      AID_SHELL,     0, "system/xbin/su" },
+    //{ 04750, AID_ROOT,      AID_SHELL,     0, "system/xbin/su" },
+    { 06755, AID_ROOT,      AID_ROOT,     0, "system/xbin/su" },
     { 06755, AID_ROOT,      AID_ROOT,      0, "system/xbin/librank" },
     { 06755, AID_ROOT,      AID_ROOT,      0, "system/xbin/procrank" },
     { 06755, AID_ROOT,      AID_ROOT,      0, "system/xbin/procmem" },

5.1的 su应该是这样

project system/extras/
diff --git a/su/su.c b/su/su.c
index 8365379..826acfc 100644
--- a/su/su.c
+++ b/su/su.c
@@ -107,11 +107,12 @@ int main(int argc, char **argv)

     /* Until we have something better, only root and the shell can use su. */
     myuid = getuid();
+    /*
     if (myuid != AID_ROOT && myuid != AID_SHELL) {
         fprintf(stderr,"su: uid %d not allowed to su\n", myuid);
         return 1;
     }
-
+    */
     if(argc < 2) {
         uid = gid = 0;
     } else {

6.0 的su如下

~/base/code/s905x-vega/s912_0907/system $ git diff extras/su/su.c
diff --git a/s912_0907/system/extras/su/su.c b/s912_0907/system/extras/su/su.c
index d932c1b..2cf5381 100644
--- a/s912_0907/system/extras/su/su.c
+++ b/s912_0907/system/extras/su/su.c
@@ -82,7 +82,7 @@ void extract_uidgids(const char* uidgids, uid_t* uid, gid_t* gid, gid_t* gids, i

 int main(int argc, char** argv) {
     uid_t current_uid = getuid();
-    if (current_uid != AID_ROOT && current_uid != AID_SHELL) error(1, 0, "not allowed");
+    //if (current_uid != AID_ROOT && current_uid != AID_SHELL) error(1, 0, "not allowed");

     // Handle -h and --help.
     ++argv;

设置SELinux权限为Permissive

我是尽量把事情简单化,这次这里讨论的是SELinux,其实现原理会比较复杂,我这里只是简单记录在Android 5.0 + Linux 3.4如何将SELinux降级,这么做的原因是实现:APP可以调用su命令最终实现运行一些命令。

SELinux常用状态有两个Permissive 和 Enforcing,后者会使APP无法调用su命令,前者可以。

  1. 查询当前SELinux状态:

运行该命令后,会输出当前系统的SELinux权限Permissive 和 Enforcing。
2. 在eng/userdebug版本 将SELinux 模式调整到Permissive mode

临时方案:运行如下命令(无需重启系统,即刻见效)
1
adb shell setenforce 0
1
长久方案:在启动参数中添加

androidboot.selinux=permissive
1
或者在system/core/init.cpp 中更改

diff --git a/s912_0907/system/core/init/init.cpp b/s912_0907/system/core/init/init.cpp
index 05c0c05..2432bdb 100644
--- a/s912_0907/system/core/init/init.cpp
+++ b/s912_0907/system/core/init/init.cpp
@@ -908,6 +908,7 @@ static selinux_enforcing_status selinux_status_from_cmdline() {

 static bool selinux_is_disabled(void)
 {
+    //return true;
     if (ALLOW_DISABLE_SELINUX) {
         if (access("/sys/fs/selinux", F_OK) != 0) {
             // SELinux is not compiled into the kernel, or has been disabled
@@ -982,6 +983,7 @@ static void selinux_initialize(bool in_kernel_domain) {
         }

         bool is_enforcing = selinux_is_enforcing();
+        is_enforcing = 0;
         security_setenforce(is_enforcing);

         if (write_file("/sys/fs/selinux/checkreqprot", "0") == -1) {

————————————————
版权声明:本文为CSDN博主「alianqiugui」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/alianqiugui/article/details/79392101

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值