Tôi bắt đầu làm việc này. Tôi đang đăng kết quả của mình cho đến nay dưới dạng câu trả lời "wiki cộng đồng" vì hai lý do: thứ nhất, nếu ai đó muốn tham gia, có một nơi để nói chuyện; thứ hai, nếu tôi bị kéo ra khỏi dự án này, sẽ có gợi ý cho người khác bắt đầu làm việc.
Logic sao lưu trên máy chủ hoàn toàn được chứa trong https://github.com/android/pl platform_system_core / blog / master / adb / commandline.cpp , trong hàm có tên backup
. Chức năng này rất đơn giản: nó xác nhận các tùy chọn dòng lệnh, gửi lệnh chủ yếu là tương tự với daemon adb trên điện thoại và ghi đầu ra của điện thoại vào tệp. Thậm chí không có kiểm tra lỗi: ví dụ, nếu bạn từ chối bản sao lưu trên điện thoại, adb
chỉ cần ghi ra một tập tin trống.
Trên điện thoại, logic sao lưu bắt đầu service_to_fd()
trong https://github.com/android/pl platform_system_core / blog / master / adb / service.cpp . Hàm xác định rằng lệnh từ máy chủ lưu trữ "backup"
và chuyển lệnh chưa được xử lý tới /system/bin/bu
, đây là một tập lệnh shell tầm thường để khởi chạy com.android.commands.bu.Backup
như là lớp chính của một quy trình ứng dụng Android mới. Điều đó gọi ServiceManager.getService("backup")
để có được dịch vụ sao lưu dưới dạng IBackupManager
và gọi IBackupManager.fullBackup()
, chuyển cho nó bộ mô tả tệp vẫn chưa được sử dụng (rất gián tiếp) được kết nối với backup.ab
tệp trên máy chủ.
Kiểm soát chuyển đến fullBackup()
trong com.android.server.backup.BackupManagerService , bật lên GUI yêu cầu người dùng xác nhận / từ chối sao lưu. Khi người dùng làm như vậy, acknowledgeFullBackupOrRestore()
(cùng một tệp) được gọi. Nếu người dùng chấp thuận yêu cầu, hãy acknowledgeFullBackupOrRestore()
tìm hiểu xem bản sao lưu có được mã hóa hay không và gửi một tin nhắn đến BackupHandler
(cùng một tệp.) BackupHandler
Sau đó khởi tạo và khởi động một PerformAdbBackupTask
( cùng một tệp, dòng 4004 tại thời điểm viết)
Cuối cùng chúng tôi bắt đầu tạo đầu ra ở đó, trongPerformAdbBackupTask.run()
, giữa dòng 4151 và dòng 4330 .
Đầu tiên, run()
viết một tiêu đề, bao gồm 4 hoặc 9 dòng ASCII:
"ANDROID BACKUP"
- phiên bản định dạng sao lưu: hiện tại
"4"
- hoặc
"0"
nếu sao lưu không nén hoặc "1"
nếu nó là
- phương thức mã hóa: hiện tại
"none"
hoặc"AES-256"
- (nếu được mã hóa), "muối mật khẩu người dùng" được mã hóa thành hex, tất cả các chữ hoa
- (nếu được mã hóa), "muối tổng kiểm tra chính" được mã hóa ở dạng hex, tất cả các chữ hoa
- (nếu được mã hóa), "số vòng PBKDF2 được sử dụng" dưới dạng số thập phân: hiện tại
"10000"
- (nếu được mã hóa), "IV của khóa người dùng" được mã hóa ở dạng hex, tất cả các chữ hoa
- (nếu được mã hóa), "blob khóa IV + chính, được mã hóa bởi khóa người dùng" được mã hóa thành hex, tất cả các chữ hoa
Chức năng sao lưu dữ liệu thực tế sau, hoặc là (tùy thuộc vào nén và mã hóa) tar
, deflate(tar)
, encrypt(tar)
, hoặc encrypt(deflate(tar))
.
TODO : viết đường dẫn mã tạo đầu ra tar - bạn chỉ cần sử dụng tar miễn là các mục nhập theo đúng thứ tự (xem bên dưới).
Định dạng lưu trữ Tar
Dữ liệu ứng dụng được lưu trữ trong thư mục ứng dụng /, bắt đầu bằng tệp _manifest, APK (nếu được yêu cầu) trong /, tệp ứng dụng trong f /, cơ sở dữ liệu theo db / và tùy chọn chia sẻ trong sp /. Nếu bạn yêu cầu sao lưu bộ nhớ ngoài (sử dụng tùy chọn chia sẻ), cũng sẽ có một thư mục / chia sẻ trong kho lưu trữ chứa các tệp lưu trữ ngoài.
$ 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
Chi tiết mã hóa
- Khóa AES 256 được lấy từ mật khẩu mã hóa dự phòng bằng 10000 vòng PBKDF2 với muối 512 bit được tạo ngẫu nhiên.
- Khóa chính AES 256 được tạo ngẫu nhiên
- Khóa chính 'tổng kiểm tra' được tạo bằng cách chạy khóa chính thông qua 10000 vòng PBKDF2 với muối 512 bit được tạo ngẫu nhiên mới.
- Một IV mã hóa sao lưu ngẫu nhiên được tạo ra.
- Khóa IV, khóa chính và tổng kiểm tra được nối và mã hóa với khóa xuất phát trong 1. Blob kết quả được lưu trong tiêu đề dưới dạng chuỗi hex.
- Dữ liệu sao lưu thực tế được mã hóa bằng khóa chính và được thêm vào cuối tệp.
Gói mẫu / giải nén mã thực hiện (sản xuất / sử dụng) lưu trữ tar: https://github.com/nelenkov/android-backup-extractor
Một số chi tiết ở đây: http://nelenkov.blogspot.com/2012/06/unpacking-android-backups.html
Các kịch bản Perl để đóng gói / giải nén và sửa chữa các tài liệu lưu trữ bị hỏng:
http://forum.xda-developers.com/showthread.php?p=27840175#post27840175