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

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 borraría todos mis datos existentes en el dispositivo.

¿Cómo extraería exactamente los datos de una aplicación de este archivo de respaldo encriptado?

Creo que ninguna de las respuestas sin usar Java funcionará en teléfonos encriptados. Vea mi respuesta a continuación que resume el uso de la aplicación de nelenkov (github.com/nelenkov/android-backup-extractor). Desafortunadamente, los scripts perl ab2tar de Adebar de Izzy no funcionarán en archivos de copia de seguridad encriptados. Similar: android.stackexchange.com/questions/23357/…
relacionado- dd if=data.ab bs=1 skip=24 | openssl zlib -d | tar -xvf -mencionado stackoverflow.com/questions/18533567/…

Respuestas (10)

Cómo extraer archivos ab

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

Uso:

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

Antecedentes

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 utilizando el algoritmo DEFLATE . Además de eso, se puede utilizar el cifrado AES . 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 ENCABEZADO del archivo es un poco diferente al de 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 "Magic" . La siguiente línea es la versión del formato de archivo de copia de seguridad de Android. La siguiente línea es un valor 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 utiliza ninguna encriptación. Si hubiera una contraseña, la línea diría "AES-256". Después de eso está el cifrado de cifrado. Si no hay contraseña, se inicia el "archivo" DEFLATE.

Se comprime utilizando Java Deflater . 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 (como C #) sigue el "SPEC".

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

deshacer

Te votaría si tuviera la reputación, ¡Dios mío, gracias!
Bienvenido. Solo conozco toda esa información porque esta es una función que agregué recientemente a la base de código de Droid Explorer, por lo que tuve que investigar un poco al respecto.
Hola, Ryan, intenté usar Droid Explorer pero no comienza a quejarse de la ubicación del SDK de Android, a pesar de que está instalado y estoy proporcionando la ruta correcta.
@UmarFarooqKhawaja Eche un vistazo a las preguntas frecuentes sobre el explorador de droides. Las últimas preguntas y respuestas abordan su problema.
Bien, extraje la carpeta 'com.app.name' relevante del tar, pero ¿cómo uso eso para restaurar los datos de la aplicación? Simplemente copiar la carpeta a sdcard/Android/data/ no parece funcionar...
El archivo resultante tarpuede tener un encabezado incorrecto, lo he encontrado. El último consejo que he recibido es ejecutar el siguiente comando, que no ayudó. YMMV:dd if=backup01.tar bs=24 skip=1 | zlib-flate -uncompress | tar xf -
puede valer la pena decirle a la gente dónde hacer clic para instalarlo sin cargar todo en Visual Studio i.stack.imgur.com/7GQUB.png

O con una sola línea:

( printf "\x1f\x8b\x08\x00\x00\x00\x00\x00" ; tail -c +25 backup.ab ) |  tar xfvz -
¡Bonito! ¿También tiene el equivalente de "paquete" (para tomar el árbol de directorios sin comprimir y crear un archivo .db)?
¿Podría agregar una explicación a la respuesta?
ESTA es la mejor respuesta: D ¡Funciona perfectamente bien! Extrayendo ahora.
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 indicadores y 4 x 0x00es una marca de tiempo), luego agrega a este encabezado el contenido del backup.abarchivo, comenzando desde el desplazamiento 25d. .tar.gzDicho flujo es un archivo válido y el tar xfvzcomando lo reconoce como tal, por lo que puede descomprimirlo con éxito.
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
Muy agradable. ¿Se puede modificar para aceptar una contraseña de descifrado?
¡Gracias, eso fue realmente útil! Como uno de los comentaristas en una respuesta similar, recibí un error de "fin de archivo inesperado", pero todo parece estar bien. Y como @dailyglen, me gustaría saber si esto es reversible.
tengo el mismo problema, gzip: stdin: datos comprimidos no válidos; formato violado tar: el niño murió con la señal 13 tar: el error no es recuperable: saliendo ahora
@Matifou @Rache Como tengo el mismo problema invalid compressed datay configuré una contraseña en la copia de seguridad, sospecho que ese es el problema. Dado que ni tar ni gzip admiten la protección con contraseña, supongo que ahora hay una manera, este comando se puede ajustar fácilmente para solicitar una contraseña. :(
¿Hay alguna manera de hacer que esto funcione con una copia de seguridad cifrada? Recientemente actualicé mi teléfono y elegí encriptar su sistema de archivos. Eso me dio una copia de seguridad encriptada y tuve que recurrir al abe.jarmétodo mucho más complicado.
Probé todos los métodos dados en todas las respuestas aquí, pero solo obtengo archivos tar vacíos. ¿Qué estoy haciendo mal?
@JosefScript, es todo para archivos ab sin cifrar. Estoy en el mismo barco. Probando la respuesta de Izzy a continuación ( android.stackexchange.com/a/42224/95893 ) que usa perl, en realidad probando su aplicación GitHub porque es una molestia instalar los requisitos para su script. Acabo de publicar un problema en su GitHub sobre cómo usar su herramienta ab2tar en cifrado. Avísame si se te ocurre algo y yo haré lo mismo, gracias
2 veces más rápido usando dd que tail en mi computadora portátil:(printf "\x1f\x8b\x08\x00\x00\x00\x00\x00" && dd if=backup.ab bs=1M iflag=skip_bytes skip=24) | tar ztv

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. hacer una 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. "descomprimir" el archivo tar

    $ tar xf decompressed-data.tar
    
¿Se espera el "final inesperado del archivo"?
La extracción en 2 sorprendentemente funcionó en un archivo encriptado. ¿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 ddinforma 22763821+0 records in 22763821+0 records out.
@TomRussell La extracción simplemente recorta bytes del inicio.
¿No es dd un poco exagerado saltarse 24 bytes? Esto tampoco es a prueba de fallas a menos que conv=noerror,sync iflag=fullblockse agregue: superuser.com/a/1523120/910769 Puede considerar esta respuesta: android.stackexchange.com/a/78183/340401

Basado en la información de otros, ahora sé que el archivo de copia de seguridad es solo una secuencia desinflada (GZip) con prefijo, según esta información, este programa simple 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ías

Desventajas :

  • necesita un JDK (que probablemente ya tenga porque está jugando con Android SDK)
  • no hay soporte para copias de seguridad encriptadas
  • necesito algo para extraer el archivo tar resultante (yo uso Total Commander)

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

En realidad, esta es una solución bastante elegante: puede ver de inmediato lo que está haciendo en un pequeño código Java. Simplemente use java (ya está en su máquina la mayor parte del tiempo): coloque el código anterior en "unab.java", llame a "javac unab.java" desde la línea de comando y luego llame a "java unab YUORFILE.ab" y eso es. ¡Gracias!

Como la pregunta implícita también es "cómo restaurar los datos de una sola aplicación", me gustaría mencionar este ingenioso script , que divide un full-backup.ab dado en archivos single-app.ab.

Requiere estos archivos jar: abe.jar y tar-bin-split.jar .

Al menos para mi caso de prueba, funcionó con los recursos a los que se hace referencia.

Otra opción es usar Perl AdbBackupRoutines de este subproceso XDA . Sin embargo, tienen algunos requisitos: Perl obviamente, 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.pldonde está incluida; funcionó bien para mí).

El uso es bastante fácil:

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

El archivo resultante .tarse puede investigar 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, no /data/data/com.app.name/databases/whatever.db, sino 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, ya que adb restoredebe descubrir las rutas reales por sí mismo.

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

Para agregar otra opción, aquí hay una versión de Windows PowerShell de la manipulación del encabezado:

$file_in = (Get-Location).Path + "\backup.ab"
$file_temp = (Get-Location).Path + "\temp.tgz"
[int32[]]$header = 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00
$bytes = [System.IO.File]::ReadAllBytes($file_in)
$bytesout = $header + $bytes[24..($bytes.Length - 1)]
[System.IO.File]::WriteAllBytes($file_temp, $bytesout)

Puede intentar usar el ejecutable tar en las versiones actuales de Windows 10 17063 o posteriores para extraer el archivo, sin embargo, parece que actualmente no maneja el archivo deformado producido en este proceso tan bien como la versión de Linux. YMMV:

tar -xvzf $file_temp

Para obtener el contenido completo, puede extraerlo manualmente con 7zip o similar. O podría combinarse con una de las respuestas de la extracción Native .tar en Powershell .

7zip y otras herramientas de archivo cuentan con herramientas de línea de comandos
Me gusta esta técnica, pero aparece un error OOM (memoria insuficiente) cuando intento usarla. Es la penúltima línea en el script de PS la que parece consumir toda la memoria RAM disponible.

Solo para agregar a otras respuestas, finalmente lo obtuve usando la aplicación de nelenkov y las instrucciones de aquí . Estaba tratando de evitar el espacio en disco adicional de 800 mb para Java. La mayoría de los teléfonos se están moviendo hacia el cifrado de forma predeterminada, y creo que la aplicación de nelenkov es la única solución que funciona bien con el cifrado.

Aquí hay un enlace directo al lanzamiento de jar compilado de nelenkov . Verifique si es el último, luego siga las instrucciones del enlace anterior. Tiene más información sobre Helium y Dividir un archivo ab en archivos de aplicaciones individuales. Y también una forma de cambiar las aplicaciones que no están configuradas para usar la copia de seguridad adb sin root. Sustitúyalo abe-all.jarsi utiliza este archivo de versión.

  1. Convierta la copia de seguridad adb original al formato tar:

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

  1. Extraiga el contenido del archivo tar. Esto debe hacerse en un sistema de archivos donde se conserven los permisos de los archivos dentro del tar, por ejemplo, usando linux, mac o bsd. Pueden aparecer hasta dos carpetas, apps y shared:

tar -xvf nexus7.tar

Ahora debería tener nuevas carpetas para buscar. Ahora puede ver qué aplicaciones están respaldadas y cuáles no.

Por cierto, la respuesta de Izzy es buena, pero su secuencia de comandos requiere la instalación de varios módulos de Perl, el tercero de los cuales no pude encontrar fácilmente. Su aplicación tiene todas las funciones, pero encuentra adb2taren Adebar-master/tools/. Una vez más, no funciona con archivos ab cifrados.

No sabía ab2tarque requiere ningún módulo de Perl. Básicamente, lo que hace es lo que describe la respuesta de rmil;) Pero tal vez lo hizo en una versión anterior...

Esto funcionó para mí en el entorno Linux:

dd if=backup.adb skip=1 bs=24 | zlib-flate -uncompress | cat > somewhere.tar
tar xvf somewhere.tar
Duplicar a arriba como, por ejemplo, android.stackexchange.com/a/73052/340401 ?
@Cadoiz no, revisa los comandos de cerca. Esto aquí es más bien lo ab2tarque hace Adebar (ver la respuesta de la alquimia).
¿Cuál es el punto de canalizar stdin cat? Elimine todo el | catpaso en la canalización.

Puede descargar el último binario del procesador de copia de seguridad de Android . Una vez descargado, extraiga el archivo zip y ejecute:

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

Comandos
Usage:
    info:       java -jar abp.jar [-debug] [-useenv=yourenv] info <backup.ab> [password]
    unpack:     java -jar abp.jar [-debug] [-useenv=yourenv] unpack <backup.ab> <backup.tar> [password]
    pack:       java -jar abp.jar [-debug] [-useenv=yourenv] pack <backup.tar> <backup.ab> [password]
    pack-kk:    java -jar abp.jar [-debug] [-useenv=yourenv] pack-kk <backup.tar> <backup.ab> [password]