Skip to content

Instantly share code, notes, and snippets.

@Lekensteyn
Created December 29, 2015 22:22
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 Lekensteyn/defef304fc2f62fd5237 to your computer and use it in GitHub Desktop.
Save Lekensteyn/defef304fc2f62fd5237 to your computer and use it in GitHub Desktop.
Quick and dirty script to parse aboot images
#!/usr/bin/env python
# From target/msm8974/tools/mkheader.c (size renamed to size)
"""
magic[0] = 0x00000005; /* appsbl */
magic[1] = 0x00000003; //Flash_partition_version /* nand */
magic[2] = 0x00000000; //image source pointer
magic[3] = base; //image destination pointer
magic[4] = code_size + cert_chain_size + signature_size; //image size
magic[5] = code_size; //code size
magic[6] = base + code_size; // start of sigs
magic[7] = signature_size;
magic[8] = code_size + base + signature_size; // start of certs
magic[9] = cert_chain_size;
if (unified_boot == 1) {
magic[10] = 0x33836685; /* cookie magic number */
magic[11] = 0x00000001; /* cookie version */
magic[12] = 0x00000002; /* file formats */
magic[13] = 0x00000000;
magic[14] = 0x00000000; /* not setting size for boot.img */
magic[15] = 0x00000000;
magic[16] = 0x00000000;
magic[17] = 0x00000000;
magic[18] = 0x00000000;
magic[19] = 0x00000000;
}
"""
import argparse, logging, struct, sys
from collections import namedtuple
_logger = logging.getLogger("aboot-parse")
sbl_header_struct = struct.Struct("<10I")
"""
(relative to destination)
+-------------+ base .
| code | | code_size
+-------------+ . .
| signature | | sig_size
+-------------+ . .
| cert chain | | cert_chain_size
+-------------+ image_size .
"""
sbl_header_fields = """
magic
version
image_source
image_base
image_size
code_size
sig_offset
sig_size
certs_offset
certs_size
""".split()
sbl_header = namedtuple("SblHeader", ' '.join(sbl_header_fields))
def handle_part(f, size, what):
data = f.read(size)
assert len(data) == size, "Expected %d bytes, read %d" % (size, len(data))
_logger.debug("Read %d bytes for %s", size, what)
return data
def open_local_readable(path):
if path == '-':
try: return sys.stdin.buffer
except: return sys.stdin
else:
return open(path, "rb")
parser = argparse.ArgumentParser()
parser.add_argument("--debug", action='store_true', help="Enable debug messages")
parser.add_argument("--dump", choices=['code', 'sig', 'certs', 'padding'],
help='Dump this part to stdout')
parser.add_argument("file", help="aboot file")
def main():
args = parser.parse_args()
logging.basicConfig(format='%(asctime)s %(name)s: %(levelname)s: %(message)s',
level=logging.DEBUG if args.debug else logging.INFO)
try: stdout_bin = sys.stdout.buffer
except: stdout_bin = sys.stdout
with open_local_readable(args.file) as f:
hdr = sbl_header_struct.unpack(f.read(sbl_header_struct.size))
for name, value in zip(sbl_header_fields, hdr):
_logger.debug("%-12s: %08x (%d)", name, value, value)
h = sbl_header(*hdr)
_logger.debug("%r", h)
code = handle_part(f, h.code_size, "code")
sig = handle_part(f, h.sig_size, "sig")
certs = handle_part(f, h.certs_size, "certs")
padding = f.read()
if padding:
_logger.debug("Padding length: %d", len(padding))
if args.dump:
data = {
"code": code,
"sig": sig,
"certs": certs,
"padding": padding,
}[args.dump]
stdout_bin.write(data)
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment