一、关于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",这样也是保护了系统的安全。