User版本的root權限

本文檔的一些實現是基於Android7.0 ,其餘android版本可能會有一些差別。linux

adbd 的root 權限

使用adb命令鏈接手機,手機中的守護進程adbd的權限爲root權限,它的子進程也具備root權限。android

執行adb shell ,若是包含#,表示adb的鏈接是root權限,以下所示:shell

test:/#
複製代碼

反之,若是看到是$ 即代表是shell 權限,以下所示:數組

test:/$
複製代碼
app 的root 權限

Android 的APK 自己都是不具有root 權限的,若是想啓用root 權限,那麼就必須藉助具備root權限的進程或者具備s bit (+s權限)的文件。安全

目前比較通用的手法是,手機root 後,內置了su到system/bin, 而後普通APP 便可藉助su 命令來達到root 權限切換。bash

注意:任何在最終user版本上打開root權限的手法都會給用戶帶來安全風險, 請仔細評估確認。

adbd 的root 權限(user)

一、修改build/core/main.mkapp

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=0ide

二、修改system/core/adb/Android.mk函數

ifneq (,$(filter userdebug eng,$(TARGET_BUILD_VARIANT)))
LOCAL_CFLAGS += -DALLOW_ADBD_DISABLE_VERITY=1
LOCAL_CFLAGS += -DALLOW_ADBD_ROOT=1
endif
複製代碼

ifneq (,$(filter userdebug eng,$(TARGET_BUILD_VARIANT)))ui

改成ifneq (,$(filter userdebug user eng,$(TARGET_BUILD_VARIANT)))

三、修改system/sepolicy/Android.mk

sepolicy_policy.conf := $(intermediates)/policy.conf
$(sepolicy_policy.conf): PRIVATE_MLS_SENS := $(MLS_SENS)
$(sepolicy_policy.conf): PRIVATE_MLS_CATS := $(MLS_CATS)
$(sepolicy_policy.conf): PRIVATE_ADDITIONAL_M4DEFS := $(LOCAL_ADDITIONAL_M4DEFS)
$(sepolicy_policy.conf): $(call build_policy, $(sepolicy_build_files))
	@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=eng \
		-s $^ > $@
	$(hide) sed '/dontaudit/d' $@ > $@.dontaudit
複製代碼

-D target_build_variant=$(TARGET_BUILD_VARIANT) 改爲 -D target_build_variant=eng

app 的root 權限

一、內置Google default su

在device.mk中添加su,系統默認是不編譯su的

PRODUCT_PACKAGES += su
複製代碼

修改system/extras/su路徑下的Android.mk 文件,將su編譯到system/bin 下

LOCAL_MODULE_PATH := $(PRODUCT_OUT)/system/bin
複製代碼
放開Google default su 只准shell/root 用戶使用的限制。

system/extras/su/su.c 中刪除下面3行代碼

if (myuid != AID_ROOT && myuid != AID_SHELL) {
    fprintf(stderr,"su: uid %d not allowed to su\n", myuid);
    return 1;
}
複製代碼
二、修改su 的內置權限,啓用sbit 位

路徑:system/core/libcutils/fs_config.c 在fs_path_config android_files[]數組中增長

{ 06755, AID_ROOT,      AID_ROOT,      0, "system/bin/su" },

複製代碼

須要放在下面一行以前

{ 00755, AID_ROOT,      AID_SHELL,     0, "system/bin/*" },
複製代碼
三、其餘修改

一、路徑:frameworks/base/core/jni/com_android_internal_os_Zygote.cpp

將 DropCapabilitiesBoundingSet(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) {
      if (errno == EINVAL) {
        ALOGE("prctl(PR_CAPBSET_DROP) failed with EINVAL. Please verify "
              "your kernel is compiled with file capabilities support");
      } else {
        RuntimeAbort(env, __LINE__, "prctl(PR_CAPBSET_DROP) failed");
      }
    }
  } */
}
複製代碼

二、路徑:frameworks/base/cmds/app_process/app_main.cpp

註釋掉main函數開始的下面這段代碼

/*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.
        if (errno != EINVAL) {
            LOG_ALWAYS_FATAL("PR_SET_NO_NEW_PRIVS failed: %s", strerror(errno));
            return 12;
        }
    }*/
複製代碼

三、路徑:system/core/adb/daemon/main.cpp

將should_drop_privileges()函數清空,直接返回 0 便可

static bool should_drop_privileges() {
	return 0;
}
複製代碼

四、將SELinux 調整到permissve mode

路徑: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;
}
複製代碼

app 的root 權限驗證

查看當前應用(Helloworld)的 uid(u0_a61), 並切到該用戶下,而後再運行su就至關於該APP在調用su命令了。

若是app有root權限,$會切換爲#,不然執行su會提示權限錯誤。
root@android:/ # ps
u0_a61 12218 120 1259632 40368 ffffffff b6e2da80 S com.example.helloworld
root@android:/ # su u0_a61
root@android:/ $ su
root@android:/ # 
複製代碼
相關文章
相關標籤/搜索