Axml

Struct Axml 

Source
pub struct Axml { /* private fields */ }
Expand description

The main AXML object representing a binary Android XML file.

§Dual-state synchronization

Axml carries two representations of the same data that must be kept in sync:

  1. Decoded state: stringblocks, resource_map, elements. These fields are the ground truth during parsing and editing.
  2. Proto state: proto is a prost-generated message used for protobuf serialization. It is populated lazily by update_proto().

Rule: after any mutation to the decoded state (e.g. modifying elements or calling import_stringblocks_json), callers must invoke update_proto() before calling get_proto() or any proto-based serialization path. Failing to do so will return a stale proto that does not reflect the current state.

Implementations§

Source§

impl Axml

Source

pub fn new() -> Self

Create a new empty AXML document.

Source

pub fn get_proto(&self) -> &Axml

Return a reference to the cached prost-generated protobuf message. The proto is populated during from_axml() / from_xml(). Call update_proto() first if the internal state has been modified.

Source

pub fn string_count(&self) -> usize

Number of strings in the string pool.

Source

pub fn export_stringblocks_json(&self) -> String

Serialize the string pool as a JSON object for use with --stringblocks-file.

Source

pub fn import_stringblocks_json(&mut self, json: &str)

Pre-populate the string pool from a JSON object previously produced by export_stringblocks_json.

Source

pub fn from_axml(data: &[u8]) -> Result<Self, AxmlError>

Parse binary AXML data into an Axml object.

Source

pub fn pack(&self) -> Vec<u8>

Serialize the AXML object back to binary format.

Bytes 4..8 of the output (the chunk total-size field) come from self.total_size verbatim. Set that field to an arbitrary value before calling pack() to produce intentionally malformed output. Call compute() first to write the correct size.

Source

pub fn to_xml(&self) -> Result<String, AxmlError>

Decode the AXML to a human-readable XML string.

Source

pub fn from_xml(&mut self, xml: &str) -> Result<(), AxmlError>

Build binary AXML from a plain XML string.

Two-pass implementation: the first pass collects all xmlns: declarations so that StartNamespace elements can be emitted before any StartElement. The second pass builds the binary elements. Android attribute → resource-ID mappings are collected inline and the resource map is assembled after the loop.

Source

pub fn compute(&mut self)

Recalculate all chunk-size header fields and store them in the struct.

Updates self.total_size (AXML outer header) and marks the string pool dirty so pack() produces a fully correct binary.

Without calling compute(), pack() uses whatever sizes were last stored either the original parsed values, values set manually, or a stale size left by apply_stringblocks_no_compute().

Source

pub fn apply_stringblocks_no_compute(&mut self, new_strings: Vec<Vec<u8>>)

Apply new string pool content without updating the pool’s chunk-size header.

new_strings must be the data bytes from each StringBlock proto entry (raw UTF-8 or UTF-16-LE bytes, no length prefix, no null terminator).

After this call pack() returns a binary where string content reflects the new values but the chunk total-size field is stale, an intentionally corrupted file useful for security testing. Call compute() before pack() to produce a correctly-sized output instead.

Source

pub fn to_proto_text(&self) -> String

Serialize to proto text format using the native prost-reflect formatter. Requires update_proto() to have been called (automatically done by from_axml() and from_xml()).

Source

pub fn to_proto_text_pretty(&self) -> String

Serialize to indented proto text format (one field per line).

Source

pub fn export_proto_file(&self, path: &str) -> Result<(), AxmlError>

Write the binary proto representation of this AXML file to path.

Source

pub fn from_proto_file(path: &str) -> Result<Self, AxmlError>

Load an AXML from a binary proto file written by [export_proto_file].

Source

pub fn export_stringblocks_proto_file( &self, path: &str, ) -> Result<(), AxmlError>

Write the binary proto representation of this file’s string pool to path.

Source

pub fn import_stringblocks_proto_file( &mut self, path: &str, ) -> Result<(), AxmlError>

Replace the string pool from a binary proto file written by [export_stringblocks_proto_file]. Marks the pool dirty so that the next pack() / compute() recalculates chunk sizes.

Source§

impl Axml

Source

pub fn to_proto_bytes(&self) -> Vec<u8>

Serialize this AXML file as a binary protobuf message (proto encoding, not the Android binary AXML format).

Source

pub fn from_proto_bytes(data: &[u8]) -> Result<Self, AxmlError>

Deserialize an AXML file from binary protobuf bytes produced by [to_proto_bytes].

Source

pub fn to_proto(&self) -> Axml

Convert to the prost-generated [proto::Axml] message for in-process manipulation.

Source

pub fn from_proto(p: Axml) -> Result<Self, AxmlError>

Reconstruct an Axml from a prost-generated [proto::Axml] message.

Source

pub fn update_proto(&mut self)

Recompute self.proto and self.stringblocks.proto from the current in-memory state. Called automatically at the end of from_axml() and from_xml(). Call manually if you modify stringblocks.inner or elements directly.

Trait Implementations§

Source§

impl Default for Axml

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

§

impl Freeze for Axml

§

impl RefUnwindSafe for Axml

§

impl Send for Axml

§

impl Sync for Axml

§

impl Unpin for Axml

§

impl UnwindSafe for Axml

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.