版权声明:本文为博主原创文章,未经博主允许不得转载。 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++;