Project

General

Profile

RestoreApplicationInternalData » History » Version 10

Denis 'GNUtoo' Carikli, 10/29/2020 12:31 AM
add more context on silence

1 1 Denis 'GNUtoo' Carikli
h1. RestoreApplicationInternalData
2
3
{{toc}}
4
5
h2. /!\ Warning: Draft
6
7
This article is in draft form and is being written:
8
* Everybody is welcome to contribute
9
* Some things might not be accurate yet, so beware before using the information contained in it.
10 2 Denis 'GNUtoo' Carikli
11
h2. Introduction
12
13
In some case, it is useful to be able to restore internal applications data:
14 9 Denis 'GNUtoo' Carikli
15
For instance you might need to move the data of an application from a device to another if you want to switch device.
16
17
Another use case is if /data/system/packages.xml or /data/system/appops.xml get corrupted, applications can loose access to their data. This can make the launcher and other applications crash. 
18
19
So while it is possible to recover from that by wiping the data partition in the recovery, sometimes it's very impractical to do that because you might have important data like silence encryption keys and established sessions that you don't want to loose.
20 3 Denis 'GNUtoo' Carikli
21
h2. Howto
22
23 10 Denis 'GNUtoo' Carikli
This howto will explain how to move silence data from a device to another. 
24
25
Silence has been chosen as an example for this tutorial because:
26
* It's an application commonly used
27
* Loosing its data (key, sessions) can be painful
28
29
Silence stores its data in the internal application storage. As far as I know it's not supposed to store any data on the microSD or user storage beside potential backups.
30 5 Denis 'GNUtoo' Carikli
31 3 Denis 'GNUtoo' Carikli
TODO:
32 5 Denis 'GNUtoo' Carikli
* Explain that we assume that the data partition isn't encrypted
33
* Explain why we need the uid/gid
34
* Explain why the ls -ld gives the application uid/gid
35
* Point to how to get root
36
* Explain how to handle a corrupted /data/system/packages.xml and /data/system/appops.xml
37 3 Denis 'GNUtoo' Carikli
* Explain how to mount a full backup, and why not to restore full backup completely
38
* Explain how and why create a tarball of the application data
39
40 5 Denis 'GNUtoo' Carikli
Once we have a tarball backup of the application data we need to reboot in the recovery to avoid any writes to the data filesystem.
41
42
Once this is done you need to mount the data partition. 
43
44
For the Galaxy SIII (GT-I9300), this can be done from your computer with this command:
45 3 Denis 'GNUtoo' Carikli
<pre>
46
$ adb shell "mount /dev/block/platform/dw_mmc/by-name/USERDATA /data"
47
</pre>
48
49 5 Denis 'GNUtoo' Carikli
Then we need to get a root shell inside the recovery. This can be done with the @adb shell@ command:
50 3 Denis 'GNUtoo' Carikli
<pre>
51
$ adb shell
52
</pre>
53
54 5 Denis 'GNUtoo' Carikli
Then we assume that you are in /data/data to simplify this tutorial.
55
You will need to remember adjust all other commands if you are not in this directory.
56
To go in /data/data, you can use the following command:
57 3 Denis 'GNUtoo' Carikli
<pre>
58
root@m0:/ # cd /data/data/                                                     
59
root@m0:/data/data # 
60
</pre>
61
62 5 Denis 'GNUtoo' Carikli
As applications are sandboxed, and that as part of that sandboxing, they have their own usersname, we need to retrieve this username.
63
To do that we can just use @ls -ld@ on the directory holding the application internal data.
64
65
The directory has the internal name of the application.
66
67
Here are some well known name correspondances:
68
69 7 Denis 'GNUtoo' Carikli
| Internal name           | Application                                 |
70
| org.smssecure.smssecure | Silence                                     |
71
| com.android.dialer      | Dialer (Android's stock dialer application) |
72 8 Denis 'GNUtoo' Carikli
| fil.libre.repwifiapp    | RepWiFi                                     |
73 5 Denis 'GNUtoo' Carikli
74
For pakcages comming from f-droid, the f-droid website can find the correspondance.
75
76
For instance the "Silence page":https://f-droid.org/en/packages/org.smssecure.smssecure/ has @org.smssecure.smssecure@ in its URL and inside the page.
77
78
So with @ls -ld@ we can find the application username in this way:
79 1 Denis 'GNUtoo' Carikli
<pre>
80 5 Denis 'GNUtoo' Carikli
root@m0:/data/data # ls -ld org.smssecure.smssecure
81 3 Denis 'GNUtoo' Carikli
__bionic_open_tzdata: couldn't find any tzdata when looking for localtime!
82
__bionic_open_tzdata: couldn't find any tzdata when looking for GMT!
83
__bionic_open_tzdata: couldn't find any tzdata when looking for posixrules!
84
drwxr-x--x 2 u0_a61 u0_a61 4096 2012-01-01 00:01 org.smssecure.smssecure
85
</pre>
86
87
Here the users and groups are @u0_a61@.
88 1 Denis 'GNUtoo' Carikli
89 5 Denis 'GNUtoo' Carikli
We will then need this information later on to restore the silence data from the other device: If we restore that data as-is it will most likely have wrong permissions: when the the silence application was installed on the older device, it was assigned an username. As this username depends on the number of applications that were installed before it, we cannot expect it to always be the same between the two devices.
90
91
It's also best to move or delete the data we don't want:
92 3 Denis 'GNUtoo' Carikli
<pre>
93
root@m0:/data/data # mv org.smssecure.smssecure org.smssecure.smssecure.delme
94
</pre>
95 1 Denis 'GNUtoo' Carikli
96 5 Denis 'GNUtoo' Carikli
Moving it has several advantages:
97
* We can still verify the username later on to see if it matches with the backup we restored.
98
* We can interrupt this tutorial more easily if something goes wrong.
99
100
Here we need to verify that the archive will extract its files in the @org.smssecure.smssecure@ directory and not in the current directory which is @/data/data@:
101 3 Denis 'GNUtoo' Carikli
<pre>
102
root@m0:/data/data # tar tf /org.smssecure.smssecure.tar
103
./org.smssecure.smssecure/
104
./org.smssecure.smssecure/lib -> /data/app/org.smssecure.smssecure-1/lib/arm
105
[...]
106 1 Denis 'GNUtoo' Carikli
</pre>
107 5 Denis 'GNUtoo' Carikli
Here we see that everything starts with @./org.smssecure.smssecure/@ (or @org.smssecure.smssecure/@) so it's good.
108 1 Denis 'GNUtoo' Carikli
109 5 Denis 'GNUtoo' Carikli
TODO: move this part earlier
110
111
If we had something like that instead:
112 1 Denis 'GNUtoo' Carikli
<pre>
113 5 Denis 'GNUtoo' Carikli
root@m0:/data/data # tar tf /org.smssecure.smssecure.tar
114
./lib -> /data/app/org.smssecure.smssecure-1/lib/arm
115
[...]
116
</pre>
117
118
Then it's best to recreate the archive.
119
120
If you need more time you could also move back org.smssecure.smsecure.delme to org.smssecure.smssecure if needed.
121
122
We can then proceed to extract the application data (with the username from the old device):
123
<pre>
124 3 Denis 'GNUtoo' Carikli
root@m0:/data/data # tar xpf /org.smssecure.smssecure.tar --numeric-owner
125
</pre>
126 1 Denis 'GNUtoo' Carikli
127 5 Denis 'GNUtoo' Carikli
Here we can see that the username differs from the one we need:
128 3 Denis 'GNUtoo' Carikli
<pre>
129
root@m0:/data/data # ls -ld org.smssecure.smssecure 
130
__bionic_open_tzdata: couldn't find any tzdata when looking for localtime!
131
__bionic_open_tzdata: couldn't find any tzdata when looking for GMT!
132
__bionic_open_tzdata: couldn't find any tzdata when looking for posixrules!
133
drwxr-x--x 9 u0_a63 u0_a63 4096 2012-01-01 00:21 org.smssecure.smssecure
134 1 Denis 'GNUtoo' Carikli
</pre>
135 5 Denis 'GNUtoo' Carikli
We have @u0_a63@ instead of @u0_a61@.
136 1 Denis 'GNUtoo' Carikli
137 5 Denis 'GNUtoo' Carikli
So we need to fix it. This can be done with the @chown@ command, like that:
138 3 Denis 'GNUtoo' Carikli
<pre>
139
root@m0:/data/data # chown u0_a61:u0_a61 -R org.smssecure.smssecure            
140
root@m0:/data/data # 
141
</pre>
142 1 Denis 'GNUtoo' Carikli
143 5 Denis 'GNUtoo' Carikli
At this point, we don't need the @org.smssecure.smssecure.delme@ directory anymore, and it's best to remove it not to create any issues later on.
144
This can be done with the following command:
145 3 Denis 'GNUtoo' Carikli
<pre>
146
root@m0:/data/data # rm -rf org.smssecure.smssecure.delme
147
root@m0:/data/data # 
148
</pre>
149 1 Denis 'GNUtoo' Carikli
150 5 Denis 'GNUtoo' Carikli
In addition to the standard unix permissions, Android also uses selinux, so we also need to fixup the selinux permissions.
151
152
The restorecon command can be used for that. Here's its help: 
153 3 Denis 'GNUtoo' Carikli
<pre>
154
root@m0:/data/data # restorecon                                                
155
usage: restorecon [-D] [-F] [-R] [-n] [-v] FILE...
156
157
Restores the default security contexts for the given files.
158
159
-D	apply to /data/data too
160
-F	force reset
161
-R	recurse into directories
162
-n	don't make any changes; useful with -v to see what would change
163
-v	verbose: show any changes
164
165
restorecon: Needs 1 argument
166
</pre>
167 1 Denis 'GNUtoo' Carikli
168 5 Denis 'GNUtoo' Carikli
So to use it to fixup the selinux permissions, we can use the following command:
169 1 Denis 'GNUtoo' Carikli
<pre>
170 5 Denis 'GNUtoo' Carikli
root@m0:/data/data # restorecon -D -F -R -v /data/
171
</pre>
172
173 6 Denis 'GNUtoo' Carikli
The order of the arguments (-D, -F, etc) seem to be important here as the wrong order might result in nothing being done.
174
Without the @-v@ argument and with the wrong order of argument, it might make you think that it did its job while it did nothing.
175
176 5 Denis 'GNUtoo' Carikli
It will then print something that looks like that:
177
<pre>
178 3 Denis 'GNUtoo' Carikli
SELinux: Loaded file_contexts contexts from /file_contexts.
179
[...]
180
SELinux:  Relabeling /data/data/org.smssecure.smssecure from u:object_r:system_data_file:s0 to u:object_r:app_data_file:s0:c512,c768.
181
SELinux:  Relabeling /data/data/org.smssecure.smssecure/lib from u:object_r:system_data_file:s0 to u:object_r:app_data_file:s0:c512,c768.
182
[...]
183 1 Denis 'GNUtoo' Carikli
</pre>
184
185 5 Denis 'GNUtoo' Carikli
The premissions fixing is now done.
186
187
So we can then umount the data partition and reboot.
188
189
To do that first we need to go outside of data, else the mount will fail:
190 1 Denis 'GNUtoo' Carikli
<pre>
191 5 Denis 'GNUtoo' Carikli
root@m0:/data/data # cd /
192
root@m0:/ # 
193
</pre>
194
195
Then we can simply unmount it with this command:
196
<pre>
197 3 Denis 'GNUtoo' Carikli
root@m0:/ # umount  /data/                                                     
198 1 Denis 'GNUtoo' Carikli
root@m0:/ # 
199
</pre>
200 3 Denis 'GNUtoo' Carikli
201 5 Denis 'GNUtoo' Carikli
Then it's a good practice to make sure that everything is written to the data partition before rebooting.
202
We can do that with the @sync@ command:
203 1 Denis 'GNUtoo' Carikli
<pre>
204
root@m0:/ # sync
205 5 Denis 'GNUtoo' Carikli
</pre>
206
207
And we can finally reboot:
208
<pre>
209 1 Denis 'GNUtoo' Carikli
root@m0:/ # reboot
210
</pre>
211
212 5 Denis 'GNUtoo' Carikli
After rebooting, silence still refused to start.
213
214
So I looked at the logs from my laptop with this command:
215 1 Denis 'GNUtoo' Carikli
<pre>
216 5 Denis 'GNUtoo' Carikli
$ adb logcat -b main
217
</pre>
218
219
I waited until no more new logs were printed.
220
221
I then press enter multiple times to create a separation with many new lines to be able to get back to the begining of the new logs easily.
222
Then I launched silence and started pressing enter multiple times again to mark the end of the silence related logs.
223
224
I then had that in these new logs:
225
<pre>
226 4 Denis 'GNUtoo' Carikli
01-01 01:27:48.260  4126  4126 D AndroidRuntime: Shutting down VM
227
01-01 01:27:48.265  4126  4126 E AndroidRuntime: FATAL EXCEPTION: main
228
01-01 01:27:48.265  4126  4126 E AndroidRuntime: Process: org.smssecure.smssecure, PID: 4126
229
01-01 01:27:48.265  4126  4126 E AndroidRuntime: Theme: themes:{}
230
01-01 01:27:48.265  4126  4126 E AndroidRuntime: java.lang.RuntimeException: Unable to create application org.smssecure.smssecure.ApplicationContext: java.lang.SecurityException: getActiveSubscriptionInfoList: Neither user 10061 nor current process has android.permission.READ_PHONE_STATE.
231 1 Denis 'GNUtoo' Carikli
01-01 01:27:48.265  4126  4126 E AndroidRuntime: 	at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4754)
232
[...]
233
</pre>
234
235 5 Denis 'GNUtoo' Carikli
So to fix it I went in @Settings->Apps->Silence->Permissions@ and gave it all the permissions it needed.
236
237
I had this issue because I didn't even launch silence after installing it, so it cound't ask me for the permissions it needed.
238
And the silence of the former device probably wrote in its data that it already asked the permissions.