README
GENERAL INFO
Project: Library to parse and modify AXML files (Rust implementation) Author: Benoît Forgette alias MadSquirrel License: GNU General Public License v3.0 and later
GOAL
pyaxml-rs is a full Rust rewrite of PyAxml to parse and write AXML (Android XML) binary files. It exposes the same functionality as the original Python library through three interfaces:
- A native Rust library crate (
pyaxml_rs) for use in Rust projects. - A Python package (
pyaxml) built with maturin and PyO3, providing the same API as the originalpyaxmlPython package. - Two CLI entry-points with identical commands:
pyaxml-rs: native Rust binary, no Python required.
Runtime dependencies (minimal by design):
quick-xml: XML parsing for thexml2axmldirectionzip: APK/ZIP file support in the CLIpyo3: (optional, only when building the Python extension)
PyAxml is a Rust tool with python wrapper to play with AXML (Android XML) files. This tool is useful to decode and encode AXML files and manipulate AXML files over a Protocol Buffers object. It is designed to work with Python 3 only. Some examples of the use of the tool is provided with the project:
- copymanifest.py that allow to decode and reencode the original file
- replace_activity_name.py to change the name an activity and replace by an other
If you want to see more example you can dig more on the project apkpatcher that use this library to add some useful permission and inject a library inside the target application.
BUILD & INSTALL
Prerequisites
- Rust toolchain (
rustup): https://rustup.rs/ - Python 3.8+ with a virtual environment (for the Python extension)
Build the Python extension
python3 -m venv .venv
source .venv/bin/activate
pip install maturin
maturin develop # debug build (fast)
maturin develop --release # release build
This installs both the pyaxml Python package and the pyaxml-rs CLI entry-point.
Build the Rust CLI binary
cargo build --release
# Binary at: target/release/pyaxml-rs
Install the Rust CLI system-wide
cargo install --path .
Or use the Makefile:
make build # compile release binary
make install # cargo install
CLI USAGE
pyaxml-rs [-h] [-i INPUT] [-o OUTPUT] [-p PATH] [-v]
[--stringblocks-file STRINGBLOCKS_FILE]
{axml2xml,xml2axml,arsc2xml,axml2proto}
Commands
| Command | Description |
|---|---|
axml2xml |
Decode a binary AXML file (or AndroidManifest.xml from an APK) to plain XML |
xml2axml |
Encode a plain XML file back to binary AXML |
arsc2xml |
Parse a resources.arsc file to XML grouped by locale |
arsc2proto |
Decode a resources.arsc file to protobuf text format |
axml2proto |
Decode a binary AXML file to protobuf text format |
Options
| Flag | Description |
|---|---|
-i FILE / --input FILE |
Input file (AXML, XML, or APK/ZIP) |
-o FILE / --output FILE |
Output file (default: stdout) |
-p PATH / --path PATH |
Path of a specific file inside a ZIP/APK |
-v / --version |
Print version |
--stringblocks-file FILE |
Export or import the string pool as JSON (axml2xml / xml2axml) |
--pretty |
Pretty-print protobuf output (arsc2proto / axml2proto) |
Examples
# Decode AndroidManifest.xml from a binary AXML file
pyaxml-rs axml2xml -i AndroidManifest.xml
# Decode from an APK
pyaxml-rs axml2xml -i app.apk -o manifest.xml
# Decode a specific file from an APK
pyaxml-rs axml2xml -i app.apk -p res/xml/network_security_config.xml
# Encode XML back to binary AXML
pyaxml-rs xml2axml -i manifest.xml -o AndroidManifest.xml
# Dump the intermediate protobuf text representation
pyaxml-rs axml2proto -i AndroidManifest.xml
# Export string pool alongside the XML
pyaxml-rs axml2xml -i AndroidManifest.xml --stringblocks-file strings.json
# Re-encode using a previously exported string pool
pyaxml-rs xml2axml -i manifest.xml -o out.axml --stringblocks-file strings.json
# Same commands work with the Python CLI
pyaxml axml2xml -i AndroidManifest.xml
PYTHON API
import pyaxml
# Parse binary AXML
with open("AndroidManifest.xml", "rb") as f:
data = f.read()
axml = pyaxml.AXML.from_axml(data)
# Convert to an XML Element (lxml or stdlib ET)
element = axml.to_xml()
# Re-pack to binary
binary = axml.pack()
# Build from XML
axml2 = pyaxml.AXML()
axml2.from_xml(element)
binary2 = axml2.pack()
# String pool access
print(axml.string_count())
print(axml.get_string(0))
# Parse binary ARSC
arsc = pyaxml.ARSC.from_axml(data)
xml_str = arsc.list_packages()
# Auto-detect AXML vs ARSC
obj = pyaxml.AXMLGuess.from_axml(data)
TESTS
# Rust integration tests
cargo test
# Python tests (requires maturin develop first)
python3 -m pytest tests-py/ -v
Or use the Makefile:
make test # both Rust and Python tests
make test-rs # Rust only
make test-py # Python only
MAKEFILE TARGETS
| Target | Description |
|---|---|
make build |
Compile the release binary (pyaxml-rs) |
make develop |
Build and install the Python extension (maturin develop) |
make lint |
Run all linters (Rust + Python) |
make test |
Run all tests (Rust + Python) |
make test-rs |
Run Rust integration tests only |
make test-py |
Run Python tests only |
make install |
Install pyaxml-rs binary via cargo install |
make bump VERSION=x.y.z |
Bump the version in Cargo.toml |
make clean |
Remove build artefacts |
make help |
Show available targets |
Metadata
Release files for pyaxml 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Built distributions (wheels)
| File | Reset | |||
|---|---|---|---|---|
| pyaxml-0.1.1-cp38-abi3-win_arm64.whl | CPython 3.8 | abi3 | Windows ARM64 | Details |
| pyaxml-0.1.1-cp38-abi3-win_amd64.whl | CPython 3.8 | abi3 | Windows x86-64 | Details |
| pyaxml-0.1.1-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl | CPython 3.8 | abi3 | Linux glibc 2.17+ x86-64 | Details |
| pyaxml-0.1.1-cp38-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl | CPython 3.8 | abi3 | Linux glibc 2.17+ ARMv7l | Details |
| pyaxml-0.1.1-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl | CPython 3.8 | abi3 | Linux glibc 2.17+ ARM64 | Details |
Total release size: 4.9 MB
Release files / pyaxml-0.1.1-cp38-abi3-win_arm64.whl
| Download URL | pyaxml-0.1.1-cp38-abi3-win_arm64.whl |
|---|---|
| Size | 913.6 kB |
| Tags | CPython 3.8 Windows ARM64 abi3 |
|
SHA-256 checksum How to use checksums |
0c33e050defac8de2283f17f09234c9ab5cf874bc24b1ca4303b71b23d238143
|
|
BLAKE2b-256 checksum How to use checksums |
c6c419cb72285d3de13e296de3a1ad237c0d5cf5e3dfe70a86f90a7332159de3
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.13
|
Release files / pyaxml-0.1.1-cp38-abi3-win_amd64.whl
| Download URL | pyaxml-0.1.1-cp38-abi3-win_amd64.whl |
|---|---|
| Size | 947.1 kB |
| Tags | CPython 3.8 Windows x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
10e0539e90d6798b135da5befd089fbdf2bde7a8edd9bbbd364431c532ea6906
|
|
BLAKE2b-256 checksum How to use checksums |
5afae1d2633a380eae851663bacdd72ecb094655a4091b9bb710f0a2a9171e7c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.13
|
Release files / pyaxml-0.1.1-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
| Download URL | pyaxml-0.1.1-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl |
|---|---|
| Size | 1.1 MB |
| Tags | CPython 3.8 Linux glibc 2.17+ x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
27248ea1a6017ef661046560f7bfe7da19dfe73f68bb9fc8aba308652dfa0626
|
|
BLAKE2b-256 checksum How to use checksums |
dade2461b2bb4e164342623c5d9ac308555a951ca00dc38661ff6463db1fd3b9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.13
|
Release files / pyaxml-0.1.1-cp38-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
| Download URL | pyaxml-0.1.1-cp38-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl |
|---|---|
| Size | 974.7 kB |
| Tags | CPython 3.8 Linux glibc 2.17+ ARMv7l abi3 |
|
SHA-256 checksum How to use checksums |
e265a5cd56d3b78ef04a40fb8ab7ec1c3acfbcc29301312dafe9ac6e6727e42f
|
|
BLAKE2b-256 checksum How to use checksums |
0aac1aaa9c8339b76ded855bb76f58cd08e352cebc51787e54d6e7ba2cbaa47c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.13
|
Release files / pyaxml-0.1.1-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
| Download URL | pyaxml-0.1.1-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl |
|---|---|
| Size | 978.8 kB |
| Tags | CPython 3.8 Linux glibc 2.17+ ARM64 abi3 |
|
SHA-256 checksum How to use checksums |
39586936a11d43a1f9d958f2fda674471822f8809d8ff3d0af873ccf6dda5d03
|
|
BLAKE2b-256 checksum How to use checksums |
eaea8b9b8dbfd272fb9fcdfbd6194a72d7b82d1112eaf3846b98c74b82f6cdd9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.13
|
Security for pyaxml 0.1.1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.