Skip to content

Instantly share code, notes, and snippets.

@uyjulian
Last active May 31, 2023 00:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save uyjulian/87434480bfa1cb37dd6393e35742e3dc to your computer and use it in GitHub Desktop.
Save uyjulian/87434480bfa1cb37dd6393e35742e3dc to your computer and use it in GitHub Desktop.
# References:
# https://github.com/ashang/unar/blob/473488cc612c3f47e1c76f9baf92d268db259dc1/XADMaster/XADRPMParser.m
# https://refspecs.linuxbase.org/LSB_3.1.1/LSB-Core-generic/LSB-Core-generic/pkgformat.html
import os
import sys
import shutil
with open(sys.argv[1], "rb") as f:
lead_header_bytes = f.read(4)
if lead_header_bytes == b"\xED\xAB\xEE\xDB":
f.seek(92, os.SEEK_CUR) # skip rest of lead
signature_header_bytes = f.read(4)
if signature_header_bytes == b"\x8E\xAD\xE8\x01":
f.seek(4, os.SEEK_CUR)
signature_entries = int.from_bytes(f.read(4), byteorder="big")
signature_bytes = int.from_bytes(f.read(4), byteorder="big")
f.seek((signature_entries * 16) + ((signature_bytes + 7) & (7 ^ 0xffffffff)), os.SEEK_CUR)
header_header_bytes = f.read(4)
if header_header_bytes == b"\x8E\xAD\xE8\x01":
f.seek(4, os.SEEK_CUR)
header_entries = int.from_bytes(f.read(4), byteorder="big")
header_bytes = int.from_bytes(f.read(4), byteorder="big")
f.seek((header_entries * 16) + header_bytes, os.SEEK_CUR)
# The actual archive data is here. Split here
header_len = f.tell()
f.seek(0)
with open(sys.argv[1] + ".header", "wb") as wf:
wf.write(f.read(header_len))
with open(sys.argv[1] + ".cpio.gz", "wb") as wf:
shutil.copyfileobj(f, wf)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment