Android客户端数据备份和恢复
1 问题点
最近一直在尝试在root情况下完成数据的备份和恢复,早期的时候rsync和cp -rp命令勉强够用。后来突然发现通过以上两条命令恢复数据无效。一度怀疑是APP做了限制,但是偶然间试用了一下钛备份,其备份和恢复功能正常,那么说明肯定是自己的备份和恢复手法出了问题,最终猜想可能是由于selinux引起的。
2 钛备份的数据备份和恢复方法
2.1 钛备份客户端
打开jeb,直接载入apk文件。在jeb中看一看到资源文件夹中包含了各个版本的busybox执行文件。
图1 加载文件
2.2 功能试用
在客户端中尝试进行数据备份。
图2 功能使用截图
每次使用备份功能备份抖音数据的时候大约会持续两分钟左右,期间通过ps获取进程好,可以从 /proc/pid/cmdline 中印证钛备份确实使用 busybox tar 来实现数据的备份和恢复的。 但是我直接通过tar -xvf命令直接使用钛备份之前生成的备份文件来恢复数据确失败了。
图3 进程截图
图4 进程启动参数
至于失败原因暂时无法追溯,可以肯定的是钛备份在使用tar命令备份和恢复之前肯定做了其他特殊操作。
3 获取所用的busybox执行命令
busybox命令集成了各种常见命令,并且以参数的方式传递。可以直接将钛备份中使用的busybox替换为我们的自定义文件,打印其中的参数,既可看到钛备份中所有的busybox命令操作。直接将 /data/data/com.keramidas.TitaniumBackup/files 下的busybox文件进行备份,并将busybox替换为如下内容。
echo $@ >> /sdcard/taibeifen.txt /data/data/com.keramidas.TitaniumBackup/files/busybox_bck $@
图5 修改busybox
busybox_bck为钛备份中的原始文件busybox,此处将其重命名为busybox_bck。
4 所有的备份和恢复命令
所有的busybox命令参数被我们重定向到 /sdcard/taibeifen.txt 中,可以直接观察到钛备份是使用了哪些命令来进行数据备份和恢复的。
4.1 数据备份
du -H -s /storage/emulated/0/Android/data/com.ss.android.ugc.aweme ln -s /storage/emulated/0/Android/data/com.ss.android.ugc.aweme /data/data/.external.com.ss.android.ugc.aweme tar -c /data/data/com.ss.android.ugc.aweme/. /data/data/.external.com.ss.android.ugc.aweme/. --exclude data/data/com.ss.android.ugc.aweme/./lib --exclude data/data/com.ss.android.ugc.aweme/./cache gzip rm /data/data/.external.com.ss.android.ugc.aweme ls --color=never -d /data/app/com.ss.android.ugc.aweme-1/base.apk chown media_rw:media_rw /data/media/0/TitaniumBackup/com.ss.android.ugc.aweme-20200210-074643.tar.gz
4.2 数据恢复
mv /data/data/com.ss.android.ugc.aweme /data/data/.com.ss.android.ugc.aweme
rm -R /storage/emulated/0/Android/data/com.ss.android.ugc.aweme
ln -s /storage/emulated/0/Android/data/com.ss.android.ugc.aweme /data/data/.external.com.ss.android.ugc.aweme
tar -C / -x --exclude data/data/com.ss.android.ugc.aweme/lib --exclude data/data/com.ss.android.ugc.aweme/./lib
cat /storage/emulated/0/TitaniumBackup/com.ss.android.ugc.aweme-20200210-060327.tar.gz
gunzip
rm /data/data/.external.com.ss.android.ugc.aweme
chown -R media_rw:media_rw /data/media/0/Android/data/com.ss.android.ugc.aweme
chown -hR 10124:10124 /data/data/com.ss.android.ugc.aweme
chmod -R u+rwx /data/data/com.ss.android.ugc.aweme
mv /data/data/.com.ss.android.ugc.aweme/lib /data/data/com.ss.android.ugc.aweme
rm -R /data/data/.com.ss.android.ugc.aweme
通过以上分析,大致逻辑已经清晰,但是通过ps的结果看,明显是使用了管道。所以还是需要完整命令。
5 利用xposed获取完整命令
5.1 定位代码
在jeb中搜索 tar -c 可以定位到命令生成出,最终通过 en类的构造函数的第二个参数进行传递 ,那么我们可以通过 hook en类的构造函数 ,然后打印参数即可。
图6 命令构造
5.2 插件开发
单独开发一个xposed插件,用来hook en的构造函数,然后直接把String参数打印出来即可,如果xposed开发不熟悉的话可以参考我之前的文章Xposed学习-插件开发(一)。
if ("com.keramidas.TitaniumBackup".equals(lpparam.packageName)) { XposedBridge.log("ready to hook method."); Class clazz = XposedHelpers.findClass("o.es.if", lpparam.classLoader); XposedHelpers.findAndHookConstructor("o.en", lpparam.classLoader, clazz, String.class, new XC_MethodHook() { @Override protected void beforeHookedMethod( MethodHookParam param) throws Throwable { if (param.args.length >= 2) { XposedBridge.log( "command is " + param.args[1]); } else { XposedBridge.log( "command is " + param.args[0]); } } }); }
02-10 18:51:03.211 25912 25912 I Xposed : command is /system/bin/am force-stop com.ss.android.ugc.aweme 02-10 18:51:04.357 25912 27420 I Xposed : command is /data/user/0/com.keramidas.TitaniumBackup/files/busybox du -H -s "/storage/emulated/0/Android/data/com.ss.android.ugc.aweme" 02-10 18:51:04.407 25912 27420 I Xposed : command is /data/user/0/com.keramidas.TitaniumBackup/files/busybox ln -s "/storage/emulated/0/Android/data/com.ss.android.ugc.aweme" "/data/data/.external.com.ss.android.ugc.aweme" 02-10 18:51:04.480 25912 27420 I Xposed : command is /data/user/0/com.keramidas.TitaniumBackup/files/busybox tar -c "/data/data/com.ss.android.ugc.aweme/." "/data/data/.external.com.ss.android.ugc.aweme/." --exclude "data/data/com.ss.android.ugc.aweme/./lib" --exclude "data/data/com.ss.android.ugc.aweme/./cache" | /data/user/0/com.keramidas.TitaniumBackup/files/busybox gzip > "/storage/emulated/0/TitaniumBackup/com.ss.android.ugc.aweme-20200210-105104.tar.gz" 02-10 18:55:21.044 25912 27420 I Xposed : command is /data/user/0/com.keramidas.TitaniumBackup/files/busybox rm "/data/data/.external.com.ss.android.ugc.aweme" 02-10 18:55:21.081 25912 27420 I Xposed : command is /data/user/0/com.keramidas.TitaniumBackup/files/busybox ls --color=never -d "/data/app/com.ss.android.ugc.aweme-1/base.apk" 02-10 18:55:21.102 25912 27420 I Xposed : command is /data/user/0/com.keramidas.TitaniumBackup/files/busybox ls --color=never "/data/data/com.android.vending/databases/" 02-10 18:55:21.134 25912 27420 I Xposed : command is /data/user/0/com.keramidas.TitaniumBackup/files/sqlite3 "/data/data/com.android.vending/databases/localappstate.db" 'pragma table_info ( appstate );' 02-10 18:55:21.174 25912 27420 I Xposed : command is /data/user/0/com.keramidas.TitaniumBackup/files/sqlite3 "/data/data/com.android.vending/databases/localappstate.db" 'SELECT appstate.package_name,auto_update,desired_version,download_uri,delivery_data_timestamp_ms,installer_state,first_download_ms,referrer,account,title,flags,continue_url,last_notified_version,last_update_timestamp_ms,account_for_update,auto_acquire_tags,external_referrer_timestamp_ms,persistent_flags,permissions_version,delivery_token,completed_split_ids,active_split_id,request_id FROM appstate WHERE installer_state = "0" AND appstate.package_name = "com.ss.android.ugc.aweme" LIMIT 1;' 02-10 18:55:21.194 25912 27420 I Xposed : command is /data/user/0/com.keramidas.TitaniumBackup/files/sqlite3 "/data/data/com.android.vending/databases/library.db" 'SELECT doc_id,doc_type,offer_type,app_certificate_hash,document_hash,library_id FROM ownership WHERE doc_id = "com.ss.android.ugc.aweme";' 02-10 18:55:21.262 25912 27420 I Xposed : command is /data/user/0/com.keramidas.TitaniumBackup/files/busybox chown media_rw:media_rw "/data/media/0/TitaniumBackup/com.ss.android.ugc.aweme-20200210-105104.tar.gz" 02-10 18:56:02.434 25912 25912 I Xposed : command is /data/user/0/com.keramidas.TitaniumBackup/files/busybox ps -w 02-10 18:56:03.396 25912 25912 I Xposed : command is /system/bin/am force-stop com.ss.android.ugc.aweme 02-10 18:56:04.600 25912 28476 I Xposed : command is /data/user/0/com.keramidas.TitaniumBackup/files/busybox mv "/data/data/com.ss.android.ugc.aweme" "/data/data/.com.ss.android.ugc.aweme" 02-10 18:56:04.632 25912 28476 I Xposed : command is /data/user/0/com.keramidas.TitaniumBackup/files/busybox rm -R "/storage/emulated/0/Android/data/com.ss.android.ugc.aweme" 02-10 18:56:04.734 25912 28476 I Xposed : command is /data/user/0/com.keramidas.TitaniumBackup/files/busybox ln -s "/storage/emulated/0/Android/data/com.ss.android.ugc.aweme" "/data/data/.external.com.ss.android.ugc.aweme" 02-10 18:56:04.746 25912 28476 I Xposed : command is /data/user/0/com.keramidas.TitaniumBackup/files/busybox cat "/storage/emulated/0/TitaniumBackup/com.ss.android.ugc.aweme-20200210-105104.tar.gz" | /data/user/0/com.keramidas.TitaniumBackup/files/busybox gunzip | /data/user/0/com.keramidas.TitaniumBackup/files/busybox tar -C "/" -x --exclude data/data/com.ss.android.ugc.aweme/lib --exclude data/data/com.ss.android.ugc.aweme/./lib 02-10 18:56:30.727 25912 28476 I Xposed : command is /data/user/0/com.keramidas.TitaniumBackup/files/busybox rm "/data/data/.external.com.ss.android.ugc.aweme" 02-10 18:56:30.748 25912 28476 I Xposed : command is /data/user/0/com.keramidas.TitaniumBackup/files/busybox chown -R media_rw:media_rw "/data/media/0/Android/data/com.ss.android.ugc.aweme" 02-10 18:56:30.769 25912 28476 I Xposed : command is /data/user/0/com.keramidas.TitaniumBackup/files/busybox chown -hR 10124:10124 "/data/data/com.ss.android.ugc.aweme" 02-10 18:56:30.960 25912 28476 I Xposed : command is /data/user/0/com.keramidas.TitaniumBackup/files/busybox chmod -R u+rwx "/data/data/com.ss.android.ugc.aweme" 02-10 18:56:31.117 25912 28476 I Xposed : command is /system/bin/restorecon -R "/data/data/com.ss.android.ugc.aweme" 02-10 18:56:31.771 25912 28476 I Xposed : command is /data/user/0/com.keramidas.TitaniumBackup/files/busybox mv "/data/data/.com.ss.android.ugc.aweme/lib" "/data/data/com.ss.android.ugc.aweme" 02-10 18:56:31.789 25912 28476 I Xposed : command is /data/user/0/com.keramidas.TitaniumBackup/files/busybox rm -R "/data/data/.com.ss.android.ugc.aweme"