Created
December 29, 2015 22:22
-
-
Save Lekensteyn/defef304fc2f62fd5237 to your computer and use it in GitHub Desktop.
Quick and dirty script to parse aboot images
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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