.. 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`