shared/DexDefs.h (164 lines of code) (raw):

/* * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ #pragma once #include <cstdint> #include "Util.h" /* * The the dex spec can be found here: * https://source.android.com/devices/tech/dalvik/dex-format.html * * The values here can be found within the spec. Naming is * kept close enough so that you should be able to search * the spec for the variable name. * */ #define DEX_HEADER_DEXMAGIC_V35 "dex\n035" #define DEX_HEADER_DEXMAGIC_V37 "dex\n037" #define DEX_HEADER_DEXMAGIC_V38 "dex\n038" #define DEX_HEADER_DEXMAGIC_V39 "dex\n039" #define ENDIAN_CONSTANT (0x12345678) #define REVERSE_ENDIAN_CONSTANT (0x78563412) /* clang-format off */ #define TYPE_HEADER_ITEM (0x0000) #define TYPE_STRING_ID_ITEM (0x0001) #define TYPE_TYPE_ID_ITEM (0x0002) #define TYPE_PROTO_ID_ITEM (0x0003) #define TYPE_FIELD_ID_ITEM (0x0004) #define TYPE_METHOD_ID_ITEM (0x0005) #define TYPE_CLASS_DEF_ITEM (0x0006) #define TYPE_CALL_SITE_ID_ITEM (0x0007) #define TYPE_METHOD_HANDLE_ITEM (0x0008) #define TYPE_MAP_LIST (0x1000) #define TYPE_TYPE_LIST (0x1001) #define TYPE_ANNOTATION_SET_REF_LIST (0x1002) #define TYPE_ANNOTATION_SET_ITEM (0x1003) #define TYPE_CLASS_DATA_ITEM (0x2000) #define TYPE_CODE_ITEM (0x2001) #define TYPE_STRING_DATA_ITEM (0x2002) #define TYPE_DEBUG_INFO_ITEM (0x2003) #define TYPE_ANNOTATION_ITEM (0x2004) #define TYPE_ENCODED_ARRAY_ITEM (0x2005) #define TYPE_ANNOTATIONS_DIR_ITEM (0x2006) #define TYPE_HIDDENAPI_CLASS_DATA_ITEM (0xF000) enum MethodHandleType { // Method handle is a static field setter (accessor) METHOD_HANDLE_TYPE_STATIC_PUT = 0x00, // Method handle is a static field getter (accessor) METHOD_HANDLE_TYPE_STATIC_GET = 0x01, // Method handle is an instance field setter (accessor) METHOD_HANDLE_TYPE_INSTANCE_PUT = 0x02, // Method handle is an instance field getter (accessor) METHOD_HANDLE_TYPE_INSTANCE_GET = 0x03, // Method handle is a static method invoker METHOD_HANDLE_TYPE_INVOKE_STATIC = 0x04, // Method handle is an instance method invoker METHOD_HANDLE_TYPE_INVOKE_INSTANCE = 0x05, // Method handle is a constructor method invoker METHOD_HANDLE_TYPE_INVOKE_CONSTRUCTOR = 0x06, // Method handle is a direct method invoker METHOD_HANDLE_TYPE_INVOKE_DIRECT = 0x07, // Method handle is an interface method invoker METHOD_HANDLE_TYPE_INVOKE_INTERFACE = 0x08 }; /* clang-format on */ #define type_id_item uint32_t #define string_id_item uint32_t /* * This header exists at the beginning of a non-optimized dex. The checking * we do on this has to do with making sure we're working on a non-opt * dex. See link to Dalvik Executable Format above. */ PACKED(struct dex_header { char magic[8]; uint32_t checksum; uint8_t signature[20]; uint32_t file_size; uint32_t header_size; uint32_t endian_tag; uint32_t link_size; uint32_t link_off; uint32_t map_off; uint32_t string_ids_size; uint32_t string_ids_off; uint32_t type_ids_size; uint32_t type_ids_off; uint32_t proto_ids_size; uint32_t proto_ids_off; uint32_t field_ids_size; uint32_t field_ids_off; uint32_t method_ids_size; uint32_t method_ids_off; uint32_t class_defs_size; uint32_t class_defs_off; uint32_t data_size; uint32_t data_off; }); PACKED(struct dex_string_id { uint32_t offset; }); PACKED(struct dex_type_id { uint32_t string_idx; }); PACKED(struct dex_map_item { uint16_t type; uint16_t na /* Not used */; uint32_t size /* Item count, not byte size */; uint32_t offset /* From start of file */; }); PACKED(struct dex_map_list { uint32_t size; /* Number of items below */ dex_map_item items[]; }); #define DEX_NO_INDEX (0xffffffff) PACKED(struct dex_class_def { uint32_t typeidx; uint32_t access_flags; uint32_t super_idx; uint32_t interfaces_off; uint32_t source_file_idx; uint32_t annotations_off; uint32_t class_data_offset; uint32_t static_values_off; }); PACKED(struct dex_method_id { uint16_t classidx; uint16_t protoidx; uint32_t nameidx; }); PACKED(struct dex_field_id { uint16_t classidx; uint16_t typeidx; uint32_t nameidx; }); PACKED(struct dex_proto_id { uint32_t shortyidx; uint32_t rtypeidx; uint32_t param_off; }); PACKED(struct dex_callsite_id { uint32_t callsite_off; }); PACKED(struct dex_methodhandle_id { uint16_t method_handle_type; uint16_t unused1; uint16_t field_or_method_id; uint16_t unused2; }); PACKED(struct dex_field_annotation { uint32_t field_idx; uint32_t annotations_off; }); PACKED(struct dex_method_annotation { uint32_t method_idx; uint32_t annotations_off; }); PACKED(struct dex_parameter_annotation { uint32_t method_idx; uint32_t annotations_off; }); PACKED(struct dex_type_item { uint16_t type_idx; }); PACKED(struct dex_annotation_set_ref_item { uint32_t annotations_off; }); PACKED(struct dex_annotation_off_item { uint32_t annotation_off; }); PACKED(struct dex_code_item { uint16_t registers_size; uint16_t ins_size; uint16_t outs_size; uint16_t tries_size; uint32_t debug_info_off; uint32_t insns_size; }); PACKED(struct dex_tries_item { uint32_t start_addr; uint16_t insn_count; uint16_t handler_off; }); PACKED(struct dex_annotations_directory_item { uint32_t class_annotations_off; uint32_t fields_size; uint32_t methods_size; uint32_t parameters_size; }); /* clang-format off */ using DexDebugItemOpcode = uint8_t; enum DexDebugItemOpcodeValues : uint8_t { DBG_END_SEQUENCE = 0x00, DBG_ADVANCE_PC = 0x01, DBG_ADVANCE_LINE = 0x02, DBG_START_LOCAL = 0x03, DBG_START_LOCAL_EXTENDED = 0x04, DBG_END_LOCAL = 0x05, DBG_RESTART_LOCAL = 0x06, DBG_SET_PROLOGUE_END = 0x07, DBG_SET_EPILOGUE_BEGIN = 0x08, DBG_SET_FILE = 0x09 }; /* clang-format on */ constexpr int32_t DBG_FIRST_SPECIAL = 0x0a; constexpr int32_t DBG_LAST_SPECIAL = 0xff; constexpr int32_t DBG_LINE_BASE = -4; constexpr int32_t DBG_LINE_RANGE = 15;