¿Cómo extrae los datos de una aplicación de una copia de seguridad completa realizada a través de "adb backup"?

117

He estado haciendo una copia de seguridad de mi Nexus 7 adb backuppara hacer una copia de seguridad de todos los archivos en una copia de seguridad cifrada. Veo que puede restaurar desde una copia de seguridad con adb restore, pero eso eliminaría todos mis datos existentes en el dispositivo.

¿Cómo extraería exactamente los datos de una aplicación de este archivo de copia de seguridad cifrado?

Ryan Conrad
fuente

Respuestas:

113

Solo para referencia de otros, aquí hay algunos antecedentes sobre el formato de archivo .ab.

El archivo de copia de seguridad de Android (* .ab) es un archivo TAR comprimido . Se comprime usando el algoritmo DEFLATE . Además de eso, puede haber encriptación AES utilizada. Esto se determina cuando crea la copia de seguridad; si ingresa una contraseña, la copia de seguridad se cifra, de lo contrario; no hay cifrado, solo está comprimido.

El HEADER del archivo es un poco diferente a un archivo DEFLATE normal. Contiene información sobre la copia de seguridad y tiene el siguiente aspecto:

ANDROID BACKUP
1
1
none

La primera línea es la línea "Magia" . La siguiente línea es la versión del formato de archivo de copia de seguridad de Android. La siguiente línea es un booleano (verdadero o falso, 1 o 0) que indica si el archivo está comprimido. La última línea es el tipo de cifrado. Este ejemplo no está usando ningún cifrado. Si hubiera una contraseña, la línea leería "AES-256". Después de eso es el cifrado de cifrado. Si no hay contraseña, se inicia el "archivo" DEFLATE.

Está comprimido usando el Deflater de Java . Lo cual, desde la perspectiva de los desarrolladores, causa problemas si desea usar algo además de Java para extraerlo. No he podido encontrar nada que pueda desinflarlo usando el mismo algoritmo, aunque se supone que todo lo que he encontrado (por ejemplo, C #) sigue el "SPEC".

Dicho esto, hay un proyecto de código abierto bajo la licencia Apache 2.0, escrito por Nikolay Elenkov que le permitirá extraer el archivo .ab en un archivo tar.

Uso:

java -jar abe.jar unpack <backup.ab> <backup.tar> <password>

Si no está seguro de cómo usar realmente eso (que está más allá del alcance de esta respuesta), la próxima versión de Droid Explorer v0.8.8.7 ( disponible aquí ) le permitirá hacer exactamente esto, y más, directamente desde Explorer. Puede leer más sobre las funciones en mi blog (sí, lo sé, un enchufe descarado. Lo hago cuando se ajusta a la pregunta)

deshacer

Ryan Conrad
fuente
1
¡Te votaría si tuviera reputación, mi dios gracias!
de nada. Solo conozco toda esa información porque esta es una característica que agregué recientemente a la base de código de Droid Explorer, así que tuve que investigar un poco al respecto.
Ryan Conrad
Hola Ryan, traté de usar Droid Explorer, pero no puedo comenzar a quejarme de la ubicación del SDK de Android, a pesar de que está instalado y estoy proporcionando el camino correcto.
Umar Farooq Khawaja
@UmarFarooqKhawaja Echa un vistazo a las preguntas frecuentes para el explorador de droides. El último Q / A aborda su problema.
Ryan Conrad el
OK, he extraído la carpeta relevante 'com.app.name' del tar, pero ¿cómo lo uso para restaurar los datos de la aplicación? Simplemente copiar la carpeta a sdcard / Android / data / no parece funcionar ...
pelms
91

O con una línea:

( printf "\x1f\x8b\x08\x00\x00\x00\x00\x00" ; tail -c +25 backup.ab ) |  tar xfvz -
Kari
fuente
2
¡Agradable! ¿También tiene el equivalente de "paquete" (para tomar el árbol de directorios descomprimido y crear un archivo .db)?
dailyglen
44
¿Podría agregar una explicación a la respuesta?
Lucky
2
Esta es la mejor respuesta: D ¡Funciona perfectamente bien! Extrayendo ahora.
xdevs23
16
Explicación: el autor crea un encabezado de archivo Zlib estándar para un .tar.gzarchivo con printfcomando ( 0x1F 0x8Bes una firma, 0x08es el método de compresión, 0x00son banderas y 4 x 0x00es la marca de tiempo), luego agrega a este encabezado el contenido del backup.abarchivo, comenzando desde el desplazamiento 25d. Dicha secuencia es un .tar.gzarchivo válido , y el tar xfvzcomando lo reconoce como tal, por lo que puede descomprimir con éxito la secuencia.
antonone
3
Hice una copia de seguridad con adb 1.0.36 (Revisión 1.7.0.0 + r33-2) y este método produjo un error de zgip:invalid compressed data--format violated
Rache
31

Una opción más es usar bash, caty gunzip( gzip).

El proceso completo podría ser este ( con una copia de seguridad sin cifrar ):

  1. copia de seguridad de los datos de una aplicación (por ejemplo, " Anular DNS para KitKat "):

    $ adb backup -f net.mx17.overridedns.ab -noapk net.mx17.overridedns
    Now unlock your device and confirm the backup operation.
    
  2. extraer los datos comprimidos

    $ dd if=net.mx17.overridedns.ab bs=1 skip=24 > compressed-data
    1285+0 records in
    1285+0 records out
    1285 bytes (1,3 kB) copied, 0,00745877 s, 172 kB/s
    
  3. descomprimir los datos comprimidos

    $ printf "\x1f\x8b\x08\x00\x00\x00\x00\x00" \
        | cat - compressed-data | gunzip -c > decompressed-data.tar
    gzip: stdin: unexpected end of file
    
  4. "deshacer" el archivo tar

    $ tar xf decompressed-data.tar
    
MaxChinni
fuente
44
¿Es de esperar el "final inesperado del archivo"?
hft
La extracción en 2 sorprendentemente funcionó en un archivo cifrado. ¿Cómo es esto posible? La descompresión luego falló con gzip: stdin: invalid compressed data--format violated. Supongo que la extracción tuvo éxito, como se ddinforma 22763821+0 records in 22763821+0 records out.
Tom Russell
4

Otra opción es usar Perl AdbBackupRoutines de este hilo XDA . Sin embargo, tienen algunos requisitos: obviamente, Perl, más libterm-readkey-perl, libcrypt-cbc-perly libcrypt-pbkdf2-perl(si sus copias de seguridad no están encriptadas, puede omitir la última dependencia simplemente comentando la línea 103 de backupdecrypt.pldónde está incluida, funcionó bien para mí).

El uso es bastante fácil:

./backupdecrypt.pl [options] <backupfile.ab> <outfile.tar>

El .tararchivo resultante puede ser investigado como cualquier otro tarball. Su estructura es bastante interesante en al menos un aspecto: no refleja las rutas reales de las que se han tomado los archivos (por ejemplo /data/data/com.app.name/databases/whatever.db, no , pero en su lugar apps/com.app.name/db/whatever.db), lo que indica que una aplicación respaldada en un dispositivo / ROM podría restaurarse a cualquier otro dispositivo / ROM sin problemas, como adb restoredebe descubrir las rutas reales en sí.

Izzy
fuente
Hay otra herramienta (un poco mejor mantenida) que hace esto: github.com/nelenkov/android-backup-extractor
tapa
Gracias, @lid! También he incluido un pequeño script de shell (casi de una sola línea) con mi herramienta Adebar (Android DEvice Backup And Report), que convierte las copias de seguridad ADB ( .ab) en .tar.gzarchivos :)
Izzy
4

Basado en la información de otros, ahora sé que el archivo de copia de seguridad es solo un flujo desinflado prefijado (GZip), basado en esta información, este simple programa puede descomprimirlo para usted:

import java.io.*;
import java.util.zip.*;

/** Run: javac unab.java && java unab backupfile.ab */
public class unab {
    private static final int BACKUP_HEADER_LENGTH = 24;
    public static void main(String[] args) throws IOException {
        InputStream in = new FileInputStream(args[0]);
        try {
            OutputStream out = new FileOutputStream(args[0] + ".tar");
            try {
                if (in.skip(BACKUP_HEADER_LENGTH) != BACKUP_HEADER_LENGTH) {
                    throw new IOException("Unexpected end of file while skipping backup header.");
                }
                byte[] buffer = new byte[100 * 1024];
                int count;
                InputStream zip = new InflaterInputStream(in);
                while ((count = zip.read(buffer)) > 0) {
                    out.write(buffer, 0, count);
                }
            } finally {
                out.close();
            }
        } finally {
            in.close();
        }
    }
}

Escribí esto porque no tengo ninguna de las herramientas de Unix mencionadas anteriormente, y fue más fácil que instalar Cygwin u otras herramientas.

Ventajas :

  • multiplataforma
  • simple (sin parámetros esotéricos)
  • sin necesidad de herramientas de tubería

desventajas :

  • necesita un JDK (que probablemente ya tenga porque está jugando con el SDK de Android)
  • sin soporte para copias de seguridad cifradas
  • Necesito algo para extraer el archivo tar resultante (uso Total Commander)

Para convertirlo en una herramienta de línea de comandos, cree unab.batcon contenido: java -cp "%~dp0." unab %*y el directorio para PATH.

TWiStErRob
fuente
4

Como la pregunta implícita también es, cómo restaurar los datos de una sola aplicación, me gustaría mencionar esta ingeniosa secuencia de comandos, que divide un archivo full-backup.ab en archivos single-app.ab:

https://sourceforge.net/projects/adb-split/

Requiere los archivos jar: abe.jar y tar-bin-split.jar que se pueden encontrar aquí:

Al menos funcionó para mi caso de prueba.

joe_zeroh
fuente