Czy istnieje sposób, aby zajrzeć do środka i zmodyfikować plik kopii zapasowej adb?

40

Utworzyłem kopię zapasową mojego Galaxy Nexusa adb backup. Powstały plik nosi nazwę backup.db i jest w jakiś sposób zaszyfrowany.

Chciałem przywrócić kopię zapasową, ale zatrzymuje się ona w przypadku przywracania com.android.providers.contacts. Kiedyś adb logcat, aby dowiedzieć się, co się dzieje i okazało się, że com.android.acoreawarii podczas procesu przywracania.

Chciałbym uzyskać dostęp do danych w kopii zapasowej i usunąć bazę danych kontaktów, aby przywrócić wszystko z powrotem do mojego telefonu. Czy istnieją inne sposoby przywracania danych z kopii zapasowej?

ingorichter
źródło

Odpowiedzi:

14

Plik nie jest szyfrowany, chyba że określisz to podczas tworzenia kopii zapasowej. Jest jednak skompresowany (przy użyciu deflacji). Dokładny format można znaleźć, przeglądając kod źródłowy Androida (com / android / server / BackupManagerService.java) i technicznie powinien być w stanie wyodrębnić z niego określone dane. Jednak, IIRC, istnieją pewne kontrole integralności plików, więc najprawdopodobniej nie zadziała, jeśli po prostu usuniesz z niego wiązkę danych. Niestety restorepolecenie wydaje się nie mieć opcji przywracania konkretnej aplikacji / pakietu lub wykluczania pakietu.

Nikolay Elenkov
źródło
Dzięki! To przynajmniej punkt wyjścia do zaglądnięcia do pliku. Byłoby łatwiej, gdybym nie podał hasła do kopii zapasowej.
ingorichter
Jeśli podałeś hasło, jest ono rzeczywiście szyfrowane. Program „BackupManagerService” zawiera szczegółowe informacje na temat rzeczywistych algorytmów szyfrowania, a parametry uzyskiwania kluczy (sól, liczba iteracji itp.) Są zapisywane w nagłówku pliku. Ponieważ znasz hasło, możesz uzyskać klucz i odszyfrować dane. Nadal jest to wykonalne, ale nie jest szczególnie łatwe ...
Tak, obecnie rozpakowuję wszystko, BackupManagerServiceaby odczytać zawartość pliku kopii zapasowej. To dużo pracy, ale potrzebuję danych z powrotem ...
ingorichter
@ingorichter jakiś postęp?
jon
@ingorichter Zacząłem nad tym pracować i zamieściłem mnóstwo notatek poniżej w odpowiedzi na „wiki społeczności”. Dodaj do tego.
jon
50

Zacząłem nad tym pracować. Do tej pory zamieszczam wyniki jako odpowiedź „wiki społeczności” z dwóch powodów: po pierwsze, jeśli ktoś inny chce dołączyć, istnieje miejsce do rozmowy; po drugie, jeśli oderwę się od tego projektu, pojawią się wskazówki dla kogoś innego, aby zaczął działać.

 

Logika tworzenia kopii zapasowych na hoście jest całkowicie zawarta w https://github.com/android/platform_system_core/blob/master/adb/commandline.cpp w funkcji o nazwie backup. Funkcja jest bardzo prosta: sprawdza poprawność opcji wiersza poleceń, wysyła polecenie głównie w niezmienionej postaci do demona adb w telefonie i zapisuje dane wyjściowe telefonu do pliku. Nie ma nawet sprawdzania błędów: jeśli na przykład odmówisz wykonania kopii zapasowej w telefonie, adbpo prostu zapisujesz pusty plik.

Na telefonie logika tworzenia kopii zapasowych rozpoczyna się service_to_fd()w https://github.com/android/platform_system_core/blob/master/adb/services.cpp . Funkcja identyfikuje, że polecenie hosta jest "backup", i przekazuje nieprzetworzone polecenie /system/bin/bu, które jest trywialnym skryptem powłoki, który można uruchomić com.android.commands.bu.Backupjako główną klasę nowego procesu aplikacji na Androida. To wywołuje, ServiceManager.getService("backup")aby uzyskać usługę tworzenia kopii zapasowych jako IBackupManager, i wywołuje IBackupManager.fullBackup(), przekazując jej wciąż nieużywany deskryptor pliku (bardzo pośrednio) podłączony do backup.abpliku na hoście.

Sterowanie przechodzi fullBackup()w com.android.server.backup.BackupManagerService , która pojawia się GUI z prośbą o potwierdzenie / odrzucenie kopię zapasową. Gdy użytkownik to zrobi, acknowledgeFullBackupOrRestore()wywoływany jest (ten sam plik). Jeśli użytkownik zatwierdzi żądanie, acknowledgeFullBackupOrRestore()dowie się, czy kopia zapasowa jest zaszyfrowana, i przekaże wiadomość do BackupHandler(tego samego pliku), BackupHandlera następnie utworzy wystąpienie i uruchomi PerformAdbBackupTask(ten sam plik, wiersz 4004 w momencie zapisu)

W końcu zaczynamy generować produkcję tamPerformAdbBackupTask.run() , między linią 4151 a linią 4330 .

Najpierw run()pisze nagłówek, który składa się z 4 lub 9 linii ASCII:

  1. "ANDROID BACKUP"
  2. wersja formatu kopii zapasowej: obecnie "4"
  3. albo "0"jeśli kopia zapasowa jest nieskompresowana, albo "1"jest
  4. Metoda szyfrowania: obecnie albo "none"albo"AES-256"
  5. (jeśli są zaszyfrowane), „sól hasła użytkownika” zakodowana szesnastkowo, wszystkie wielkie litery
  6. (jeśli są zaszyfrowane), „sól kontrolna suma kontrolna” zakodowana szesnastkowo, wszystkie wielkie litery
  7. (jeśli są zaszyfrowane), „liczba użytych rund PBKDF2” jako liczba dziesiętna: obecnie "10000"
  8. (jeśli są zaszyfrowane), „IV klucza użytkownika” zakodowane szesnastkowo, wszystkie wielkie litery
  9. (jeśli są zaszyfrowane), „główny obiekt blob IV +, zaszyfrowany kluczem użytkownika” zakodowany szesnastkowo, wszystkie wielkie litery

Rzeczywiste dane kopii zapasowej w następujący sposób, jako (w zależności od kompresji i szyfrowania) tar, deflate(tar), encrypt(tar), lub encrypt(deflate(tar)).

 

DO ZROBIENIA : napisz ścieżkę kodu, która generuje wyjście tar - możesz po prostu użyć tar, o ile wpisy są w odpowiedniej kolejności (patrz poniżej).

Format archiwum tar

Dane aplikacji są przechowywane w katalogu app /, zaczynając od pliku _manifest, APK (na żądanie) w /, pliki aplikacji w f /, bazy danych w db / i wspólne preferencje w sp /. Jeśli zażądano kopii zapasowej zewnętrznej pamięci masowej (przy użyciu opcji -shared), w archiwum będzie także udostępniony katalog / zawierający pliki zewnętrznej pamięci masowej.

$ tar tvf mybackup.tar
-rw------- 1000/1000      1019 2012-06-04 16:44 apps/org.myapp/_manifest
-rw-r--r-- 1000/1000   1412208 2012-06-02 23:53 apps/org.myapp/a/org.myapp-1.apk
-rw-rw---- 10091/10091     231 2012-06-02 23:41 apps/org.myapp/f/share_history.xml
-rw-rw---- 10091/10091       0 2012-06-02 23:41 apps/org.myapp/db/myapp.db-journal
-rw-rw---- 10091/10091    5120 2012-06-02 23:41 apps/org.myapp/db/myapp.db
-rw-rw---- 10091/10091    1110 2012-06-03 01:29 apps/org.myapp/sp/org.myapp_preferences.xml

Szczegóły szyfrowania

  1. Klucz AES 256 jest uzyskiwany z hasła do szyfrowania kopii zapasowej przy użyciu 10000 rund PBKDF2 z losowo wygenerowaną 512-bitową solą.
  2. Klucz główny AES 256 jest generowany losowo
  3. „Suma kontrolna” klucza głównego jest generowana przez uruchomienie klucza głównego przez 10000 rund PBKDF2 z nową losowo wygenerowaną 512-bitową solą.
  4. Generowane jest losowe szyfrowanie kopii zapasowej IV.
  5. IV, klucz główny i suma kontrolna są łączone i szyfrowane za pomocą klucza pochodzącego z 1. Powstały obiekt blob jest zapisywany w nagłówku jako ciąg szesnastkowy.
  6. Rzeczywiste dane kopii zapasowej są szyfrowane kluczem głównym i dołączane na końcu pliku.

Przykładowa implementacja kodu paczki / rozpakowania (produkuje / wykorzystuje) archiwa tar: https://github.com/nelenkov/android-backup-extractor

Więcej szczegółów tutaj: http://nelenkov.blogspot.com/2012/06/unpacking-android-backups.html

Skrypty Perla do pakowania / rozpakowywania i naprawy uszkodzonych archiwów:

http://forum.xda-developers.com/showthread.php?p=27840175#post27840175

jon
źródło
Jeśli gdzieś umieścisz kod, mogę dołączyć. OP (@ngorichter) prawdopodobnie ma już także działający kod :) Narzędzie, które dekompresuje i wyodrębnia rzeczywiste pliki, może być przydatne, abyś mógł przywracać tylko części (jeśli oczywiście masz root).
Nikolay Elenkov
1
Jeśli chodzi o część szyfrowania, muszę sprawdzić szczegóły, ale klucz jest uzyskiwany przy użyciu PBKDF2 przez kod PIN soli i odblokowania urządzenia, hasło lub wzór (konwertowany na ciąg). Klucz główny jest generowany losowo i szyfrowany za pomocą klucza uzyskanego z hasła. Zacznij od pracy w przypadku niezaszyfrowanych archiwów. Mogę zaimplementować część deszyfrującą, jeśli masz z tym problem.
Nikolay Elenkov
Niestety, klucz jest wyprowadzany na podstawie hasła podanego podczas uruchamiania kopii zapasowej.
Nikolay Elenkov
@NikolayElenkov Nie mam jeszcze żadnego kodu, ale planuję napisać narzędzie do manipulowania plikami ab. Szyfrowanie Wrt, nie sądzę, że będzie to trudne; po prostu przejrzałem tylko tę część kodu. Podobnie prześledziłem ścieżkę kodu (jeszcze nie napisaną powyżej), która generuje strumień tar, ale jeszcze nie sprawdziłem, czy rzeczywistym formatem jest tar GNU.
jon
Wow, jestem pod wrażeniem twojej analizy. Wyodrębniłem trochę kodu z BackupManagerService do prostego, świetnego skryptu, ale kiedy uruchamiam program, wynik jest zawsze taki sam: wprowadzono nieprawidłowe hasło! Utworzyłem nową kopię zapasową z prostym hasłem, ale weryfikacja hasła nie powiodła się. Obecnie staram się postępować zgodnie z programem opisanym powyżej, aby znaleźć swój błąd.
ingorichter
7

Świetna i szczegółowa odpowiedź Nikołaja Elenkowa . Powinienem jednak dodać, że ktoś już opracowuje oprogramowanie, które właśnie to robi i pakuje je tutaj: http://sourceforge.net/projects/adbextractor/

Pakiet zawiera zarówno narzędzia Java, jak i Perl. Ja osobiście wolę Perla niż Javę, więc wyodrębniłem kody Perla, upewniłem się, że są one wykonywalne, zainstalowałem wymaganą bibliotekę Perla i uruchomiłem backupdecrypt.plplik kopii zapasowej adb i przekonwertowałem go na plik tar lub gzip kwestia.

W Bash 3 utworzyłem nawet jedną linijkę, która pozwala mi na tworzenie kopii zapasowej adb bezpośrednio w gzipowanym pliku tar:

adb backup -f >(backupdecrypt.pl -D -z - backup.tgz) -all

Mam nadzieję, że to pomoże.

SP Arif Sahari Wibowo
źródło
6
Tak, spakowali narzędzie (napisane w Javie), które napisałem :) Pomogłem również przenieść to do Perla. Jeśli nie przeczytałeś README, może nie być od razu oczywiste, że najpierw pojawił się zapis, a potem narzędzia ...
Nikolay Elenkov
Zrobiłem kopię zapasową, ale nie utworzyłem pliku .ab, zamiast tego utworzyłem plik .backup. Chcę wiedzieć, jak to wyodrębnić. Nie jestem też pewien, czy wszystkie zdjęcia i filmy zostały pobrane jako kopie zapasowe?
hajirazin
-4

Aby przejrzeć istniejący plik kopii zapasowej, wypróbuj stronę http://www.adb-backup.com , jest to proste bez „dd”, „tar”, ...

Dane nie są przechowywane na tym serwerze. Opracowałem tę usługę online, aby ułatwić przeglądanie kopii zapasowych bez manipulacji przy użyciu dd / tar lub instalowania dodatkowego oprogramowania. Jestem autorem www.adb-backup.com

Liszak
źródło
7
Byłbym bardzo ostrożny przy przesyłaniu kopii zapasowej adb (i podaniu hasła) do losowej witryny ... Dane zawarte w kopii zapasowej adb są prywatne i nie masz możliwości dowiedzenia się, co strona robi z kopią zapasową. Może to być nieszkodliwe, ale nie zaleciłbym tego.
bmdixon
Według Metasmoke jest to URL spamu . Poza tym w pełni zgadzam się z @bmdixon tutaj - zwłaszcza, że ​​istnieją bezpieczne sposoby wykonywania zadania lokalnie.
Izzy
@Izzy W każdym razie oznaczyłem jako spam i zgłosiłem to SmokeDetectorowi.
iBug
Dane nie są przechowywane na tym serwerze. Opracowałem tę usługę online, aby ułatwić przeglądanie kopii zapasowych bez manipulacji przy użyciu dd / tar lub instalowania dodatkowego oprogramowania. Jestem autorem www.adb-backup.com
Liszak