Android5.1.1实现备份应用数据功能

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/LEAD_SOLO/article/details/53522551

Android5.1.1实现备份应用数据功能

20170418更正,方法三无法实现备份,仍需要有root权限才行。

    首先先来几个知识点,Android各个应用数据的隔离实际上是通过不同的UID来区别的。UID分配过程不在本文详解。应用安装时会在/data/data/目录下以包名为目录名,创建一个目录,并且分配权限为751,并分配对应的用户与用户组,这就导致了,要想读取某个应用的应用数据,就应该需要这个应用的uid或者gid,如果要对这个目录进行写的话,则需要uid一致才能进行写。大致实现方法有以下三种
    1、留下一个su的暗门,在需要进行备份数据的时候,备份应用对对应的应用包名目录进行chmod 777的修改。
    2、破坏沙箱机制,在uid分配过程中,强制统一赋值为统一个值,这样应用的uid都相同,也就都拥有uid权限。
    3、破坏沙箱机制,在对应应用的包名目录创建时,创建的权限修改为777的创建,这样就可以保证不在用户与用户组的apk能够进行对该目录的读写。本文以第三种方法进行代码修改。
frameworks/native/cmds/installd/commands.c
@@ -58,15 +58,28 @@ int install(const char *pkgname, uid_t uid, gid_t gid, const char *sein
         return -1;
     }

-    if (mkdir(pkgdir, 0751) < 0) {//原生沙箱隔离机制
-        ALOGE("cannot create dir '%s': %s\n", pkgdir, strerror(errno));
-        return -1;
-    }
-    if (chmod(pkgdir, 0751) < 0) {
-        ALOGE("cannot chmod dir '%s': %s\n", pkgdir, strerror(errno));
-        unlink(pkgdir);
-        return -1;
-    }
+   //破坏隔离机制,大于system的uid应用创建目录时全以777位权限。
+    if ((uid > AID_SYSTEM) || (gid > AID_SYSTEM)) {
+               if (mkdir(pkgdir, 0777) < 0) {
+                       ALOGE("cannot create dir '%s': %s\n", pkgdir, strerror(errno));
+                       return -1;
+               }
+               if (chmod(pkgdir, 0777) < 0) {
+                       ALOGE("cannot chmod dir '%s': %s\n", pkgdir, strerror(errno));
+                       unlink(pkgdir);
+                       return -1;
+               }
+       }else {
+               if (mkdir(pkgdir, 0751) < 0) {
+                        ALOGE("cannot create dir '%s': %s\n", pkgdir, strerror(errno));
+                       return -1;
+               }
+               if (chmod(pkgdir, 0751) < 0) {
+                       ALOGE("cannot chmod dir '%s': %s\n", pkgdir, strerror(errno));
+                       unlink(pkgdir);
+                       return -1;
+               }
+
+       }

     if (lstat(libsymlink, &libStat) < 0) {
         if (errno != ENOENT) {
@@ -208,15 +221,27 @@ int make_user_data(const char *pkgname, uid_t uid, userid_t userid, c
         return -1;
     }

-    if (mkdir(pkgdir, 0751) < 0) {
-        ALOGE("cannot create dir '%s': %s\n", pkgdir, strerror(errno));
-        return -errno;
-    }
-    if (chmod(pkgdir, 0751) < 0) {
-        ALOGE("cannot chmod dir '%s': %s\n", pkgdir, strerror(errno));
-        unlink(pkgdir);
-        return -errno;
-    }
+    if ((uid > AID_SYSTEM)) {  
+               if (mkdir(pkgdir, 0777) < 0) {
+                       ALOGE("cannot create dir '%s': %s\n", pkgdir, strerror(errno));
+ +                       return -errno;
+               }
+               if (chmod(pkgdir, 0777) < 0) {
+                       ALOGE("cannot chmod dir '%s': %s\n", pkgdir, strerror(errno));
+                       unlink(pkgdir);
+                       return -errno;
+               }
+       }else {         
+               if (mkdir(pkgdir, 0751) < 0) {
+                       ALOGE("cannot create dir '%s': %s\n", pkgdir, strerror(errno));
+                       return -errno;
+               }
+               if (chmod(pkgdir, 0751) < 0) {
+                       ALOGE("cannot chmod dir '%s': %s\n", pkgdir, strerror(errno));
+                       unlink(pkgdir);
+                       return -errno;
+               }
+       }

     if (lstat(libsymlink, &libStat) < 0) {
         if (errno != ENOENT) {
@@ -1116,11 +1141,19 @@ void mkinnerdirs(char* path, int basepos, mode_t mode, int uid, int
             path[basepos] = 0;
             if (lstat(path, statbuf) < 0) {
                 ALOGV("Making directory: %s\n", path);
-                if (mkdir(path, mode) == 0) {
-                    chown(path, uid, gid);
-                } else {
-                    ALOGW("Unable to make directory %s: %s\n", path, strerror(errno));
- -                }
+                               if ((uid > AID_SYSTEM) || (gid > AID_SYSTEM)) {
+                                       if (mkdir(path, mode) == 0) {
+                                               chown(path, uid, gid);
+                                       } else {
+                                               ALOGW("Unable to make directory %s: %s\n", 
+                                       }
+                               }else {
+                                       if (mkdir(path, mode) == 0) {
+                                               chown(path, uid, gid);
+                                       } else {
+                                               ALOGW("Unable to make directory %s: %s\n", 
+                                       }
+                               }
             }
             path[basepos] = '/';
             basepos++;

猜你喜欢

转载自blog.csdn.net/LEAD_SOLO/article/details/53522551