Pkg.VDEX — API for parsing Android VDEX containers

Overview

The Pkg.VDEX module contains the API for parsing Android ART VDEX containers. VDEX files are produced by the dex2oat compiler and ship alongside OAT files in /system/framework/ or /data/dalvik-cache/. They embed one or more DEX (or CompactDex) files plus verifier dependencies, quickening information, and other metadata that ART uses to skip class verification at class-load time. The parser supports every released VDEX version (006, 010, 019, 021 and 027).

Parsing a VDEX File

The following code example demonstrates how to enumerate the embedded DEX files in a VDEX container and dump them to disk:

from Pro.Core import *
from Pkg.VDEX import *

def extractDexFromVDEX(fname):
    c = createContainerFromFile(fname)
    if c.isNull():
        return
    obj = VDEXObject()
    if not obj.Load(c) or not obj.Initialize():
        return
    print("version:", obj.GetVersion(), "dex files:", obj.GetDexFileCount())
    for i in range(obj.GetDexFileCount()):
        e = obj.GetDexFile(i)
        print("  [%d] %s offset=0x%x size=%d checksum=0x%08x" %
              (i, e.name, e.offset, e.size, obj.GetChecksum(i)))
        data = obj.GetDexFileData(i)
        data.save(e.name)

Module API

Pkg.VDEX module API.

Classes:

VDEXEntry()

Describes a single region inside a VDEX container.

VDEXObject()

This class represents an Android ART VDEX container.

class VDEXEntry

Describes a single region inside a VDEX container.

Each entry records the offset, the size, and a descriptive name of a logical region of the file, such as the main header, the dex checksums table, an embedded DEX file, the verifier dependencies blob, etc. Use VDEXObject.GetEntries() to enumerate all entries.

class VDEXObject

Bases: Pro.Core.CFFObject

This class represents an Android ART VDEX container.

VDEX files are produced by the Android ART dex2oat compiler and ship alongside OAT files to accelerate class loading. A VDEX container embeds one or more DEX (or CompactDex) files together with verifier dependencies, quickening information, and, depending on the platform version, additional metadata such as boot classpath checksums or type lookup tables. This class supports all released VDEX versions (006, 010, 019, 021 and 027) with a single unified interface.

Methods:

GetChecksum(idx)

Returns the location checksum associated with the DEX file at the given index.

GetDexFile(idx)

Returns the VDEXEntry describing the embedded DEX file at the given index.

GetDexFileCount()

Returns the number of embedded DEX (or CompactDex) files.

GetDexFileData(idx)

Returns a stream containing the raw bytes of the embedded DEX file at the given index.

GetEntries()

Returns the list of all logical entries discovered in the container.

GetQuickenTableOffsetForDexIdx(idx)

Returns the per-DEX QuickenTableOffset (the u4 prefix written before each embedded DEX in VDEX 019/021) for the DEX file at the given zero-based index.

GetQuickeningInfoBlob()

Returns the raw bytes of the quickening info section, or empty bytes when none is present.

GetQuickeningInfoForCDEX(cdex_stream)

Convenience entry point used by child CDEX scan providers.

GetQuickeningInfoSize()

Returns the size in bytes of the quickening info section.

GetVerifierDepsSize()

Returns the size in bytes of the verifier dependencies blob.

GetVersion()

Returns the VDEX version string as recorded in the file header.

HasDexSection()

Indicates whether the container carries an actual DEX section with embedded DEX files.

GetChecksum(idx: int)int

Returns the location checksum associated with the DEX file at the given index.

Parameters

idx (int) – The zero-based DEX file index.

Returns

Returns the 32-bit location checksum.

Return type

int

GetDexFile(idx: int)Optional[Pkg.VDEX.VDEXEntry]

Returns the VDEXEntry describing the embedded DEX file at the given index.

Parameters

idx (int) – The zero-based DEX file index.

Returns

Returns the entry if the index is valid; otherwise returns None.

Return type

Optional[VDEXEntry]

See also GetDexFileData().

GetDexFileCount()int

Returns the number of embedded DEX (or CompactDex) files.

For VDEX files that carry only verifier dependencies and no DEX section (e.g. 019/021 with an empty dex section) this returns 0.

Returns

Returns the number of embedded DEX files.

Return type

int

GetDexFileData(idx: int)Pro.Core.NTContainer

Returns a stream containing the raw bytes of the embedded DEX file at the given index.

Parameters

idx (int) – The zero-based DEX file index.

Returns

Returns the DEX data if successful; otherwise returns an invalid container.

Return type

NTContainer

See also GetDexFile().

GetEntries()List[Pkg.VDEX.VDEXEntry]

Returns the list of all logical entries discovered in the container.

Entries cover every region of the file — header, checksums, dex section header, embedded DEX files, verifier dependencies, quickening info, boot classpath checksums, class loader context, type lookup tables and version-specific section tables — depending on what the container actually contains.

Returns

Returns the list of entries.

Return type

List[VDEXEntry]

GetQuickenTableOffsetForDexIdx(idx: int)Optional[int]

Returns the per-DEX QuickenTableOffset (the u4 prefix written before each embedded DEX in VDEX 019/021) for the DEX file at the given zero-based index. Returns None for VDEX versions that do not carry per-DEX quicken tables (006/010/027) or when the index is out of range.

Parameters

idx (int) – The zero-based DEX file index.

Returns

Returns the quicken table offset, or None.

Return type

Optional[int]

GetQuickeningInfoBlob()bytes

Returns the raw bytes of the quickening info section, or empty bytes when none is present.

Returns

Returns the quickening info bytes.

Return type

bytes

GetQuickeningInfoForCDEX(cdex_stream: Pro.Core.NTContainer)Optional[Any]

Convenience entry point used by child CDEX scan providers. Identifies which embedded DEX the given stream represents (by header comparison), then returns a (blob_bytes, quicken_table_offset) tuple suitable for passing to Pkg.CDEX.CDEXObject.ConvertToDEX(). Returns None when no quickening information is available.

Parameters

cdex_stream (NTContainer) – A stream pointing to the embedded CDEX bytes.

Returns

Returns the (blob, quicken_table_offset) tuple, or None.

Return type

Optional[Any]

GetQuickeningInfoSize()int

Returns the size in bytes of the quickening info section.

This section is only populated for VDEX 006/010/019/021 files that embed a DEX section; for VDEX 027 and for deps-only containers this returns 0.

Returns

Returns the quickening info size.

Return type

int

GetVerifierDepsSize()int

Returns the size in bytes of the verifier dependencies blob.

Returns

Returns the verifier dependencies size.

Return type

int

GetVersion()str

Returns the VDEX version string as recorded in the file header.

The returned string is one of "006", "010", "019", "021" or "027".

Returns

Returns the VDEX version string.

Return type

str

HasDexSection()bool

Indicates whether the container carries an actual DEX section with embedded DEX files.

Verifier-deps-only VDEX files (produced for the boot image on Android 9+) report False.

Returns

Returns True if a DEX section is present; otherwise returns False.

Return type

bool