Android 系统 -- android apk 的root 权限和USB adb 权限的区别
android apk 的root 权限和usb adb 权限的区别
usb adb 权限是指,当adb 连接手机时,手机中的守护进程adbd 的权限为root 权限,从而它的子进程也具有root 权限,通常如果adb shell 看到是:
android 4.0 以后版本:
c:\>adb shell
root@android:/#
android 2.3 版本:
c:\>adb shell
#
即表明adb 的连接是root 权限的,相反如果看到是$ 即表明是shell 权限android 的apk 本身都是不具备root 权限的,如果想启用root 权限,那么就必须借助具有root 权限的进程或者具有s bit 的文件,目前比较通用的手法是,手机root 后,内置了su到system/bin, 然后普通app 即可借助su 命令来达到root 权限切换。
网络上已经有同仁修改su 命令,并通过一个apk 来控制su 命令的权限控制。
supersu:https://forum.xda-developers.com/showthread.phpt=1538053(更新速度很快,推荐使用)综上所叙,如果adb 已经有root 权限,那么让apk 行使root 权限就很简单了。比如在jb 版本或者以前的版本上:
adb remount
adb push su /system/bin
adb push superuser.apk /system/app
adb shell chmod 0644 /system/app/superuser.apk
adb shell chmod 6755 /system/bin/su
adb reboot
kk 以后的版本:
* adb 的root 权限是在system/core/adb/adb.c 中控制。主要根据ro.secure 以及 ro.debuggable 等system property 来控制。
默认即档ro.secure 为0 时,即开启root 权限,为1时再根据ro.debuggable 等选项来确认是否可以用开启root 权限。为此如果要永久性开启adb 的root 权限,有两种修改的方式:
1. 修改system property ro.secure, 让ro.secure=0。
2. 修改adb.c 中开启root 权限的判断逻辑。
*在l 版本上adb 会受到selinux 的影响, 所以需要调整selinux policy 设置.
下面详细说明这两种修改方式:
第一种方法. 修改system property ro.secure, 让ro.secure=0。
(1)修改alps/build/core/main.mk
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 即可。
(2)在android jb 版本(4.1) 以后,google 从编译上直接去除了adbd 的user 版本root 权限, 为此您要修改system/core/adb/android.mk 中的编译选项allow_adbd_root, 如果没有打开这个选项,那么adb.c 中将不会根据ro.secure 去选择root 还是shell 权限,直接返回shell 权限。因此您必须需要android.mk 中的第126行:
ifneq (,$(filter userdebug eng,$(target_build_variant)))
===> ifneq (,$(filter userdebug user eng,$(target_build_variant)))
(3)在android l (5.0) 以后, google 默认开启selinux enforce mode, 需要在user build 上将su label 默认build 进sepolicy.
放开selinux 的限制. 更新alps/external/sepolicy/android.mk 116 行, 将su label 默认编译进入sepolicy.
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) : $(call build_policy, $(sepolicy_build_files))
@mkdir -p $(dir $@)
$(hide) m4 -d mls_num_sens=$(private_mls_sens) -d mls_num_cats=$(private_mls_cats) \
-d target_build_variant=$(target_build_variant)\
-d force_permissive_to_unconfined=$(force_permissive_to_unconfined) \
-s $^ > $@
$(hide) sed '/dontaudit/d' $@ >$@.dontaudit
将-d target_build_variant=$(target_build_variant) 改成 -d target_build_variant=eng
如果是n 版本, selinux policy 已经搬移到 alps/system/sepolicy.
即第一种方法在android l(5.0) 以后你需要改(1),(2),(3).
第二种方法. 修改adb.c 中开启root 权限的判断逻辑。这里针对4.1 以后版本 和4.1以前版本有所区别。
(1).如果是jb 4.1 以后版本,直接修改函数should_drop_privileges()函数, 清空这个函数,直接返回 0 即可。返回0 即开启root 权限。
(2).如果是jb 4.1 以前版本,直接修改函数adb_main 函数,在
/* don't listen on a port (default 5037) if running in secure mode */
/* don't run as root if we are running in secure mode */
if (secure) {
struct __user_cap_header_struct header;
struct __user_cap_data_struct cap;
if (prctl(pr_set_keepcaps, 1, 0, 0, 0) != 0) {
exit(1);
}
在这段代码前加一行:
secure = 0; //mtk71029 add for root forever.
/* don't listen on a port (default 5037) if running in secure mode */
/* don't run as root if we are running in secure mode */
if (secure) {
struct __user_cap_header_struct header;
struct __user_cap_data_struct cap;
if (prctl(pr_set_keepcaps, 1, 0, 0, 0) != 0) {
exit(1);
}
(3)在android l (5.0) 以后, google 默认开启selinux enforce mode, 需要在user build 上将su label 默认build 进sepolicy.
放开selinux 的限制. 更新alps/external/sepolicy/android.mk 116 行, 将su label 默认编译进入sepolicy.
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) : $(call build_policy, $(sepolicy_build_files))
@mkdir -p $(dir $@)
$(hide) m4 -d mls_num_sens=$(private_mls_sens) -d mls_num_cats=$(private_mls_cats) \
-d target_build_variant=$(target_build_variant)\
-d force_permissive_to_unconfined=$(force_permissive_to_unconfined) \
-s $^ > $@
$(hide) sed '/dontaudit/d' $@ >$@.dontaudit
将-d target_build_variant=$(target_build_variant) 改成 -d target_build_variant=eng
如果是n 版本, selinux policy 已经搬移到 alps/system/sepolicy.
即第二种方法在android l(5.0) 以后你需要改(1),(3).
[测试与确认]
当修改完成后,只需要重新build bootimage ,然后download 即可,然后到setting 中开启debug 选项,adb 连接后,会显示 #, 即root 成功。
(1). adbd 的root 权限
我们通常在debug user 版本问题时, 或者进行user 版本的monkey test 时都会这个工作,以便debug. 可以参考faq.如果你想user 版本adb root 权限默认关闭, 而在想开启时, 可以通过工程模式中的设置项开启, 那么请user2root 功能 (l 版本不再支持此功能)。
此功能默认关闭, 如果开启, 需要在projectconfig.mk 中设置: mtk_user_root_switch = yes
同样注意此项功能通常只用于debug 或者 cmcc 送测, 在正式出货版本, 强烈要求关闭, 否则有安全风险.
(2). app 的root 权限
app 的root 权限通常是通过执行su 命令来获取。注意的是kk 上, 因为多种限制, 普通的su 难以直接拿到root 权限, 需要做针对性的改动.
通常我们会内置具有控制端的第三方su, 下面以内置supersu, 以及使用google default su 为例进行说明。(3). 如何内置第三方supersu
该方式可以绕过zygote 和 adbd 对root capabilities boundset 的限制. mtk 目前仅测试kk 以及以前的版本,l 版本后因为supersu 还在持续更新中, 请客户查看它官网的说明.
3.1. 下载supersu
supersu:https://forum.xda-developers.com/showthread.phpt=1538053
3.2. 内置superuser.apk 到 system/app
将su 复制并改名成: daemonsu
内置su 到 system/xbin
内置daemonsu 到 system/xbin
内置chattr 到 system/xbin
内置chattr.pie 到 /system/xbin3.3. 内置install-recovery.sh 到system/etc
并且按照faq: faq09021 如何修改内置文件的权限, 用户,属性https://online.mediatek.com/pages/faq.xlist=sw&faqid=faq09021
更新alps/system/core/inlcude/private/android_filesystem_config.h
在android_files 数组的最开始新增.
{ 00755, aid_root, aid_root, 0, "system/etc/install-recovery.sh" },
(4). 如何内置google default su
4.1 放开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;
}4.2 首先将此编译出的su 内置到system/bin, 然后修改su 的内置权限,启用sbit 位.
按照faq: faq09021 如何修改系统内置文件的权限, 用户,属性https://online.mediatek.com/pages/faq.aspxlist=sw&faqid=faq09021
更新alps/system/core/inlcude/private/android_filesystem_config.h
在android_files 数组中
增加
{ 06755, aid_root, aid_root, 0, "system/bin/su" },
注意这行要放在
{ 00755, aid_root, aid_shell, 0, "system/bin/*" },
之前4.3 如果是kk 版本(非kk2 mt6752/mt6732), 需要强行解除zygote 和 adbd 对root capabilities boundset 的限制
更新kernel/security/commoncap.c 中 cap_prctl_drop 函数为:
static long cap_prctl_drop(struct cred *new, unsigned long cap)
{
//mtk71029 add begin: let 'zygote' and 'adbd' drop root capabilities boundset ineffectively
if (!strncmp(current->comm, "zygote", 16)) {
return -einval;
}
if (!strncmp(current->comm, "adbd", 16)) {
return -einval;
}
// add end if (!capable(cap_setpcap))
return -eperm;
if (!cap_valid(cap))
return -einval; cap_lower(new->cap_bset, cap);
return 0;
}4.4 如果贵司一定要在k2(mt6752/mt6732)上开启, 请提交eservice, 申请定制的dvm, 放开相关的权限限制.4.5 如果贵司在l 版本操作, 请按下面的流程:
4.5.1 更新alps/frameworks/base/core/jni/com_android_internal_os_zygote.cpp
将 dropcapabilitiesboundingset(jnienv* env) 这个函数置空.
4.5.2 更新alps/frameworks/base/cmds/app_process/app_main.cpp 的main 函数,注释掉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;
}
}
4.5.3 更新alps/system/core/adb/adb.c 将should_drop_privileges() 函数, 清空这个函数,直接返回 0 即可.
4.5.4 将selinux 调整到permissve mode, 参考faq11484:https://online.mediatek.inc/pages/faq.aspxlist=sw&faqid=faq11484
重新编译系统, 重新download 后, adb shell 进入后再输入su 看看是否命令行由$切换到#, 如果切换即成功。
(5). 在kk 版本后app 使用root 权限受到更加严格的限制。android kk 4.4 版本后,user 版本su 权限严重被限制。
上一篇: 该有的要素都有了
下一篇: Android 之 Bitmap 解析