-
-
Save jerrykan/b3b2f7f43b5e1d4d5b5198748be16bb2 to your computer and use it in GitHub Desktop.
#!/usr/bin/env python3 | |
BACKUP_FILE = 'backup.ab' | |
# Constants | |
# ref: https://github.com/omnirom/android_bootable_recovery/blob/android-7.1/adbbu/twadbstream.h | |
TWRP = b'TWRP' + b'\x00\x00\x00\x00' | |
TWSTREAMHDR = b'twstreamheader' | |
TWFN = b'twfilename' | |
TWIMG = b'twimage' | |
TWDATA = b'twdatablock' | |
MD5TRAILER = b'md5trailer' | |
TWENDADB = b'twendadb' | |
class ParseError(Exception): | |
pass | |
with open(BACKUP_FILE, 'rb') as backup_file: | |
initial = backup_file.read(10240) # size picked randomly | |
backup_file.seek(initial.find(TWRP)) | |
while True: | |
block_header = backup_file.read(8) | |
if block_header != TWRP: | |
pos = backup_file.tell() - 8 | |
raise ParseError( | |
f'Expected TWRP header, got: {block_header} ({pos})' | |
) | |
block_type = backup_file.read(16).rstrip(b'\x00') | |
if block_type in (TWSTREAMHDR, TWENDADB): | |
# AdbBackupControlType | |
block_crc = backup_file.read(4) | |
backup_file.seek(484, 1) | |
if block_type == TWENDADB: | |
# We should have reached the end of the backup file | |
break | |
elif block_type in (TWFN, TWIMG): | |
# twfilehdr | |
block_size = backup_file.read(8) | |
block_compressed = backup_file.read(8) | |
block_crc = backup_file.read(4) | |
name = backup_file.read(468).rstrip(b'\x00') | |
file_name = name.split(b'/')[-1].decode() | |
output = open(file_name, 'wb') | |
print('Extracting', block_type.decode(), name.decode()) | |
elif block_type in TWDATA: | |
# AdbBackupControlType + data | |
block_crc = backup_file.read(4) | |
backup_file.seek(484, 1) | |
# Write out data in block | |
output.write(backup_file.read(1048064)) # (1024 * 1024) - 512 | |
elif block_type == MD5TRAILER: | |
# AdbBackupFileTrailer | |
block_crc = backup_file.read(4) | |
block_ident = backup_file.read(4) | |
block_md5 = backup_file.read(40) | |
backup_file.seek(440, 1) | |
output.close() | |
else: | |
pos = backup_file.tell() - 24 | |
raise ParseError( | |
f"Unknown block type: '{block_type}' ({pos})" | |
) |
Thank you so much. Please publish this as a standalone to save people lives. I was almost breaking to cry because I made a backup, assumed it was working and just deleted 2 years of my life from my phone after a corrupt system upgrade. I had a hard time finding this thread.
Thank you so much. Please publish this as a standalone to save people lives. I was almost breaking to cry because I made a backup, assumed it was working and just deleted 2 years of my life from my phone after a corrupt system upgrade. I had a hard time finding this thread.
Same happend with me but in my case I lost my phone efs partition and don't know how to extract it from backup.
Finally I found this after two days of searching, such a life saver..
Thank you for this, I was able to restore my phone piecemeal because the backup had a setting or file that bootlooped my phone if I restored the whole thing. (LeanageOS 21.1, User partitions decrypted by TWRP recovery before backing up)
Hi @JordanPlayz158 unfortunately my knowledge of the TWRP backup files is very limited. This script was written using a bit of guess work as I only had the
twadbstream.h
file to work from. The backup file I was working with didn't have encryption, so I'm not sure what would be involved in decrypting the backup.