CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-lief

Library to instrument executable formats including ELF, PE, Mach-O, and Android formats

Pending
Overview
Eval results
Files

android-formats.mddocs/

Android Formats

Specialized support for Android application formats including DEX bytecode, ART runtime files, OAT optimized executables, and VDEX verification data. These formats enable analysis of Android applications, runtime optimization, and security research.

Capabilities

Format Detection

Identify Android-specific formats for proper parsing and analysis.

def is_dex(file: Union[str, Sequence[int]]) -> bool:
    """Check if file is DEX format."""
    
def is_art(file: Union[str, Sequence[int]]) -> bool:
    """Check if file is ART format."""
    
def is_oat(file: Union[str, Sequence[int], ELF.Binary]) -> bool:
    """Check if file is OAT format."""
    
def is_vdex(file: Union[str, Sequence[int]]) -> bool:
    """Check if file is VDEX format."""

Usage example:

import lief

# Check Android format types
apk_dex = "/data/app/com.example.app/base.apk!/classes.dex"
if lief.is_dex(apk_dex):
    print("DEX file detected")

oat_file = "/data/dalvik-cache/arm64/system@framework@boot.oat"
if lief.is_oat(oat_file):
    print("OAT file detected")

art_file = "/data/dalvik-cache/arm64/system@framework@boot.art"
if lief.is_art(art_file):
    print("ART file detected")

Android Version Support

Identify and work with different Android API versions and their characteristics.

class ANDROID_VERSIONS(enum.Enum):
    UNKNOWN = 0
    VERSION_601 = 1  # Android 6.0.1
    VERSION_700 = 2  # Android 7.0
    VERSION_710 = 3  # Android 7.1.0
    VERSION_712 = 4  # Android 7.1.2
    VERSION_800 = 5  # Android 8.0
    VERSION_810 = 6  # Android 8.1
    VERSION_900 = 7  # Android 9.0

def code_name(version: ANDROID_VERSIONS) -> str:
    """Get Android codename for version."""
    
def version_string(version: ANDROID_VERSIONS) -> str:
    """Get version string for Android version."""

Usage example:

import lief.Android as Android

# Work with Android versions
version = Android.ANDROID_VERSIONS.VERSION_900
print(f"Codename: {Android.code_name(version)}")
print(f"Version: {Android.version_string(version)}")

# Map all versions
for version in Android.ANDROID_VERSIONS:
    if version != Android.ANDROID_VERSIONS.UNKNOWN:
        codename = Android.code_name(version)
        version_str = Android.version_string(version)
        print(f"{version_str} ({codename})")

DEX Format Analysis

Analyze DEX (Dalvik Executable) files containing Android application bytecode.

# Access through lief.DEX module
import lief.DEX as DEX

def parse(file: Union[str, bytes, io.IOBase]) -> Optional[File]

class File:
    header: Header
    classes: Iterator[Class]
    methods: Iterator[Method]
    strings: Iterator[str]
    types: Iterator[Type]
    fields: Iterator[Field]
    prototypes: Iterator[Prototype]
    
class Header:
    magic: bytes
    version: int
    checksum: int
    signature: bytes
    file_size: int
    header_size: int
    link_size: int
    link_offset: int
    map_offset: int
    strings_offset: int
    types_offset: int
    prototypes_offset: int
    fields_offset: int
    methods_offset: int
    classes_offset: int
    data_size: int
    data_offset: int
    
class Class:
    fullname: str
    package_name: str
    name: str
    pretty_name: str
    access_flags: int
    parent: Optional[Class]
    source_filename: str
    methods: Iterator[Method]
    fields: Iterator[Field]
    
class Method:
    name: str
    index: int
    pretty_name: str
    access_flags: int
    code_offset: int
    prototype: Prototype
    
class Field:
    name: str
    index: int
    access_flags: int
    type: Type
    
class Type:
    type: str
    dim: int
    
class Prototype:
    return_type: Type
    parameters_type: List[Type]

DEX files contain the compiled Java bytecode for Android applications. They include:

  • Class definitions: Java classes compiled to Dalvik bytecode
  • Method signatures: Function definitions and implementations
  • String constants: All string literals used in the application
  • Type definitions: Class and primitive type information
  • Field definitions: Class member variables and their types

Usage example:

import lief.DEX as DEX

# Parse DEX file from APK
dex_binary = DEX.parse("classes.dex")
if dex_binary:
    print("DEX file parsed successfully")
    # DEX-specific analysis would be available through dex_binary object

ART Format Analysis

Analyze ART (Android Runtime) files used for ahead-of-time compilation.

# Access through lief.ART module
import lief.ART as ART

def parse(file: Union[str, bytes, io.IOBase]) -> Optional[File]

class File:
    header: Header
    
class Header:
    magic: bytes
    version: str
    image_base: int
    image_size: int
    image_methods_offset: int
    image_methods_count: int
    image_roots_offset: int
    oat_checksum: int
    oat_file_begin: int
    oat_data_begin: int
    oat_data_end: int
    oat_file_end: int
    boot_image_begin: int
    boot_image_size: int
    boot_oat_begin: int
    boot_oat_size: int
    patch_delta: int
    image_roots_size: int
    pointer_size: int
    compile_pic: bool
    is_pic: bool
    storage_mode: int
    data_size: int

ART files are used by the Android Runtime for ahead-of-time (AOT) compilation:

  • Compiled code: Native machine code compiled from DEX bytecode
  • Runtime metadata: Information needed for execution and garbage collection
  • Object layouts: Memory layout information for Java objects
  • Method information: Mapping between DEX methods and compiled code

Usage example:

import lief.ART as ART

# Parse ART file
art_binary = ART.parse("boot.art")
if art_binary:
    print("ART file parsed successfully")
    # ART-specific analysis would be available

OAT Format Analysis

Analyze OAT (Optimized Android executables) files containing compiled DEX code.

# Access through lief.OAT module (OAT files are ELF-based)
import lief.OAT as OAT

def parse(file: Union[str, bytes, io.IOBase]) -> Optional[Binary]

class Binary(lief.ELF.Binary):
    header: Header
    dex_files: Iterator[DexFile]
    classes: Iterator[Class]
    methods: Iterator[Method]
    
class Header:
    magic: bytes
    version: str
    adler32_checksum: int
    instruction_set: INSTRUCTION_SETS
    instruction_set_features: int
    dex_file_count: int
    executable_offset: int
    interpreter_to_interpreter_bridge_offset: int
    interpreter_to_compiled_code_bridge_offset: int
    jni_dlsym_lookup_offset: int
    quick_generic_jni_trampoline_offset: int
    quick_imt_conflict_trampoline_offset: int
    quick_resolution_trampoline_offset: int
    quick_to_interpreter_bridge_offset: int
    image_patch_delta: int
    image_file_location_oat_checksum: int
    image_file_location_oat_data_begin: int
    key_value_size: int
    
class DexFile:
    location: str
    checksum: int
    dex_file_offset: int
    classes_offsets: List[int]
    lookup_table_offset: int
    
class Class:
    status: int
    type: str
    bitmap: List[int]
    methods: Iterator[Method]
    
class Method:
    native_method_addr: int
    native_quick_generic_jni_trampoline: int
    native_quick_to_interpreter_bridge: int
    
enum INSTRUCTION_SETS:
    NONE = 0
    ARM = 1
    ARM64 = 2
    X86 = 3
    X86_64 = 4
    MIPS = 5
    MIPS64 = 6

OAT files are ELF files with Android-specific extensions:

  • ELF structure: Standard ELF format with additional sections
  • Compiled DEX code: Native code compiled from DEX bytecode
  • DEX file embedding: Original DEX files embedded within OAT
  • Runtime information: Data needed for execution and optimization

Usage example:

import lief.ELF as ELF

# OAT files are ELF files, so parse with ELF module
oat_binary = ELF.parse("boot.oat")
if oat_binary and lief.is_oat(oat_binary):
    print("OAT file parsed as ELF")
    
    # Look for Android-specific sections
    for section in oat_binary.sections:
        if section.name.startswith(".oat"):
            print(f"OAT section: {section.name}")

VDEX Format Analysis

Analyze VDEX (Verified DEX) files containing verification and optimization data.

# Access through lief.VDEX module
import lief.VDEX as VDEX

def parse(file: Union[str, bytes, io.IOBase]) -> Optional[File]

class File:
    header: Header
    dex_files: Iterator[DEX.File]
    
class Header:
    magic: bytes
    version: str
    number_of_dex_files: int
    dex_size: int
    dex_shared_data_size: int
    quickening_info_size: int
    verifier_deps_size: int
    bootclasspath_checksums_size: int

VDEX files contain verification and optimization data:

  • Verification data: Information about DEX file verification status
  • Optimization information: Data for runtime optimizations
  • DEX contents: The original DEX file data
  • Dependencies: Information about class dependencies and loading

Usage example:

import lief.VDEX as VDEX

# Parse VDEX file
vdex_binary = VDEX.parse("base.vdex")
if vdex_binary:
    print("VDEX file parsed successfully")
    # VDEX-specific analysis would be available

APK Analysis Integration

Integrate Android format analysis with APK (Android Package) files.

# APK files are ZIP archives containing:
# - classes.dex (DEX files)
# - AndroidManifest.xml  
# - Resources (res/)
# - Native libraries (lib/)
# - Assets (assets/)

APK files can be analyzed by extracting their components:

Usage example:

import zipfile
import lief

def analyze_apk(apk_path):
    """Analyze Android APK file contents."""
    with zipfile.ZipFile(apk_path, 'r') as apk:
        # List all files
        print("APK contents:")
        for file_info in apk.filelist:
            print(f"  {file_info.filename}")
            
        # Analyze DEX files
        for filename in apk.namelist():
            if filename.endswith('.dex'):
                print(f"Found DEX file: {filename}")
                dex_data = apk.read(filename)
                if lief.is_dex(dex_data):
                    print(f"  Valid DEX file: {len(dex_data)} bytes")
                    
        # Check for native libraries
        native_libs = [f for f in apk.namelist() if f.startswith('lib/')]
        if native_libs:
            print("Native libraries:")
            for lib in native_libs:
                print(f"  {lib}")
                lib_data = apk.read(lib)
                if lief.is_elf(lib_data):
                    elf_binary = lief.ELF.parse(lib_data)
                    if elf_binary:
                        print(f"    ELF: {elf_binary.header.machine_type}")

# Usage
analyze_apk("app.apk")

Runtime Analysis Support

Support for analyzing Android runtime environments and optimization.

DEX Optimization Process:

  1. DEX files are packaged in APK
  2. VDEX files contain verification data
  3. OAT files contain compiled native code
  4. ART files contain runtime metadata

Analysis workflow:

def analyze_android_optimization(package_path):
    """Analyze Android app optimization artifacts."""
    
    # Check for different optimization stages
    dex_files = find_dex_files(package_path)
    vdex_files = find_vdex_files(package_path)  
    oat_files = find_oat_files(package_path)
    art_files = find_art_files(package_path)
    
    print(f"Found {len(dex_files)} DEX files")
    print(f"Found {len(vdex_files)} VDEX files")
    print(f"Found {len(oat_files)} OAT files")
    print(f"Found {len(art_files)} ART files")
    
    # Analyze optimization level
    if art_files:
        print("Ahead-of-time (AOT) compilation detected")
    elif oat_files:
        print("Optimized DEX compilation detected")
    elif vdex_files:
        print("Verified DEX files detected")
    else:
        print("Unoptimized DEX files only")

Security Analysis

Android format analysis for security research and malware detection.

Common security analysis tasks:

  • DEX code analysis: Examine Android application logic
  • Native library analysis: Analyze JNI libraries in APKs
  • OAT inspection: Understand runtime optimizations
  • Packing detection: Identify obfuscated or packed applications

Usage example:

def security_analysis(apk_path):
    """Perform security analysis on Android APK."""
    
    with zipfile.ZipFile(apk_path, 'r') as apk:
        # Check for suspicious files
        suspicious_files = []
        
        for filename in apk.namelist():
            # Look for native libraries
            if filename.startswith('lib/') and filename.endswith('.so'):
                lib_data = apk.read(filename)
                if lief.is_elf(lib_data):
                    elf_binary = lief.ELF.parse(lib_data)
                    if elf_binary:
                        # Check for packing indicators
                        if any('upx' in section.name.lower() for section in elf_binary.sections):
                            suspicious_files.append(f"{filename}: UPX packed")
                            
                        # Check for anti-debugging
                        if elf_binary.has_symbol("ptrace"):
                            suspicious_files.append(f"{filename}: ptrace usage")
            
            # Analyze DEX files
            elif filename.endswith('.dex'):
                dex_data = apk.read(filename)
                if lief.is_dex(dex_data):
                    # DEX-specific security checks would go here
                    print(f"Analyzing DEX: {filename}")
        
        if suspicious_files:
            print("Suspicious indicators found:")
            for indicator in suspicious_files:
                print(f"  {indicator}")

Types

# Android-specific enumerations and constants

enum ANDROID_VERSIONS:
    UNKNOWN = 0
    VERSION_601 = 1  # Marshmallow 6.0.1
    VERSION_700 = 2  # Nougat 7.0
    VERSION_710 = 3  # Nougat 7.1.0  
    VERSION_712 = 4  # Nougat 7.1.2
    VERSION_800 = 5  # Oreo 8.0
    VERSION_810 = 6  # Oreo 8.1
    VERSION_900 = 7  # Pie 9.0

# DEX file format constants
DEX_FILE_MAGIC = "dex\n"
DEX_FILE_VERSION_035 = "035\0"
DEX_FILE_VERSION_037 = "037\0"
DEX_FILE_VERSION_038 = "038\0"
DEX_FILE_VERSION_039 = "039\0"

# OAT file format constants  
OAT_MAGIC = "oat\n"
OAT_VERSION_MINIMUM = "045"
OAT_VERSION_MAXIMUM = "199"

# ART file format constants
ART_MAGIC = "art\n"

# VDEX file format constants
VDEX_MAGIC = "vdex"

Install with Tessl CLI

npx tessl i tessl/pypi-lief

docs

android-formats.md

assembly-engine.md

core-operations.md

debug-info.md

elf-format.md

extended-features.md

index.md

macho-format.md

pe-format.md

tile.json