admin管理员组文章数量:1564684
申明:本文部分内容为网络相关资料整理,并结合本人实际工作总结而成。请引用或者转载注明出处,对于文章内容有疑问请留言。
一、Android ROOT
1.ROOT原理
ROOT也叫系统管理员用户,该账户拥有整个系统的最高权限,他可以访问和修改手机几乎所有的文件。只有ROOT才能具备最该级别的管理员权限,我们ROOT手机就是获取手机最高权限的过程。同时为了防止不良软件也取得ROOT用户的权限,当我们在ROOT手机的过程中会给系统安装一个叫做Superuser.apk的APP。当某些程序执行su指令时想去的系统最高权限时,Superuser就会自动启动,拦截该动作并作出询问,当用户认为该程序可以安全使用时,那就选择允许,程序就可以获取到ROOT权限。否则,可以禁止该程序继续取得最高权限。Root的过程其实就是把su文件放到/system/bin/ Superuser.apk 放到system/app下面,还需要设置/system/bin/su可以让任意用户可运行,有set uid和set gid的权限。即要在android机器上运行命令:adb shell chmod 4755 /system/bin/su。而通常,厂商是不会允许我们随便这么去做的,我们就需要利用操作系统的各种漏洞,来完成这个过程。2.对于ROOT的思考(转自:http://www.zhihu/question/21074979)
你想在Linux下获取root权限的时候就是执行sudo或者su,接下来系统会提示你输入root用户的密码,密码正确就获得root权限了。Android本身就不想让你获得Root权限,大部分手机出厂的时候根本就没有su这个程序。所以你想获得Android的root权限,第一步就是要把编译好的su文件拷贝到Android手机的/system/bin或者/system/xbin/目录下。我们先假设你可以把su放在xbin下,接下来你可以在Android手机的adb shell或者串口下输入su了。Linux下su以后输入密码就可以root了,但Android里的su和Linux里的su是不一样的,Android里的su不是靠验证密码的,而是看你原来的权限是什么。意思就是如果你是root,那你可以通过su切换到别的用户,比如说shell,wifi,audio什么的。但如果你是root之外的其他用户,就不能切换回root了,会提示你permission denied。也就说用root运行su才有用,但我这个时候还没有root怎么办呢?这就涉及到另外个问题。
一般我们在Linux的console下输入 ls -l 会列出所有文件的权限。比如:-rwxr-xr-x,用过Linux的人都知道r代表该文件可读,w代表可写,x代表可执行,- 就代表没有该权限。第一个rwx代表文件所有者的权限,第二个rwx代表和所有者同组人的权限,第三个rwx代表其他用户对该文件的权限。但下面这个文件就比较特殊。
rws,它的执行权限标志位是一个s,s代表当任何一个用户执行该文件的时候都拥有文件所有者的权限,这文件的所有者是root,简单点说就是不管谁执行这个文件,他执行的时候都是以root身份执行的。也就说即使我不是root也有可能以root身份来执行程序,那么我就把一个所有者是root的su程序权限标志位置成-rwsr-xr-x,那么不管谁执行它,都是root身份执行,su就可以顺利执行成功了,执行成功之后我就是root身份了。
问题都清楚了,就是你需要把一个所有者是root的su拷贝到Android手机上,并且把su的权限标志位置成-rwsr-xr-x。能把这个事情搞定你就成功root了一个手机。
大概意思就是两行代码
cp /data/tmp/su /system/bin/ #copy su 到/system/分区
chown root:root su #su的所有者置成root
chmod 4775 /system/bin/su #把su置成-rwsr-xr-x
熟悉Android的同学都知道,执行上面的每一行代码都需要root权限才能成功。意思就是说,你只有有root权限的情况下才能执行上面两行代码,而这两行代码就是为了让你获得root权限的,这是一个逻辑闭环,那么如何打破这个逻辑闭环呢?一个办法就是找一个本身已经有root权限的进程来启动我上面的两行代码,那我这两行代码一启动就是root权限,就可以顺利执行了。但是已经有root权限的进程都是出厂时候就装到手机上的,代码写死了,你没法控制它执行你自己的代码啊。这个时候就需要你找漏洞了,比如用来破解Android2.3 root权限的zergRush漏洞就是利用一个拥有root权限的进程栈溢出漏洞。
为什么su一定要放到/system/bin/或者/system/xbin/ ?su不能放在data分区原因是因为data分区在mount时就指定了不能给可执行程序加s位。你在adb shell里执行mount就可以看到,或者看下面的截图。
下面有下划线的部分是原作者的解释:
/*
* 首先,你当然可以把su这个程序copy到/data/分区,但你adb push进去的时候,su有这个程序的所
* 有者肯定不是root,一般是shell什么的(记不清了,应该是和adbd这个进程的所有者一样),这个时
* 候即使你把它权限置为-rwsr-xr-x,哪你运行它的时候也是shell身份运行的,su会提示你输入密码
* 的。
* 第二我们root手机的目的是为了运行需要root权限的APP,比如goagent或者什么的。这些APP里代
* 码需要获得root的时候是这么写的:
* Process p = Runtime.getRuntime().exec("su");
* 也就是它们在代码里调用了一下su这个程序,哪可以写成下面这个样子吗?
* Process p = Runtime.getRuntime().exec("./data/tmp/su");
* 我没写过APP,不太清楚,估计是不行的。换句话说你必须把su放到环境变量PATH所有的目录
* 里,APP才能调用到它。如果你不想放到bin或者xbin下,你就必须给PATH增加一个目录。PATH是
* root权限才能修改的,你如果能修改PATH,说明你已经有root权限了,修改PATH就没必要了,还
* 不如直接放到bin下面。
*/
3.APP获取ROOT权限(转自:http://blog.csdn/jingwen3699/article/details/8175937)
A.要让Android应用获取ROOT权限,首先Android设备需要具有ROOT权限。下面代码为判断设备是否具有ROOT权限<span style="font-size:18px;"> public static boolean runRootCommand(String command) {
Process process = null;
DataOutputStream os = null;
try {
process = Runtime.getRuntime().exec("su");
os = new DataOutputStream(process.getOutputStream());
os.writeBytes(command+"\n");\\os.writeBytes("echo \"Do I have root?\" >/system/sd/temporary.txt\n");
os.writeBytes("exit\n");
os.flush();
process.waitFor();
} catch (Exception e) {
Log.d(TAG, "the device is not rooted, error message: " + e.getMessage());
return false;
} finally {
try {
if (os != null) {
os.close();
}
if(process != null) {
process.destroy();
}
} catch (Exception e) {
e.printStackTrace();
}
}
return true;
}</span><pre name="code" class="java"><span style="font-size:18px;">
</span>
<span style="font-size:18px;">或者:
/**
* 判断当前手机是否有ROOT权限
* @return
*/
public boolean isRoot(){
boolean bool = false;
try{
if ((!new File("/system/bin/su").exists()) && (!new File("/system/xbin/su").exists())){
bool = false;
} else {
bool = true;
}
Log.d(TAG, "bool = " + bool);
} catch (Exception e) {
}
return bool;
}</span>
B.在设备具有ROOT权限的前提下,执行su命令,这时会提示用户进行授权。
<span style="font-size:18px;">import java.io.DataOutputStream;
import android.app.Activity;
import android.util.Log;
/**
* 应用程序运行命令获取 Root权限,设备必须已破解(获得ROOT权限)
* @param command 命令:String apkRoot="chmod 777 "+getPackageCodePath(); RootCommand(apkRoot);
* @return 应用程序是/否获取Root权限
*/
public boolean RootCommand(String command)
{
Process process = null;
DataOutputStream os = null;
try
{
process = Runtime.getRuntime().exec("su");
os = new DataOutputStream(process.getOutputStream());
os.writeBytes(command + "\n");
os.writeBytes("exit\n");
os.flush();
process.waitFor();
} catch (Exception e)
{
Log.d("*** DEBUG ***", "ROOT REE" + e.getMessage());
return false;
} finally
{
try
{
if (os != null)
{
os.close();
}
process.destroy();
} catch (Exception e)
{
}
}
Log.d("*** DEBUG ***", "Root SUC ");
return true;
}
}</span>
C.对上述代码进行调用
<span style="font-size:18px;">public class MainActivity extends Activity
{
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
String apkRoot="chmod 777 "+getPackageCodePath();</span>
<pre name="code" class="cpp"><span style="font-size:18px;"> //读、写、运行三项权限可以用数字表示,就是r=4,w=2,x=1。所以,上面的例子中的rw-r--r--用数字表示成644。
//反过来说777就是rwxrwxrwx,意思是该登录用户(可以用命令id查看)、他所在的组和其他人都有最高权限。
//getPackageCodePath():获取自身APK路径
SystemManager.RootCommand(apkRoot);</span><pre name="code" class="java"><span style="font-size:18px;">}</span>
二、System权限
1.System权限介绍(目前没有深入研究,待以后补充)
在linux系统中是只有ROOT权限和普通权限的,Android包装了一套自己的权限体系,有platform、media、shared等的权限。ROOT权限是超级权限,如果得到ROOT权限则可以对系统进行任意操作。Android系统肯定不会让APK获得这种权限,但是提供了访问system目录的权限,即system权限,对应Android的权限体系为platform。 一般情况下system用户可以在系统中创建和删除文件,访问设备等等。但是有些情况下system权限还是不够的。比如:设置网卡IP地址,ifconfig命令是需要ROOT权限的。安卓系统并不像windows,system权限(uid1000)并不是最高权限,仅仅比普通用户拥有少量的特殊权限,比如安装软件无需弹窗。而系统中最高权限是root权限(uid0)。所以综上:ROOT权限高于System权限。2.如何获取System权限(下述方法未亲自验证)
A.一般权限的添加一般情况下,设定apk的权限,可在AndroidManifest.xml中添加android:sharedUserId="android.uid.xxx>
例如: 给apk添加system权限
<manifest xmlns:android="http://schemas.android/apk/res/android"
... ...
android:sharedUserId="android.uid.system">
同时还需要在对应的Android.mk中添加LOCAL_CERTIFICATE := platform这一项。即用系统的签名,通过这种方式只能使apk的权限升级到system级别,系统中要求权限才能访问的文件,apk还是不能访问。比如在android 的API中有提供 SystemClock.setCurrentTimeMillis()函数来修改系统时间,这个函数需要root权限或者运行与系统进程中才可以用。第一个方法简单点,不过需要在Android系统源码的环境下用make来编译,综上:
a. 在应用程序的AndroidManifest.xml中的manifest节点中加入android:sharedUserId="android.uid.system"这个属性。
b. 修改Android.mk文件,加入LOCAL_CERTIFICATE := platform这一行 c. 使用mm命令来编译,生成的apk就有修改系统时间的权限了。
B.修改密钥
a.在代码中,AndroidManifest.xml文件的manifest项中,添加android:sharedUserId="android.uid.system"
b.编译程序,得到APK文件,如src.apk
c.将APK文件用压缩软件打开,删除META-INF目录里面的CERT.SF和CERT.RSA两个文件
d.给*.apk文件签名
这步需要在android源码中进行
cd build/tools/signapk
javac signapk.java(这里产生*.class) mkdir test/com/android/signapk cp *.class test/com/android/signapk jar cvfm signapk.jar SignApk.mf -C test/ .(这里产生signapk.jar)e.运行命令(其中signapk.jar platform.x509.pem platform.pk8这3个文件在源码的build目录下可以找到)
mkdir SignApk 步骤4中产生的signapk.jar拷贝到SignApk文件夹中 cp build/target/product/security/{platform.x509.pem,platform.pk8} SignApkjava -jar signapk.jar platform.x509.pem platform.pk8 src.apk dst.apk
f.dst.apk安装后就有system权限,就可以访问设备
C.直接把eclipse编出来的apk用系统的签名文件签名
a. 加入android:sharedUserId="android.uid.system"这个属性。
b. 使用eclipse编译出apk文件。
c. 使用目标系统的platform密钥来重新给apk文件签名。首先找到密钥文件,在我ndroid源码目录中的位置是"build/target/product/security",下面的platform.pk8和platform.x509.pem两个文件。然后用Android提供的Signapk工具来签名,signapk的源代码是在"build/tools/signapk"下,编译后在out/host/linux-x86/framework下,用法为java -jar signapk.jar platform.x509.pem platform.pk8 input.apk output.apk"。加入android:sharedUserId="android.uid.system"这个属性。通过Shared User id,拥有同一个User id的多个APK可以配置成运行在同一个进程中。那么把程序的UID配成android.uid.system,也就是要让程序运行在系统进程中,这样就有权限来修改系统时间了。只是加入UID还不够,如果这时候安装APK的话发现无法安装,提示签名不符,原因是程序想要运行在系统进程中还要有目标系统的platform key,就是上面第二个方法提到的platform.pk8和platform.x509.pem两个文件。用这两个key签名后apk才真正可以放入系统进程中。第一个方法中加入LOCAL_CERTIFICATE := platform其实就是用这两个key来签名。
这也有一个问题,就是这样生成的程序只有在原始的Android系统或者是自己编译的系统中才可以用,因为这样的系统才可以拿到platform.pk8和platform.x509.pem两个文件。要是别家公司做的Android上连安装都安装不了。试试原始的Android中的key来签名,程序在模拟器上运行OK,不过放到G3上安装直接提示"Package ... has no signatures that match those in shared user android.uid.system",这样也是保护了系统的安全。
注:将APP安装到system/app目录下可以用于防卸载,以后会出一个Android防卸载专题。
三、设备管理器
1.关于设备管理器
Android2.2后提供了设备管理器,通过API可以对Android设备进行更多权限的管理和操作,如清除所有数据、更改屏幕解锁密码及规则、锁定屏幕、设置存储设备加密、停用相机、锁屏时禁用某些功能等等,而且相同功能的程序之间的权限互不冲突。2.代码示例(转自:http://blog.csdn/etzmico/article/details/6848061)
第一步,注册一个广播类,用于监听权限的变化:
[java] view plain copy- <receiver android:name=".deviceAdminReceiver" android:label="@string/app_name"
- android:description="@string/description" android:permission="android.permission.BIND_DEVICE_ADMIN">
- <meta-data android:name="android.app.device_admin"
- android:resource="@xml/device_admin" />
- <intent-filter>
- <action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
- </intent-filter>
- </receiver>
android:permission 表示此功能需要的权限。
android:name="android.app.action.DEVICE_ADMIN_ENABLED"表示此动作的跳转界面。
<meta-data android:name="android.app.device_admin"android:resource="@xml/device_admin" />表示这个应用可以管理的权限清单。
XML清单:
[java] view plain copy- <span style="color:#000000;"><?xml version="1.0" encoding="utf-8"?>
- <device-admin xmlns:android="<a href="http://schemas.android/apk/res/android">http://schemas.android/apk/res/android</a>">
- <uses-policies>
- <limit-password />
- <watch-login />
- <reset-password />
- <force-lock />
- <wipe-data />
- </uses-policies>
- </device-admin></span>
第二步,广播服务类的JAVA代码,重写一些必要的实现函数:
广播类deviceAdminReceiver 继承DeviceAdminReceiver
[java] view plain copy- package cn.etzmico;
- import android.app.admin.DeviceAdminReceiver;
- import android.content.Context;
- import android.content.Intent;
- import android.content.SharedPreferences;
- import android.widget.Toast;
- public class deviceAdminReceiver extends DeviceAdminReceiver {
- /**
- * 获取设备存储的数值
- *
- * @param context
- * @return
- */
- public static SharedPreferences getDevicePreference(Context context) {
- return context.getSharedPreferences(
- DeviceAdminReceiver.class.getName(), 0);
- }
- // 密码的特点
- public static String PREF_PASSWORD_QUALITY = "password_quality";
- // 密码的长度
- public static String PREF_PASSWORD_LENGTH = "password_length";
- public static String PREF_MAX_FAILED_PW = "max_failed_pw";
- void showToast(Context context, CharSequence text) {
- Toast.makeText(context, text, Toast.LENGTH_SHORT).show();
- }
- @Override
- public void onEnabled(Context context, Intent intent) {
- // TODO Auto-generated method stub
- showToast(context, "设备管理:可用");
- }
- @Override
- public void onDisabled(Context context, Intent intent) {
- // TODO Auto-generated method stub
- showToast(context, "设备管理:不可用");
- }
- @Override
- public CharSequence onDisableRequested(Context context, Intent intent) {
- // TODO Auto-generated method stub
- return "这是一个可选的消息,警告有关禁止用户的请求";
- }
- @Override
- public void onPasswordChanged(Context context, Intent intent) {
- // TODO Auto-generated method stub
- showToast(context, "设备管理:密码己经改变");
- }
- @Override
- public void onPasswordFailed(Context context, Intent intent) {
- // TODO Auto-generated method stub
- showToast(context, "设备管理:改变密码失败");
- }
- @Override
- public void onPasswordSucceeded(Context context, Intent intent) {
- // TODO Auto-generated method stub
- showToast(context, "设备管理:改变密码成功");
- }
- }
第三步,也就是最关键的操作代码了
激活相关
[java] view plain copy- Intent intent = new Intent(
- DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN);
- intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN,
- mDeviceComponentName);
- intent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION,
- "(自定义区域2)");
- startActivityForResult(intent, RESULT_ENABLE);
代码中的自定义区域2是可以输入一些自己想说的话,和广播类中的android:description="@string/description"一样。
这个是系统提供的两个自定义区域。
[java] view plain copy- <string name="description">(可自定义区域1)</string>
锁屏相关
[java] view plain copy- // ""中为设置的PIN密码,默认为123456
- <span style="white-space:pre"> </span>mDPM.resetPassword("123456",
- <span style="white-space:pre"> </span>DevicePolicyManager.RESET_PASSWORD_REQUIRE_ENTRY);
- <span style="white-space:pre"> </span>mDPM.lockNow();
锁屏操作,由于是模拟器不能做到真正错屏,只能停到初始模拟器进来需要解锁的状态,屏幕不会变暗。
设置屏幕灯光变暗时间相关
[java] view plain copy- long timeout = 1000L * Long.parseLong(et.getText().toString());
- mDPM.setMaximumTimeToLock(mDeviceComponentName, timeout);
et是定义的一个EditText,用于进行时间的输入
屏幕变暗最小时间为5秒
恢复出厂设置相关
[java] view plain copy- mDPM.wipeData(0);
恢复出厂设置只能通过真机去操作,模拟器操作后会停留在正在关机的dialog画面
恢复后数据会被清空,因此要做好备份操作。
注:激活设备管理器也可以用于防卸载,只是到Android5.0以上版本,可能会失灵。
本文标签: 设备管理器权限androidrootSystem
版权声明:本文标题:Android ROOT System权限 设备管理器 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://www.elefans.com/dongtai/1727083602a1097136.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论