概述:通过阅读本文可以深刻理解Android系统中获得Root权限的方法和原理。本文会详细介绍Root的目的,原理和代码层次的具体实现方法。

Android Root介绍:

1. Root目的

手机获得Root权限以后,用户就可以完全拥有手机系统的最高权限,在Linux系统中相当于Root账号,在Windows系统中相当于Administrator账号。因为Android系统是基于Linux的,所以叫Root权限。

有了Root权限以后,用户可以自由删除一些系统自带的无用软件,更换开关机铃声,去除状态栏弹出的广告和常用软件中嵌入的第三方广告平台展示广告的干扰,让你的手机随心所欲,不再受干扰,总之一句话Root可以让你真正享有手机主人的感觉。

2. Root原理介绍

给手机Root的原理大概分为三个步骤:步骤一,把su文件拷贝到/system/bin/目录下面。步骤二,把Superuser.apk放到/system/app/目录下面。步骤三,设置/system/bin/su让任意用户都可以运行并且拥有set_uid和set_gid的权限。

当然,这些操作厂商是不会轻易允许我们这样做的,这样我们就需要去利用Android操作系统的各种漏洞去实现这些操作,利用这些漏洞完成以上三步操作的过程就是Root的过程。

Su – Switch User切换用户。

3. Root方法介绍

      从Root的原理我们了解到,想要Root需要三个步骤:

  1. adb push su /system/bin ­­­­­­­­­— xbin下是放一些小工具来方便使用的
  2. adb push SuperUser.apk /system/app
  3. adb shell chmod 4755 /system/bin/su(关于chmod XXX可以到这里了解一下http://hi.baidu.com/angivo/item/345af44260142b09e9350416

      如果系统是英文版,那么经过以上三个步骤,Root就大功告成了,通过安装Root Explorer软件就可以在根目录下创建删除文件了。但是国内的手机的系统都是经过厂商改造过的中文版,通过以上三个步骤是不行的,原因有以下三点:

  1. 中文版的/system路径是只读权限,我们是不能完成写入或者copy操作的
  2. chmod命令是需要拥有Root权限后才可以使用的,我们的在操作的时候是没有Root权限的,所以这个命令在我们Root过程中是无法使用的
  3. 某些厂商定制的系统在系统重新启动的时候会自动将su的权限从4755改成755或者直接删除了su,正是因为这个原因我们经常会碰到,明明我们是已经Root过的手机,但是手机重启后就没有Root权限了。这种只是临时获得的Root权限。

针对以上三点,我们怎么能够确保获得永久的Root权限呢?一种方案是自己去烧制一个英文版boot.img,刷一个英文版的系统然后再Root就OK了。另外一种方案就是去实时监控system/bin目录下已有的su文件是否存在,如果不存在就立即copy一个过去。

4. 深入理解Root机制

      Root调用流程如下:

  1. su被用户调用
  2. su创建一个socket监听,搭建一个通道来完成通讯
  3. su通过广播的方式通知superuser目前有一个应用要使用Root
  4. su等待socket数据通讯完成,通常会有超时处理
  5. superuser在收到广播以后会在界面弹出一个对话框,与用户交互,询问用户是否给予Root权限
  6. superuser将用户的选择结果再通过socket回传给su
  7. su根据socket得到的结果在做相应的处理判断应不应该继续给Root权限
  8. 完成本次授权处理

Superuser.apk这个应用是Root成功后,专门用来管理Root权限使用的,防止恶意应用滥用。可以去这个地方下载官方的superuser源码和su文件:http://superuser.googlecode.com/svn/trunk/ 自己就可以在Eclipse上打开superuser代码,完成编译和安装。

Superuser和su之间的通讯原理:

Superuser使用运行在Java虚拟机中,而su是运行在Linux的真是进程中,他们两个之间通讯superuser这个应用来完成大部分工作,superuser一共有两个Activity:一个是SuperuserActivity另外一个是SuperuserRequestActivity,其中SuperuserActivity是用来管理白名单的,用来记住那些应用程序已经被允许使用Root权限了,这样白名单中的应用再次提权时,就不需要麻烦用户选择了。而superuserRequestActivity是用来负责弹出对话框询问用户当前某个应用请求使用Root权限,让用户来完成选择授予还是不授予。如果用户选择永久授予Root权限,那会通过SuperuserActivity会将本次提权的应用写入白名单中。白名单其实就是一个sqlite的数据库,来保存用户选择永久授予Root权限的应用名单。白名单在数据库中位置为:

/data/data/com.koushikdutta.superuser/databases/superuser.sqlite

上文已经说过,Root的本质就是往 /system/bin/ 目录下放一个su文件,并且给su文件4755的权限,任何用户都有调用su的权限,这样普通程序可以调用该su来运行Root权限的命令。superuser.apk中就自带了一个这样的su程序。一开始superuser会检测/system/bin/su是否存在:

File su = new File("/system/bin/su");

// 检测su文件是否存在,如果不存在则直接返回

if (!su.exists())  {

Toast toast = Toast.makeText(this, "Unable to find /system/bin/su.",

Toast.LENGTH_LONG);

toast.show();

return;

}

//如果大小一样,则认为su文件正确,直接返回了事。

if (su.length() == suStream.available())

{

suStream.close();

return;

}

// 如果检测到/system/bin/su 文件存在,但是不对头,则把自带的su先写到"/data/data/com.koushikdutta.superuser/su"

//再写到/system/bin/su。

byte[] bytes = new byte[suStream.available()];

DataInputStream dis = new DataInputStream(suStream);

dis.readFully(bytes);

FileOutputStream suOutStream = new

FileOutputStream("/data/data/com.koushikdutta.superuser/su");

suOutStream.write(bytes);

suOutStream.close();

Process process = Runtime.getRuntime().exec("su");

DataOutputStream os = new

DataOutputStream(process.getOutputStream());

os.writeBytes("mount -oremount,rw /dev/block/mtdblock3    /system\n");

os.writeBytes("busybox cp /data/data/com.koushikdutta.superuser/su /system/bin/su\n");

os.writeBytes("busybox chown 0:0 /system/bin/su\n");

os.writeBytes("chmod 4755 /system/bin/su\n");

os.writeBytes("exit\n");

os.flush();

有进程使用root权限,superuser是怎么知道的呢,关键是句:

sprintf(sysCmd, "am start -a android.intent.action.MAIN -n         com.koushikdutta.superuser/com.koushikdutta.superuser.SuperuserRe questActivity --ei uid %d --ei pid %d > /dev/null", g_puid, ppid);

if (system(sysCmd))

return executionFailure("am.");

Superuser操作白名单代码:

static int checkWhitelist()

{

sqlite3 *db;

int rc = sqlite3_open_v2(DBPATH, &db, SQLITE_OPEN_READWRITE, NULL);

if (!rc)

{

char *errorMessage;

char query[1024];

sprintf(query, "select * from whitelist where _id=%d limit 1;",   g_puid);

struct whitelistCallInfo callInfo;

callInfo.count = 0;

callInfo.db = db;

rc = sqlite3_exec(db, query, whitelistCallback, &callInfo,     &errorMessage);

if (rc != SQLITE_OK)

{

sqlite3_close(db);

return 0;

}

sqlite3_close(db);

return callInfo.count;

}

sqlite3_close(db);

return 0;

}

5. 资源文件的获取

从上文的源码地址获取源代码,替换系统的system/extras/su/下面的su.c 和Android.mk文件,使用编译命令./mk td28 u adr system/extras/su/ 编译成功后会生成out/target/product/hsdroid/system/xbin/su 文件,而Superuser.apk就是普通的apk文件,都在源码地址里面可以下载,下载后倒入到eclipse即可直接运行。

Android Root原理的更多相关文章

  1. Android root 原理

    Android root 原理 0x00 关于root linux和类Unix系统的最初设计都是针对多用户的操作系统,对于用户权限的管理很非常严格的,而root用户(超级用户)就是整个系统的唯一管理员 ...

  2. [转] Android root 原理

    欢迎转载,转载请注明出处:http://www.cnblogs.com/lanrenxinxin/p/5572640.html 0x00 关于root linux和类Unix系统的最初设计都是针对多用 ...

  3. Android Root原理初探

    Root Linux:Root == Windows:Adminstrator Android是Linux系统吗? 操作系统 = 系统内核 + 文件系统 Linux发行版:Linux内核 + 文件系统 ...

  4. Android root检测方法小结

    转载目的,之前主要应用这里的原理解决了,手机被某个APP检测为root过的手机的问题,记录后续可能参考. 出于安全原因,我们的应用程序不建议在已经root的设备上运行,所以需要检测是否设备已经root ...

  5. [Android Pro] android root权限破解分析

    许 多机友新购来的Android机器没有破解过Root权限,无法使用一些需要高权限的软件,以及进行一些高权限的操作,其实破解手机Root权限是比较简 单及安全的,破解Root权限的原理就是在手机的/s ...

  6. Android ADB原理及常用命令

    Android调试桥(ADB, Android Debug Bridge)是一个Android命令行工具,包含在SDK 平台工具包中,adb可以用于连接Android设备,或者模拟器,实现对设备的控制 ...

  7. NFC(6)NFC编程的几个重要类,NFC硬件启动android应用原理

    用于NFC编程的几个重要类 Tag NFC 标签 NfcAdapter Nfc 的适配类 NdefMessage 描述NDEF格式的信息 NdefRecord 描述NDEF信息的一个信息段,类似tab ...

  8. android的原理,为什么不需要手动关闭程序

    转自android的原理,为什么不需要手动关闭程序 不用在意剩余内存的大小,其实很多人都是把使用其他系统的习惯带过来来了. Andoird大多应用没有退出的设计其实是有道理的,这和系统对进程的调度机制 ...

  9. 【转】Android Activity原理以及其子类描述,androidactivity

        Android Activity原理以及其子类描述,androidactivity 简介 Activity是Android应用程序组件,实现一个用户交互窗口,我们可以实现布局填充屏幕,也可以实 ...

随机推荐

  1. WPF 中,如何使用自定义的resources

    第一步,先自己自定义一个Resources 1.新建一个xaml文件,在其中自定义好自己的Resources 这个Resource 的根节点是 <ResourceDictionary xmlns ...

  2. android API文档查询---context、toast、SharedPreferences

    /*查阅api ---context1.abstract AssetManager     getAssets() Returns an AssetManager instance for the a ...

  3. 一种c#深拷贝方式完胜java深拷贝(实现上的对比)

    楼主是一名asp.net攻城狮,最近经常跑java组客串帮忙开发,所以最近对java的一些基础知识特别上心.却遇到需要将一个对象深拷贝出来做其他事情,而原对象保持原有状态的情况.(实在是不想自己new ...

  4. C语言中的%0nd,%nd,%-nd

    C语言中的%0nd printf --> formatted print/格式化输出 一.十进制 d -> decimal/十(shí)进制 int a=1; int b=1234; do ...

  5. 九度OJ 1386 旋转数组的最小数字 【算法】

    题目地址:http://ac.jobdu.com/problem.php?pid=1386 题目描述: 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转.输入一个递增排序的数组的一个旋 ...

  6. SVN查看提交日志的命令

    Windows下,使用svn客户端查看日志很方便,但是如果在linux下,常规查看日志的命令对于日志记录数比较多的时候,屏幕显示不了,就比较麻烦,后来发现了一个很有用的参数可以限制要查看的记录条数 查 ...

  7. <<深入Java虚拟机>>-第三章-垃圾收集器与内存分配策略-学习笔记

    垃圾收集 垃圾收集(Garbage Collection,GC),垃圾收集需要完成的三件事情. 哪些对象需要回收 什么时候回收 如何回收 如何确定对象已死(即不可能在被任何途径引用的对象) 引用计数算 ...

  8. [数据库连接字符串] Access 连接字符串

    [数据库连接字符串] Access 连接字符串 //ODBC 标准安全策略 Driver={Microsoft Access Driver (*.mdb)};Dbq=C:\mydatabase.mdb ...

  9. wpf 只在window是ShowDialog打开时才设置DialogResult

    //only set DialogResult when window is ShowDialog before if(System.Windows.Interop.ComponentDispatch ...

  10. STL的pair学习, map学习

    http://blog.csdn.net/calvin_zcx/article/details/6072286 http://www.linuxidc.com/Linux/2014-10/107621 ...