AXML Module

class apkInspector.axml.ManifestStruct(header: ResChunkHeader, string_pool: StringPoolType, resource_map: XmlResourceMapType, elements)

A class to represent the AndroidManifest as a composition

static check_reached_element(file: BytesIO)

Static method to check if the next element right after the resource map chunk has been reached. There is only a set of possible elements after the resource map chunk that could be met.

Parameters:

file (io.BytesIO) – The AndroidManifest file

get_manifest()

Method to return the AndroidManifest created from this instance

Returns:

The AndroidManifest.xml as a string

Return type:

str

classmethod parse(file)

A composition of the rest of the classes available in the apkInspector.axml module, to form the AndroidManifest structure.

Parameters:

file (bytesIO) – the axml that will be processed

Returns:

an instance of itself

Return type:

ManifestStruct

static parse_lite(manifest, num_of_elements=None)

Parse the AndroidManifest with a limit on the elements to be parsed after the string pool. The goal of this method is to make it possible to partially parse the AndroidManifest and allow faster parsing when needed. Only the header is parsed from each chunk, and the rest are there as blobs of bytes.

Parameters:
  • manifest (bytesIO) – The manifest to be processed

  • num_of_elements (int) – How many elements of the manifest to process. Usually 3 are enough to get basic info about it.

Returns:

A tuple containing four elements: ResChunkHeader, [ResStringPoolHeader, string_pool_data], [ResChunkHeader, resource_map_data], elements

Return type:

tuple (ResChunkHeader_init, [ResStringPoolHeader, bytes], [ResChunkHeader, bytes], list of bytes)

static parse_next_header(file)

Dispatcher method to parse the next available header. It takes into account to move on past the header if it contains extra info besides the standard ones. The dispatcher automatically picks the correct processing method for each chunk type.

Parameters:

file (bytesIO) – the axml that will be processed

Raises:

NotImplementedError – The chunk type identified is not supported

Returns:

Dispatches to the appropriate processing method for each chunk type.

static process_elements(file, num_of_elements=None)

It starts processing the remaining chunks after the resource map chunk.

Parameters:
  • file (BytesIO) – the axml that will be processed

  • num_of_elements (int) – how many elements should it process

Returns:

Returns all the elements found as their corresponding classes and whether dummy data were found in between.

Return type:

set(list, set(bool, bool))

class apkInspector.axml.ResChunkHeader(header_type, header_size, total_size, data)

Chunk header used throughout the axml. This header is essential as it contains information about the header size but also the total size of the chunk the header belongs to.

classmethod parse(file)

Read the header type (2 bytes), header size (2 bytes), and entry size (4 bytes).

Parameters:

file (bytesIO) – the xml file e.g. with open(‘/path/AndroidManifest.xml’, ‘rb’) as file

Returns:

Returns an instance of itself

Return type:

ResChunkHeader

class apkInspector.axml.ResStringPoolHeader(header: ResChunkHeader, string_count, style_count, flags, strings_start, styles_start, data)

It reads the string pool header which contains information about the StringPool.

classmethod parse(file)

Read and parse ResStringPoolHeader from the file.

Parameters:

file (bytesIO) – the xml file right after the header has been read.

Returns:

Returns an instance of itself

Return type:

ResStringPoolHeader

class apkInspector.axml.ResXMLHeader(header: ResChunkHeader, data)

Chunk header used as a header for the elements. This header represents the header for the rest of the elements besides the initial header, the string pool and the resource map.

classmethod parse(file)

Supporting header for the elements besides the initial header, the string pool and the resource map.

Parameters:

file (bytesIO) – the xml file e.g. with open(‘/path/AndroidManifest.xml’, ‘rb’) as file

Returns:

Returns an instance of itself

Return type:

ResXMLHeader

class apkInspector.axml.StringPoolType(string_pool_header: ResStringPoolHeader, string_offsets, strings, string_pool_data)

The stringPool class which is a composition of the ResStringPoolHeader along with the string offsets and the string data.

classmethod decode_stringpool_mixed_string(file, is_utf8, end_stringpool_offset)

Handling the different encoding possibilities that can be met.

Parameters:
  • file (bytesIO) – the xml file at the offset where the string is to be read

  • is_utf8 (bool) – boolean to check if a utf8 string is expected

  • end_stringpool_offset (int) –

Returns:

Returns the decoded string

Return type:

str

classmethod get_string_from_pool(position, string_pool_data, end_stringpool_offset, strings_start, is_utf8)

Retrieve a single string from the String Pool, given its position. It first gets the correct offset of the string and then reads the string.

Parameters:
  • position (int) – The position of the string to be retrieved

  • string_pool_data (io.BytesIO) – the string pool data parsed as bytes

  • end_stringpool_offset (int) – the offset at which the string pool ends

  • strings_start (int) – the offset at which the string data starts

  • is_utf8 (bool) – boolean to check if a utf8 string is expected

Returns:

Returns the string or None

Return type:

str or None

classmethod parse(file)

Parse the string pool to acquire the strings used within the axml.

Parameters:

file (bytesIO) – the xml file right after the file header is read

Returns:

Returns an instance of itself

Return type:

StringPoolType

classmethod parse_lite(file)

A ‘lite’ parser that gets the header and then reads the rest of the chunk as a blob of bytes.

Parameters:

file (bytesIO) – the AndroidManifest.xml file

Returns:

returns the header and the chunk data

Return type:

tuple(ResStringPoolHeader, bytes)

classmethod read_string(file, string_offset, strings_start, is_utf8, end_stringpool_offset)

Read a string from the string pool when the offset of it is known already.

Parameters:
  • file (io.bytesIO) – the string pool data parsed as bytes

  • string_offset (int) – the offset at which the string is located in the string pool

  • strings_start (int) – the offset at which the string data starts

  • is_utf8 (bool) – boolean to check if a utf8 string is expected

  • end_stringpool_offset (int) – the offset at which the string pool ends

Returns:

Returns the string or None

Return type:

str or None

classmethod read_string_offset(file, position)
classmethod read_string_offsets(file, num_of_strings, end_absolute_offset)

Reads the offset available for each string. Requires to know the number of strings available beforehand.

Parameters:
  • file (bytesIO) – the xml file right after the string pool header has been read.

  • num_of_strings (int) – the calculated number of strings available

  • end_absolute_offset (int) – the absolute value of the offset where the offsets finish.

Returns:

Returns a list of strings offsets.

Return type:

list

classmethod read_strings(file, string_offsets, strings_start, is_utf8)

Gets the actual strings based on the offsets retrieved from read_string_offsets().

Parameters:
  • file (bytesIO) – the xml file right after the string pool offsets have been read

  • string_offsets (list) – see -> read_string_offsets()

  • strings_start (int) – the offset at which the string data starts

  • is_utf8 (bool) – boolean to check if a utf8 string is expected

Returns:

Returns a list of the string data

Return type:

list

class apkInspector.axml.XmlAttributeElement(full_namespace_index, name_index, raw_value_index, typed_value_size, typed_value_res0, typed_value_datatype, typed_value_data)

The attributes within each element within the axml, should be described by this class.

classmethod parse(file, attr_count, attr_size)

The method is responsible to parse and retrieve the attributes of an element based on the attribute count. There are many datatypes that are not read according to the specification (at least for now), but that does not affect the main goal of the tool, therefore it is not a priority. For the presentation of the values another check is occurring in the process_attributes method.

Parameters:
  • file (BytesIO) – the axml already pointing at the right offset

  • attr_count (int) – The attribute count value part of XmlStartElement.attrext

  • attr_size (int) – The attribute size value part of XmlStartElement

Returns:

List of attributes

Return type:

list

class apkInspector.axml.XmlEndElement(header: ResXMLHeader, attrext, attrext_data)

The end of an element, where the attrext contains the necessary information on which element it ends.

classmethod parse(file, header_t: ResXMLHeader)

Parse the end of an element.

Parameters:
  • file (bytesIO) – the axml already pointing at the right offset

  • header_t (ResXMLHeader) – the already read header of the chunk

Returns:

an instance of itself

Return type:

XmlEndElement

class apkInspector.axml.XmlEndNamespace(header: ResXMLHeader, prefix_namespace_index, uri_index, end_namespace_data)

Class to represent the end of a Namespace.

classmethod parse(file, header_t: ResXMLHeader)

Parse the ending element of a Namespace.

Parameters:
  • file (bytesIO) – the axml already pointing at the right offset

  • header_t (ResXMLHeader) – the already read header of the chunk

Returns:

an instance of itself

Return type:

XmlEndNamespace

class apkInspector.axml.XmlResourceMapType(header, resids, resids_data)

Resource map class, with the header and the resource IDs.

classmethod parse(file)

Parse the resource map and get the resource IDs.

Parameters:

file (bytesIO) – the xml file right after the string pool is read

Returns:

Returns an instance of itself

Return type:

XmlResourceMapType

classmethod parse_lite(file)

A ‘lite’ parser that gets the header and then reads the rest of the chunk as a blob of bytes.

Parameters:

file (bytesIO) – the AndroidManifest.xml file

Returns:

returns the header and the chunk data

Return type:

tuple(ResChunkHeader, bytes)

class apkInspector.axml.XmlStartElement(header: ResXMLHeader, attrext, attributes, start_element_data)

The starting point of an element, its attributes are described by XmlAttributeElement. The attrext contains information about the element including the attribute count.

classmethod parse(file, header_t: ResXMLHeader)

Parse the current element

Parameters:
  • file (BytesIO) – the axml already pointing at the right offset

  • header_t (ResXMLHeader) – the already read header of the chunk

Returns:

an instance of itself

Return type:

XmlStartElement

class apkInspector.axml.XmlStartNamespace(header: ResXMLHeader, ext, ext_data)

The actual start of the xml, after this the elements of the xml will be found.

classmethod parse(file, header_t: ResXMLHeader)

Parse the starting element of a Namespace :param file: the axml already pointing at the right offset :type file: bytesIO :param header_t: the already read header of the chunk :type header_t: ResXMLHeader :return: an instance of itself :rtype: XmlStartNamespace

class apkInspector.axml.XmlcDataElement(header: ResXMLHeader, data_index, typed_value_size, typed_value_res0, typed_value_datatype, typed_value_data, cdata_data)

A class to cover any CDATA section https://developer.android.com/reference/org/w3c/dom/CDATASection

classmethod parse(file, header_t: ResXMLHeader)

Parse the CDATA element.

Parameters:
  • file (bytesIO) – the axml already pointing at the right offset

  • header_t (ResXMLHeader) – the already read header of the chunk

Returns:

an instance of itself

Return type:

XmlcDataElement

apkInspector.axml.create_manifest(elements, string_list)

Method to create the readable XML AndroidManifest.xml file based on the elements discovered from the processed APK

Parameters:
  • elements (list) – The parsed elements as returned by process_elements()[0]

  • string_list (list) – The string pool data

Returns:

The AndroidManifest.xml as a string

Return type:

str

apkInspector.axml.get_attribute_value(attr_name, attribute, end_stringpool_offset, strings_start, is_utf8, string_pool_data)

Gets the value for a single attribute

Parameters:
  • attr_name (str) – The attribute name as it has been retrieved by the string pool

  • attribute (XmlAttributeElement) – the parsed attribute itself

  • end_stringpool_offset (int) – The end of string pool offset

  • strings_start (int) – the strings start offset for the string pool

  • is_utf8 (bool) – boolean to check if a utf8 string is expected

  • string_pool_data (io.BytesIO) – The string pool data as io.BytesIO

Returns:

returns the attribute value

Return type:

str

apkInspector.axml.get_manifest(raw_manifest)

Helper method to directly return the AndroidManifest file as created by create_manifest()

Parameters:

raw_manifest (bytesIO) – expects the encoded AndroidManifest.xml file as a file-like object

Returns:

returns the decoded AndroidManifest file

Return type:

str

apkInspector.axml.get_manifest_lite(manifest: BytesIO, num_of_elements: int)

A method to provide ‘lite’ parsing of the AndroidManifest in order to retrieve a few details as fast as possible. Based on the integer ‘num_of_elements’ being passed as a parameter, it will attempt to fetch this many chunks right after the ‘resource map’ chunk and will get the attributes values of these elements if they are of instance XmlStartElement

Parameters:
  • manifest (io.BytesIO) – The manifest to be processed

  • num_of_elements (int) –

Returns:

Returns a dictionary of the attributes discovered

Return type:

dict

apkInspector.axml.parse_apk_for_manifest(inc_apk, raw: bool = False, lite: bool = False, num_of_elements: int = 3)

Helper method to retrieve the AndroidManifest directly from an APK, either by providing the APK itself or the path.

Parameters:
  • inc_apk (str) – The path of the APK file or the APK itself

  • raw (bool) – Boolean parameter to define whether the manifest is provided as string or bytes

  • lite (bool) – Boolean parameter to define whether the lite parsing would occur or not

  • num_of_elements (int) – Number of elements to parse from the APK

Returns:

Returns the AndroidManifest.xml as string

Return type:

str

apkInspector.axml.process_attributes(attributes, string_list, ns_dict)

Helps in processing the representation of attributes found in each element of the axml. It should be noted that not all datatypes are taken into account, meaning that the values of certain attributes might not be represented properly.

Parameters:
  • attributes (list) – the attributes of an XmlStartElement object as returned by XmlAttributeElement.parse()

  • string_list (list) – the string data list from the String Pool

  • ns_dict (dict) – a namespace dictionary based on the XmlStartNamespace elements found

Returns:

returns a string of all the attributes with their values

Return type:

str

apkInspector.axml.read_remaining(file: BytesIO, header: ResChunkHeader)
Parameters:
  • file (io.BytesIO) – the current file that is being processed

  • header (ResChunkHeader) – the header of the current chunk of instance ResChunkHeader

Returns:

Returns the remaining bytes of the chunk except the header

Return type:

bytes