手把手教你root Android系统

因为从事的是智能家居相关行业,用的系统也是android系统,在某些场景下可能需要拿到系统的root权限。下面就手把手教大家去拿到app的root权限和adb的root权限,比如一般手机在出厂的时候,开关机动画都是固定的,但是如果有一个需求就是需要你动态的去切换开关机的动画的时候,可能就需要你拿到root权限,然后对system/media的开关机动画进行操作等,这些都是需要拿到root权限才能进行的

当然在android系统的root权限中也是有区别的,会在下面指出区别在哪:
您要确认您是想开启adbd 的root 权限,还是让app 也可以拿到root 权限。他们之间是有很大区别的,起功能导向也肯定不一样,举个例子:如果你的系统adb root了,并不代表你的apk可以对系统目录进行操作,同样也是apk如果拿到root权限,也不一定代表可以拿到所有对系统的操作权限;

注意严重声明: 任何在最终user版本上打开root权限的手法都会给用户带来安全风险, 请仔细评估您的需求是否真实需要.
MTK 强烈反对此类做法, 由此带来的安全风险,以及造成的损失, MTK 不承担任何的责任。
注意:MTK是强烈反对对user版本进行root的,因为会带来严重的安全行问题

什么是adb的权限:
USB adb 权限是指,当adb 连接手机时,手机中的守护进程adbd 的权限为root 权限,从而它的子
进程也具有root 权限,通常如果adb shell 看到是:

在上面可以看到:在输入adb shell之后,直接拿到的就是root的权限

什么是apk的root权限
一个apk想要拿到系统的root权限可没那么容易,知道linux的都知道,linux系统下如果想拿到系统的权限就必须要使用sudo命令,同样,在android系统中,如果你想你的apk可以拿到系统的权限,就必须要su,那么这个su就要在编译的时候编译到system/bin文件夹或者system/xbin下面,而且su文件使用权限也必须要对普通的用户进行开放


从上图可以看出,集成了su命令的系统,在进去shell的时候,其adb是没有root权限的,依旧是 ,但是在执行su,命令之后,其后面的 ,但是在执行su,命令之后,其后面的就已经转变成#,说明已经拿到root的权限了,但是本篇博客重点讲的就是如何去进行adb的root和apk的root

如何永久性开启adb的root的权限

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

即第一种方法在android L(5.0) 以后你需要改(1),(2),(3).
注:目前我们项目的系统是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

即第二种方法在android L(5.0) 以后你需要改(1),(3).
当修改完成后,只需要重新build bootimage ,然后download 即可,然后到setting 中开启debug选项,adb 连接后,会显示 #, 即root 成功。

如何去开启apk的root权限(su命令内置和克服SELINUX)

通过内置第三方SuperSU来进行apk的root(PS:作者由于项目时间比较忙,并没有尝试过这样的root方法)

该方式可以绕过zygote 和 adbd 对Root Capabilities BoundSet 的限制. MTK 目前仅测试KK 以及以前的版本, L 版
本后因为SuperSU 还在持续更新中, 请客户查看它官网的说明.
1:下载SuperSU
SuperSU: http://forum.xda-developers.com/showthread.php?t=1538053
2:内置Superuser.apk 到 system/app

将su 复制并改名成: daemonsu
内置su 到 system/xbin
内置daemonsu 到 system/xbin
内置chattr 到 system/xbin
内置chattr.pie 到 /system/xbin

3. 内置install-recovery.sh 到system/etc

更新alps/system/core/inlcude/private/android_filesystem_config.h
在android_files 数组的最开始新增.
{ 00755, AID_ROOT, AID_ROOT, 0, "system/etc/install-recovery.sh" },

第二种方法就是内置Google default su命令

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;
}

2:首先将此编译出的su 内置到system/bin, 然后修改su 的内置权限,启用sbit 位.

1、修改 alps\system\extras\su\Android.mk
LOCAL_MODULE_TAGS := debug 改为 LOCAL_MODULE_TAGS := optional
注:将su设置在编译的时候不仅仅是在debug状态下才编译的 2、修改 alps\build\target\product\core.mk
增加PRODUCT_PACKAGES += \ su \
注:在编译的时候,编译su项目3、如果是KK(非KK2)版本。需要强行解除 zygote 和adbd 对Root Capabilities BoundSet 的限制。修改 alps\kernel\security\commoncap.c 增加static long cap_prctl_drop(struct cred *new, unsigned long cap) { //add start 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、然后修改su 的内置权限
更新alps/system/core/inlcude/private/android_filesystem_config.h
在android_files 数组中,将原来su的权限修改成:
{ 06755, AID_ROOT,  AID_ROOT,      0, "system/xbin/su" },
注:这个时候编译出来的是可以获取root权限的,并且其编译成功后的目录是在system/xbin目录下的

3:如果贵司在L 版本操作, 请按下面的流程:(目前我操作的版本是L版本以后的)

更新alps/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 {ALOGE("prctl(PR_CAPBSET_DROP) failed");RuntimeAbort(env);}}}*/
}

4:更新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;}

}

5:如果是L 版本, 需要手动关闭SELinux

更新bootable/bootloader/lk/platform/mt6xxx/rules.mk
# choose one of following value -> 1: disabled/ 2: permissive /3: enforcing
SELINUX_STATUS := 3
调整这个SELINUX_STATUS这个的值为 2

6:修改system/core/init/Android.mk 新增

ifeq ($(strip $(TARGET_BUILD_VARIANT)),user)
LOCAL_CFLAGS += -DALLOW_DISABLE_SELINUX=1
endif

笔者也是在网上参考了很多过来的人经验,再结合自己在实际修改权限的过程中遇到的某些问题做的一些总结,可能有时候我们做手机并不需要去更改的系统想相关的权限,而我们的用户可能对手机root也并不是那么敏感。但是作为一个开发者,并不意味着我们不会遇到某些场景下,需要打开root的这样的需求。当然,如果打开了root之后,最直接的结果可能就是会导致安全性会稍稍降低,但是也可以采用其他的方式来避免

参考的相关博客:
http://blog.csdn.net/muyang_ren/article/details/49507393
http://blog.csdn.net/kangear/article/details/51872653

当然这些内容其实在FAQ中其实都是有讲解和解决的,只是这个文档相对来说是比较大,就没有传上去了,在这里有需要的可以关注下 私信发一下

欢迎访问我的博客

android开发中,手把手教你root Android系统相关推荐

  1. Android 开发之手把手教你写 ButterKnife 框架(三)

    系列文章目录导读: Android开发之手把手教你写ButterKnife框架(一) Android开发之手把手教你写ButterKnife框架(二) Android开发之手把手教你写ButterKn ...

  2. Android开发中遇到的问题(四)——Android中WARNING: Application does not specify an API level requirement!的解决方法

    Android开发中遇到的问题(四)--Android中WARNING: Application does not specify an API level requirement!的解决方法 参考文 ...

  3. android开发中遇到的技术难题,android开发过程中遇到的问题以及解决办法

    ####编译的时候遇到的问题: "android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original th ...

  4. android开发模式,Android开发中无处不在的设计模式

    Android开发中无处不在的设计模式――单例模式 Android开发中无处不在的设计模式――Builder模式 前面介绍了单例模式和Builder模式,有兴趣的见上面两个链接,这篇文章侧重介绍1下视 ...

  5. Android开发中无处不在的设计模式——动态代理模式

    继续更新设计模式系列.写这个模式的主要原因是近期看到了动态代理的代码. 先来回想一下前5个模式: - Android开发中无处不在的设计模式--单例模式 - Android开发中无处不在的设计模式-- ...

  6. Android常用:手把手教你实现搜索框(含历史搜索记录)

    http://blog.csdn.net/carson_ho/article/details/53366570 前言 像下图的搜索功能在Android开发中非常常见 今天我将手把手教大家如何实现具备历 ...

  7. 史上最全Android开发中100%会用到的开源框架整理(1/5)

    其实这个开源框架整理很久了,只是一直放在有道云笔记里面,笔者还有很多写得文章都放在有道云笔记里面,有时间都好好整理一下放出来,本篇文章也会不定期更新,由于整理的开源框架分类都有200多个,所有这次只将 ...

  8. 在 Android 开发中使用 Kotlin 协程 (一) -- 初识 Kotlin 协程

    前言 最近在研究 Kotlin 协程,发现功能真的超级强大,很有用,而且很好学,如果你正在或计划使用 Kotlin 开发 Android,那么 Kotlin 协程你一定不能错过! 协程是什么? 我们平 ...

  9. android addview指定位置,Android开发中,请问当在一个视图中addView另一个布局视图时为什么报错?...

    Android开发中,我在一个视图中addView另一个布局视图(该视图通过inflate加载获得,其中root为null即没有附加parent视图),为什么还是会报错误: The specified ...

最新文章

  1. CSS盒模型及边距问题
  2. 宇宙中至少有两种方式能灭绝人类,第一种仅需两秒
  3. [转]23种经典设计模式的java实现_5_职责链模式
  4. KMP算法的动态规划解说
  5. python爬虫和数据分析电脑推荐_大数据分析必备的5款Python爬虫库
  6. Windows 下的 PHP 编译
  7. UI5 EventBus
  8. 设置本地Nexus存储库并从Maven部署WAR文件
  9. mysql的主主复制模型
  10. Unity3D中脚本的执行顺序和编译顺序
  11. SVN中,A项目如何共享B项目的内容
  12. 西电版《离散数学》勘误
  13. 解决微信小程序银行卡号输入转换格式
  14. 最小二乘法的线性拟合
  15. Express4.X版本修改默认模板jade为ejs并且试用html为视图模板后缀名
  16. 如何把win7电脑设置成网站服务器吗,如何为win7电脑设置服务器
  17. Ubuntu 怎么在 Libreoffice 中添加字体
  18. 解决 docker 磁盘空间不足问题
  19. 你真的适合学习JAVA开发吗?
  20. 统计学习导论(ISLR)(四):分类算法

热门文章

  1. ubuntu使用docker搭建licode
  2. 理解HBase面向列存储
  3. 好用到爆的python实战技巧
  4. 调色板,真彩色,DDB,DIB,BMP,RGB,YUV
  5. 类EMD的“信号分解方法”及MATLAB实现(第四篇)——VMD
  6. 暴风集团公布前三季度业绩预告,盈利同比增长惊人
  7. 微信小程序如何制作消息提示框---wx.showToast(Object object)
  8. php网络验证系统源码,kakaPHP 网络验证PHP服务端源码 - 下载 - 搜珍网
  9. 解决 invalid multibyte string 1
  10. uni-app 小项目开发 仿小米商城 后端提供数据3