Library / SDK
5ec1cff/payload-dumper avatar
5ec1cff/payload-dumper

payload-dumper pulls selected partitions out of an Android OTA without downloading the whole file

Dump Android's payload.bin

853 stars91 forksPythonLicense varies

At a glance

What is it?
payload-dumper is a Python tool for extracting partitions from the payload.bin inside an Android update package, with added support for reading from a zip or straight from a URL and for multithreaded work. Its licence is unstated and the last push to the repository was on 2026-04-03.
Who is it for?
payload-dumper is a good fit for a developer who needs one small partition such as boot, init_boot or vbmeta out of a large Android update package, especially when the package is only reachable over the network, because it can fetch and extract a single partition without pulling the whole payload down. It is not a good tool for repeated production flashing work, since it has no published releases, an unstated licence and a dependency set that includes a native bsdiff4 build.
Can I use it commercially?
Not without permission. GitHub finds no licence file in the repository, and without a licence all rights are reserved by default: you may read the code but not reuse it. Check the README, or ask the authors, before using it.
Is it still maintained?
Activity is slowing. The repository last received commits 6 months ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 24, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The payload.bin inside an Android update package

Android update images ship as a payload.bin, a container of compressed partitions that a device applies during an over the air update. payload-dumper extracts those partitions so you can look at them, patch them or feed them to something else.

The core description in the README is that the tool dumps the payload.bin image found in Android update images, and claims significant performance gains over other tools because it uses multiprocessing. The requirement is Python 3 and pip, and the command is installed as a console script called payload_dumper, mapped in the pyproject file to payload_dumper:main.

What the tool is not is a flasher. Nothing here writes to a device or applies an update. It reads a container and writes partition image files, which makes it a development and analysis tool rather than part of a ROM pipeline.

The repository also carries a Chinese README at docs/README.zh-CN.md, and the English README reads as two documents stitched together. The first half describes this fork's additions in first person, and the second half is the original project's own documentation with its installation section, its partition dump examples and its development instructions. That structure is worth knowing when you read the documentation, because requirements stated in the two halves do not always agree.

Three additions over the original dumper

The fork lists three features on top of the original behaviour, and they are all about not doing unnecessary work.

The first is extracting partitions directly from a zip archive that contains payload.bin, without unpacking the archive first. The second is extracting partitions directly from a URL, such as an OTA update URL, without downloading the entire file. The third is multithreaded downloading and extraction.

The payoff is stated plainly: with this script you need a small amount of time and storage space to extract the partitions you want from an OTA update package or address, especially the smaller partitions such as boot, init_boot and vbmeta.

That is the real use case. A full Android update package is large, and downloading and unpacking all of it to look at a few megabytes of boot image is wasteful, particularly on a metered connection. The tool accepts a file path or a URL as its target, so the same command covers both.

The README ends with a forward looking note, that in the future the tool might support extracting some files inside system partitions. That is an idea rather than a feature, so nothing in the current tool does per-file extraction from a system partition.

Dumping everything, or naming the partitions you want

The simplest run takes the payload file and extracts all of it.

bash
payload_dumper payload.bin

When you only want a few partitions, the tool takes a comma separated list.

bash
payload_dumper --partitions boot,dtbo,vendor payload.bin

That is the same option the fork's own usage snippet uses, where the second argument is either a file path or a URL.

bash
payload_dumper --partitions <partitions you need> <file path or url>

Installation from a clone is the usual Python packaging dance.

bash
pip install git+https://github.com/5ec1cff/payload-dumper

For working on the code itself, the README describes cloning the repository, running the module from the src directory and installing from the project root.

bash
git clone https://github.com/5ec1cff/payload-dumper
# run
cd src
python -m payload_dumper
# install
cd ..
pip install .

Note that the project uses Poetry for its build, with poetry-core as the build backend, so pip install . works by building the project through that backend rather than a plain setup.py path.

Patching an old image with the --diff flag

The second half of the README documents a diff mode for the original tool. OTA packages can carry deltas rather than whole partitions, and in that case the payload contains the changes to apply to an older image.

The command assumes the older partitions are already sitting in a directory named old/.

bash
payload_dumper --diff payload.bin

The mechanism behind that is the bsdiff4 dependency in the pyproject file, which is the Python binding for binary diff patching. The dependency is pinned at 1.2.3 or newer, with a comment in the file noting that this version officially supports Python 3.12. That pin matters because it is a native extension, so an install can fail on a platform without a compiler or a prebuilt wheel.

The requirement here is quiet but important: the diff mode only works if the old partitions are in the right place and in the right format before the tool runs. The README does not document what happens when they are missing or mismatched, so treat a failed diff as a setup problem to diagnose rather than as a corrupt payload.

Both modes need the same decompression stack, which is where the compression dependencies come in.

httpx, protobuf, zstd, brotli and a Python version that disagrees with the README

The dependency list in the pyproject file explains the shape of the tool. httpx with a minimum of 0.23.1 handles HTTP for the URL mode, with a comment linking to a pull request. protobuf at 6.32.0 or newer parses the payload metadata, and the file carries a note that the protobuf runtime is why the Python requirement is set where it is. zstd and brotli provide the two compression formats used by Android payload entries. bsdiff4 handles delta patches. enlighten provides the progress bar, which is the tool you see while a long download runs.

The Python floor is where the two halves of the README disagree. The README installation section says Python3 >= 3.8 and pip, while the pyproject dependency block states python = ">=3.9" with the comment that the protobuf runtime requires this. The metadata is the authority for what installs, so 3.9 is the number to plan around.

The project is built with Poetry, tests are configured in the same file with pythonpath set to src, and the isort configuration sets the black profile with a line length of 89. The repository has no GitHub releases, so the version you get comes from the install commands, and the pyproject file records it as 0.4.0.

No stated licence and a last push from April 2026

The repository does not name a licence. There is no LICENSE file in the tree, the pyproject file has no licence field, and the GitHub licence classification for the project is unknown. That is a practical problem rather than a legal opinion. Without a licence, the default position is that you do not have permission to copy, modify or redistribute the code, and the tool is published on GitHub and on PyPI through a pip install from a git URL.

For a personal analysis script that never ships, most people will not notice. For a tool inside a product build or inside a company repository, the absence of a licence is a blocker that someone has to resolve with the author. Read the repository for any file that grants terms, and if there is none, ask before you redistribute.

On activity, the repository is not archived and the last push was on 2026-04-03, which is over six months back. There are no published releases, so the changelog story is only visible in the commit history. What that means in practice is that you should assume you are running whatever the install commands fetch, test it against your own payload files, and keep your own copy of the version you depend on.

The tooling around the tool is current enough to be usable: httpx and a recent protobuf are pinned, and the compression bindings are separate packages that carry their own release cadence.

Where a manual extraction is enough

The alternative is the manual route. A payload.bin can be unpacked by parsing its metadata and decompressing each entry, which is exactly what this tool automates, and for a single file on a fast machine the result is the same. The difference is in effort and in what happens when the container is large or remote.

Manually, you would extract payload.bin from the OTA zip with an unzip tool, parse the metadata, and decompress entries with a zstd or brotli decoder. That works, but it needs the whole payload present locally first, and it means writing or finding the metadata parsing step. The fork's additions exist precisely to remove those two steps: read the partition out of the zip without unpacking, and read it over HTTP without downloading everything.

There is a case where the manual route wins. If you already have the payload extracted and you want exactly one partition from a local file, the plain payload_dumper command is faster to reason about than adding a URL fetch or a zip reader into the path.

For the network case, the trade is different. Streaming one partition out of a multi gigabyte OTA URL saves the bandwidth and the disk space of the full download, and that saving is why this fork exists at all.

Editorial conclusion

payload-dumper is a good fit for a developer who needs one small partition such as boot, init_boot or vbmeta out of a large Android update package, especially when the package is only reachable over the network, because it can fetch and extract a single partition without pulling the whole payload down. It is not a good tool for repeated production flashing work, since it has no published releases, an unstated licence and a dependency set that includes a native bsdiff4 build. Before adopting it, check the licence yourself because the repository does not name one, confirm your Python version satisfies the pyproject requirement of 3.9 or newer rather than the looser figure in the README, and test the --partitions path first since it is the feature this fork adds.

Frequently asked questions

How do I install payload-dumper?

Run pip install git+https://github.com/5ec1cff/payload-dumper, or clone the repository and install it with pip install . from the project root. The project is built with Poetry and exposes a console script named payload_dumper.

How do I extract only some partitions from payload.bin?

Pass a comma separated list after the --partitions option, for example payload_dumper --partitions boot,dtbo,vendor payload.bin. The final argument can be a local file, a zip archive containing payload.bin, or a URL.

What does the --diff option do?

It patches an older image with the delta carried in the payload, assuming the old partitions are in a directory named old/. The binary patching is handled by the bsdiff4 dependency.

What Python version does payload-dumper need?

The README installation section says Python3 >= 3.8 and pip, but the pyproject file sets the requirement to python = ">=3.9" because the protobuf runtime requires it, so 3.9 is the figure to plan around.

What license does payload-dumper use?

The repository does not state one. There is no LICENSE file in the tree and the pyproject file has no licence field, so the licence classification is unknown and you should confirm the terms with the author before redistributing it.

Official sources

  1. 5ec1cff/payload-dumper on GitHub
  2. Issues
  3. README
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/5ec1cff-payload-dumper.svg)](https://hysenlabs.com/projects/5ec1cff-payload-dumper)

Was this useful?