DexTrace is organized as a small public API and CLI layer on top of internal parsing and decoding modules.
At a high level, the repository is split into:
- public API and CLI entry points
- APK / DEX parsing core
- API extraction and reference resolution
- Dalvik bytecode disassembly internals
- binary manifest parsing
- pytest-based tests and fixtures
This document explains the role of each Python module currently present in the repository.
Public Python-facing entry point for programmatic use of DexTrace functionality.
Use this module when integrating DexTrace into other Python workflows instead of invoking the CLI directly.
Top-level CLI dispatcher.
Responsible for wiring subcommands and handing control to command-specific modules.
CLI command for APK / manifest metadata-oriented output.
Used when inspecting package metadata, manifest-derived information, or other high-level APK facts.
CLI command focused on disassembly-oriented workflows.
Used when instruction-level or smali-like output is needed for debugging and parser verification.
CLI command for DEX/API-oriented workflows.
Used when inspecting DEX content, extracted references, or API-level evidence from bytecode.
CLI command implementing dextrace run.
Loads a DEX (or the DEX embedded in an APK), builds the method map, and executes a
single entry method on the Dalvik VM (src/dextrace/vm/), printing the return value,
optional call tree, and optional registers.
Shared input-loading helper for CLI subcommands.
Provides load_dex_bytes, which loads DEX bytes from a .dex file or extracts
classes.dex from an .apk, so each command does not re-implement input handling.
Package marker for CLI modules.
Reads APK archive contents.
Acts as a lower-level APK access layer used by metadata extraction, manifest parsing, and DEX loading workflows.
Extracts high-level APK metadata.
Typical outputs include package-level metadata derived from the APK and manifest.
Main DEX parsing entry point.
Coordinates reading of DEX structures and provides parsed data needed by downstream extraction and analysis.
Parses and represents DEX header information.
Useful when validating offsets, section sizes, and overall structural correctness of a DEX file.
Handles DEX string table parsing and lookup.
Provides string resolution support for other parsed tables and decoded references.
Handles DEX prototype table parsing.
Used for method signature and descriptor-related resolution.
Handles DEX method table parsing.
Provides method identity and indexing information used throughout DEX analysis.
Maps parsed methods to code items or code-related structures.
Supports downstream workflows that need to connect method definitions with instruction streams.
Shared iteration over DEX class_def and encoded_method structures.
Walks class definitions without going through the full dex_code_map.py pipeline; used
by the VM's class_hierarchy.py vtable builder and other class-walking code.
Extracts API usage evidence from parsed DEX methods.
This is one of the most important Quark-facing modules because it turns raw method/code content into extracted invoke/API facts that can later be consumed by higher-level rule engines.
Resolves method or API references from parsed DEX data.
Used to convert lower-level parsed indices or references into more meaningful method/API identities.
Higher-level manifest parsing bridge.
Works with the low-level binary manifest parser to produce usable manifest information for the rest of the project.
Package marker for core modules.
Utility for file hashing.
Useful for sample tracking, reproducibility notes, or identifying analysis inputs consistently.
Package marker for core utilities.
Abstraction for bytecode input sources.
Helps unify how raw instruction bytes are supplied to decoding and disassembly logic.
Primary Dalvik disassembly engine.
Transforms parsed bytecode into decoded instructions or instruction-oriented output used for debugging and verification.
Infers instruction size from opcode format rules.
Important for reliable instruction boundary handling.
Defines or exposes opcode format metadata.
Acts as a reference source for operand decoding and instruction size logic.
Builds opcode lookup tables from underlying opcode definitions.
Supports deterministic and testable opcode metadata construction.
Decodes instruction operands from raw Dalvik bytecode.
A critical low-level component for correct disassembly and invoke extraction.
Handles payload-style instructions.
This includes instruction forms that need specialized decoding beyond ordinary opcode handling.
Resolves or normalizes instruction size behavior.
Closely related to bytecode traversal correctness.
Smali-related helpers or formatting support.
Used when rendering or reasoning about disassembled instruction output in a smali-adjacent representation.
Shared type definitions or structures for Dalvik-related logic.
Provides consistency across disassembler and decoder internals.
Package marker for Dalvik modules.
Package marker for bundled data resources used by Dalvik internals.
The src/dextrace/vm/ package executes Dalvik bytecode (dynamic analysis). This is
distinct from src/dextrace/dalvik/, which only decodes and disassembles instructions.
It is the subsystem behind the dextrace run command.
DalvikVM, the iterative execution engine. Drives the instruction loop, invoke
resolution, handler/stub dispatch, try/catch handling, and trace emission.
Static-walk adapter that yields a method's decoded instructions for the engine.
Raises MethodNotFound / DexParseError (walk_method).
VMState: the mutable execution state carried through the instruction loop.
RegisterFile: the Dalvik register file for a frame.
CallFrame: caller state saved at invoke time so execution can resume after a call.
Object heap mapping integer handles to HeapEntry records (ObjectHeap).
ClassHierarchy: vtable construction and virtual method resolution.
32/64-bit integer and IEEE 754 float/double helpers used by the arithmetic handlers.
Internal exception-flow signals raised by handlers (_ThrowSignal).
Execution tracing: per-instruction TraceStep / ExecutionTrace and the
CallNode / CallTreeTrace call-tree representation.
VM exception hierarchy (DexTraceVMError, DexTraceNotImplementedError, and Java-style
exceptions such as NullPointerException, ArithmeticException, ClassCastException).
Package marker for VM modules.
Each handler module registers the opcodes it implements with the engine.
arithmetic.py: integer/long/float/double arithmetic instructionsarray.py: array creation and element accessbranch.py: conditional branch andgotoinstructionscompare.py:cmp*comparison instructionsfield.py: instance and static field accessmove.py:move,const, andmove-result/move-exceptioninstructionsthrow.py: thethrow vAAopcodetype_check.py:check-cast,instance-of,monitor-enter,monitor-exittype_conv.py: numeric type-conversion instructions__init__.py: package marker for handler modules
Simulated Android/Java framework methods so framework-dependent code can run without a
device. __init__.py is the stub registry and shared value types (StubResult, Value,
Wide, ObjectRef).
content.py:ContentProvider/ContentResolverand network connectivity stubsfilesystem.py: file I/O, Android UI, network extras, andStringhelpersintent.py:Intent,Bundle, andContextstubsnetwork.py: Java networking stubs (URL/HttpURLConnection/streams)runtime.py:Runtime,Process,SharedPreferences, and system stubssms.py:SmsManagerstubstelephony.py: telephony /SmsMessagestubstext.py:java.lang/java.utilstubs (StringBuilder,String, date formatting)
Low-level binary AndroidManifest AXML parser.
This module is the foundation for manifest decoding and is typically used indirectly via core/manifest_parser.py.
Package marker for manifest modules.
Shared error and exception definitions.
Use this module when standardizing project-specific failure modes.
Package version information.
Top-level package marker and package exports.
The test suite is organized by subsystem. Contributors should treat tests as the main executable specification for current behavior.
Shared pytest fixtures and configuration.
Synthetic DEX fixture builder used by tests.
This is especially useful when adding deterministic parser or disassembler regression coverage without relying entirely on external samples.
Package marker for fixtures.
Covers CLI metadata behavior.
Smoke coverage for basic package functionality.
Coverage for APK archive reading behavior.
Coverage for APK metadata extraction.
Coverage for higher-level manifest parsing behavior.
Coverage for DEX parser behavior.
Coverage for DEX header parsing.
Parser-level coverage for try_item and encoded_catch_handler decoding (try/catch
region and typed catch handlers).
Validates synthetic DEX fixture behavior.
Coverage for API extraction behavior and a key place to add regression tests when Quark-facing API evidence changes.
Coverage for operand decoding.
Coverage for instruction size resolution.
Coverage for opcode lookup table construction.
Coverage for instruction size inference correctness.
End-to-end disassembly coverage using synthetic DEX input.
Evidence-oriented disassembly checks tied to expected instruction representations.
Coverage for payload-style instruction handling.
Checks format inference coverage.
Coverage based on generated bytecode vectors.
End-to-end coverage for the Dalvik VM (src/dextrace/vm/) and dextrace run. Most are
named tests/test_vm_run_*.py and execute a small synthetic method to assert a result:
tests/test_vm_run_const_return.py, tests/test_vm_run_fibonacci.py, tests/test_vm_run_long_arithmetic.py
Arithmetic, constants, recursion, and wide (long) value handling.
tests/test_vm_run_arrays.py, tests/test_vm_run_instance_fields.py, tests/test_vm_run_packed_switch.py
Array operations, instance field access, and packed-switch control flow.
Virtual / interface method dispatch through the class hierarchy.
tests/test_vm_run_try_catch.py, tests/test_vm_run_try_catch_with_fields.py, tests/test_vm_run_try_catch_with_stubs.py
Exception flow, including interaction with fields and Android API stubs.
Null-receiver handling and the move-result pending-result lifecycle.
Additional VM-focused tests and fixtures.
Run the VM tests with pytest -k vm.
Use this document to answer three common contributor questions.
Start with:
README.mdsrc/dextrace/api.pysrc/dextrace/cli/main.py- the relevant subsystem in
src/dextrace/core/,dalvik/,vm/, ormanifest/
Map the problem to a subsystem first:
- metadata problem →
apk_reader.py,apk_metadata.py - manifest problem →
manifest_parser.py,axml_parser.py - DEX structure problem →
dex_parser.py, related core tables - API extraction problem →
dex_api_extractor.py,dex_resolver.py - instruction/disassembly problem →
dalvik/ - VM execution /
dextrace runproblem →src/dextrace/vm/,src/dextrace/cli/cmd_run.py
Run the narrowest relevant subsystem tests first, then broaden if needed.
- VM execution changes →
pytest -k vm