.. Pyaxml documentation master file, created by
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
Welcome to Pyaxml's documentation |version| |release|!
==========================================================
PyAxml is a full python tool 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 and Rust 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.
To have a better understanding about how is composed the AXML format a
graphic is associated in drawio and svg format: format.drawio, format.drawio.svg
The link of the project https://gitlab.com/MadSquirrels/mobile/pyaxml
QuickStart
==========
To get you started, here is a detailed example of how to replace an activity
in an Android AXML file using Python. This script utilizes the pyaxml library
to handle the AXML format.
.. code-block:: python
import pyaxml
import click
@click.command()
@click.argument('input_file')
@click.argument('output_file')
@click.argument('activity_name')
@click.argument('new_activity_name')
def replace_activity(input_file, output_file, activity_name, new_activity_name):
filename = input_file
with open(filename, "rb") as f:
axml = pyaxml.AXML.from_axml(f.read())
xml = axml.to_xml()
android_name = "{http://schemas.android.com/apk/res/android}name"
for activity in xml.findall(f"./application/activity/[@{android_name}='{activity_name}']"):
activity.attrib[android_name] = new_activity_name
axml_object = pyaxml.AXML()
axml_object.from_xml(xml)
# Rewrite the file
with open(output_file, "wb") as f:
f.write(axml_object.pack())
if __name__ == "__main__":
replace_activity()
To begin with a more simple example you can use the tool to only encode and
decode AXML thanks to 3 available commands:
- axml2xml: to decode AXML and print it in XML;
- arsc2xml: to decode ARSC and print it in XML;
- xml2axml: to encode XML in AXML.
.. code-block:: bash
# Python CLI
pyaxml axml2xml -i AndroidManifest.xml
pyaxml arsc2xml -i resources.arsc
pyaxml xml2axml -i AndroidManifest.xml -o AndroidManifest.axml
# Rust CLI (same commands, no Python required)
pyaxml-rs axml2xml -i AndroidManifest.xml
pyaxml-rs arsc2xml -i resources.arsc
pyaxml-rs xml2axml -i AndroidManifest.xml -o AndroidManifest.axml
AXML or ARSC
------------
In Android application development, AXML and ARSC files are key components:
- AXML (Android XML): Typically used for AndroidManifest.xml, which contains essential information about the application such as its components and permissions.
- ARSC (Android Resource Synchronized Container): Contains compiled resources like strings, styles, and layouts.
To handle these file types, pyaxml provides distinct classes for each:
- AXML: Manages AXML files, allowing for parsing and modification of XML data.
- ARSC: Handles ARSC files, enabling the manipulation of compiled resource data.
When dealing with files whose type you might not be certain of, pyaxml offers a convenient solution:
- AXML_guess: This class includes the from_axml method, which can automatically determine whether a file is an AXML or an ARSC file. Based on this determination, it returns an instance of either the AXML class or the ARSC class.
**Example Usage**
Here's how you might use AXML_guess to handle files without knowing their exact type:
.. code-block:: python
import pyaxml
import click
@click.command()
@click.argument('input_file')
def process_file(input_file):
filename = input_file
with open(filename, "rb") as f:
guessed_object = pyaxml.AXML_guess.from_axml(data)
if isinstance(guessed_object, pyaxml.AXML):
print("Processing AXML file")
# Handle AXML file
xml = guessed_object.to_xml()
# Perform operations on XML data
# ...
elif isinstance(guessed_object, pyaxml.ARSC):
print("Processing ARSC file")
# Handle ARSC file
# Perform operations on ARSC data
# ...
else:
print("Unknown file type")
# Write the modified AXML to the output file
with open(output_file, "wb") as f:
f.write(guessed_object.pack())
if __name__ == "__main__":
process_file()
Details
=======
.. toctree::
:maxdepth: 2
:titlesonly:
:glob:
user_guide
developer_guide
modules
rust_api
Indices and tables
==================
* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`