本文档的一些实现是基于Android7.0 ,其余android版本可能会有一些差别。linux
使用adb命令链接手机,手机中的守护进程adbd的权限为root权限,它的子进程也具备root权限。android
执行adb shell ,若是包含#,表示adb的链接是root权限,以下所示:shell
test:/#
复制代码
反之,若是看到是$ 即代表是shell 权限,以下所示:数组
test:/$
复制代码
Android 的APK 自己都是不具有root 权限的,若是想启用root 权限,那么就必须借助具备root权限的进程或者具备s bit (+s权限)的文件。安全
目前比较通用的手法是,手机root 后,内置了su到system/bin, 而后普通APP 便可借助su 命令来达到root 权限切换。bash
一、修改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=0
ide
二、修改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
在device.mk中添加su,系统默认是不编译su的
PRODUCT_PACKAGES += su
复制代码
修改system/extras/su路径下的Android.mk 文件,将su编译到system/bin 下
LOCAL_MODULE_PATH := $(PRODUCT_OUT)/system/bin
复制代码
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;
}
复制代码
路径: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;
}
复制代码
查看当前应用(Helloworld)的 uid(u0_a61), 并切到该用户下,而后再运行su就至关于该APP在调用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:/ #
复制代码