Parse, extract and rebuild Android boot-image sections — entirely in memory.
bootseg operates only on boot partition image files (e.g. boot.img). It does
not talk to devices, does not touch partitions, and never writes intermediate files.
The whole source image is read into RAM, sections are recombined there, and the
final result is written to the output you specify.
It is generic: any boot image using the AOSP bootimg.h format, header version 0–4,
works regardless of device, SoC or vendor.
An Android boot image is a fixed struct boot_img_hdr followed by page-aligned
entities. bootseg knows the authoritative field offsets for every header version
(verified against AOSP bootimg.h / mkbootimg.py):
| section | header version | offset (u32 field) |
|---|---|---|
kernel |
all | 0x08 |
ramdisk |
v0–v2 | 0x10 |
| v3–v4 | 0x0C |
|
second |
v0–v2 | 0x18 |
recovery_dtbo |
v1–v2 | 0x660 |
dtb |
v2 only | 0x670 |
signature |
v4 only | 1580 (V4-4) |
page_size |
v0–v2 | 0x24 (v3/v4 fixed 4096) |
Header sizes: v0=1632, v1=1648, v2=1660, v3=1580, v4=1584.
Note: v3 has no dtb/signature sections (mkbootimg ignores --dtb for v2);
v4 has a signature_size field but still no dtb in the boot image itself.
- Python 3.6+ (stdlib only;
struct,os,hashlib,xml.etree,argparse)
bootseg [-i <file.img>] (-r | -e <section> | -f <section> <newfile.img> | -b) [-o <file|dir>] [<file.img>]
The source image can be given with -i/--image/--if <file.img>, as a positional
argument, or as - to read from stdin.
bootseg -r boot.img
Prints image metadata (magic, header version/size, Android OS version), a section table with offset/size/padding/compression/md5 for every section, and whether an AVB vbmeta footer is present.
The AVB footer is reported as present/absent only: vendor footers are not guaranteed to follow the strict AOSP layout, so its numeric fields are not decoded or printed.
bootseg -e ramdisk -o ramdisk.img boot.img
Writes the section's payload (unpadded) to the output file. Works for header too.
bootseg -f ramdisk new_ramdisk.img -o boot_new.img boot.img
Reads new_ramdisk.img, replaces the section in memory, repacks every section
into a compact layout (mkbootimg semantics) and writes the rebuilt image.
The repack is what makes the result bootloader-correct: all sections after the replaced one move to their canonical page-aligned offsets (so shrinking the kernel pulls the ramdisk forward), and every header size field is synced. Without it, an image that keeps original offsets while updating only the size field contradicts itself — the bootloader derives the next section's offset from the (padded) cumulative sizes, exactly the header-sizes you just changed, so it reads padding instead of data.
The replacement may be any size from 1 byte up (no fixed padded-span limit), as
long as the rebuilt image fits its partition. A warning is printed if the output
still carries an AVB footer — the image is never re-signed, so for verified
boot it must pass through avbtool add_hash_footer (or an unlocked bootloader).
bootseg -b -o backup_dir boot.img
Dumps each section as name.img plus a sections.xml table (name/offset/size/
padding/compression/md5/file).
bootseg -r boot.img
bootseg -e kernel -o kernel.img boot.img
bootseg -f ramdisk ramdisk_new.img -o boot_patched.img boot.img
bootseg -b -o ./bak boot.img
cat boot.img | bootseg -r -
0success1invalid input (not a boot image, truncated, unsupported header version, missing section, oversized payload), or no action given (usage is printed)2CLI usage error (argparse)
Fully cross-validated against the official AOSP mkbootimg.py: parse/extract/
rebuild/backup matrices pass for header versions 0–4, payloads are byte-identical,
and error paths are covered (garbage input, truncated header, unknown version,
absent section, oversized payload). Also verified against a real device boot image
(header v3, lzma ramdisk, AVB footer).
MIT