Skip to content

Instantly share code, notes, and snippets.

@jerrykan
Created March 9, 2022 10:44
Show Gist options
  • Save jerrykan/b3b2f7f43b5e1d4d5b5198748be16bb2 to your computer and use it in GitHub Desktop.
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})"
)
@Overpricedgpu
Copy link

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..

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment