一、关于android的用户机制
首先,Android不同的应用拥有不同的进程,进程有独立的地址空间,进程与进程间默认是不能互相访问的,是一种很可靠的保护机制。
Android通过为每一个安装在设备上的包(apk)分配唯一的linux userID来实现,名称为"app_"加一个数字,比如app_43不同的UserID,运行在不同的进程,所以apk之间默认便不能相互访问。
一般的讲,如果你没有手动的设置uid,Android将为每一个APK独立的分配一个进程,一个UserId。所以不同的apk之间不能互相访问对方的私有数据。Android的系统程序也有它的UId,Android的系统程序的Uid是android.uid.system,所以,普通的apk用户是不能访问System的数据。
使用adb shell命令,进入android的shell,输入ls -l
可以看到输出详细的文件目录信息。例如
drwxrwxr-x root system 2013-10-08 17:25 mnt
最前面的第2~10个字符是用来表示权限。第一个字符一般用来区分文件和目录,第2~10个字符当中的每3个为一组,左边三个字符表示所有者权限,中间3个字符表示与所有者同一组的用户的权限,右边3个字符是其他用户的权限。这三个一组共9个字符,代表的意义如下:r(Read,读取):对文件而言,具有读取文件内容的权限;对目录来说,具有浏览目录的权限。
w(Write,写入):对文件而言,具有新增、修改文件内容的权限;对目录来说,具有删除、移动目录内文件的权限。
x(eXecute,执行):对文件而言,具有执行文件的权限;对目录了来说该用户具有进入目录的权限。
因为其他用户组拥有r-x的权限,所以,即便不是目录所有者或同组用户,也可以读取和执行/mnt的东西。
后边的两组表示所有者为root,用户组为system。
二、获取root,操作/data目录
进入整体,操作data目录.
之前ls -l 会发现/data目录的权限为
drwxrwx--x system system
由此得知,要想操作data目录
第一种,就是必须为system用户组或者有用户权限,因为系统应用可以访问这些目录的,其他用户只有执行权限。
第二种,就是把/data目录的权限更改为其他用户也可以访问
1、修改/data目录权限
修改/data权限,必须有root,这个简单。但是需要注意的是,只有执行su后的那一段流才能继续保持root权限,如果再次调用runtime.exe("xxx");这里将失去root权限。
至于为什么,我猜可能是每一次runtime.exe()都是打开一个终端,之后的输入输出流都是这个终端的输入输出,而再次执行,就相当于关闭了当前终端,你的root权限就么有了。以上这一段属猜想,欢迎拍砖。
还有就是,更改了权限,操作完后,就把权限再改回去。
添加权限的cmd= chmod 777 /data
改回去的cmd = chmod 771 /data
具体改权限这块不会的,百度下,就明白了。
如果操作过程中,遇到其他类似的问题,活学活用应该能解决。
以下为代码,如下。
<span style="font-size:14px;"> Runtime runtime = null;
Process process=null;
if (runtime==null) {
runtime=Runtime.getRuntime();
try {
process=runtime.exec("su");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
try {
InputStream inputStream=process.getInputStream();
OutputStream outputStream=process.getOutputStream();
cmd=cmd+"\n";
outputStream.write(cmd.getBytes());
outputStream.close();
System.out.println("Execute:"+cmd);
BufferedReader reader=new BufferedReader(new InputStreamReader(inputStream));
reader.close();
inputStream.close();
System.out.println("Execute End!");</span>
2、让你的APK成为系统应用
这个理论上是可以实现的,但是有很多限制。如上,所说,系统应用一般都是Uid="android.uid.system",但是仅有uid还是不能够成为系统级应用的,不然早被黑成灰了。
添加uid后,同时还需要在对应的Android.mk中添加LOCAL_CERTIFICATE := platform这一项。即用系统的签名,通过这种方式只能使apk的权限升级到system级别,系统中要求root权限才能访问的文件,apk还是不能访问。比如在android 的API中有提供 SystemClock.setCurrentTimeMillis()函数来修改系统时间,这个函数需要root权限或者运行与系统进程中才可以用。
第一个方法简单点,不过需要在Android系统源码的环境下用make来编译:
1. 在应用程序的AndroidManifest.xml中的manifest节点中加入android:sharedUserId="android.uid.system"这个属性。
2. 修改Android.mk文件,加入LOCAL_CERTIFICATE := platform这一行
3. 使用mm命令来编译,生成的apk就有修改系统时间的权限了。
第二个方法是直接把eclipse编出来的apk用系统的签名文件签名
1. 加入android:sharedUserId="android.uid.system"这个属性。
2. 使用eclipse编译出apk文件。
3. 使用目标系统的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",这样也是保护了系统的安全。
欢迎关注公众号: