1 // Copyright 2018 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef COMPONENTS_ZUCCHINI_TYPE_DEX_H_ 6 #define COMPONENTS_ZUCCHINI_TYPE_DEX_H_ 7 8 #include <stdint.h> 9 10 namespace zucchini { 11 namespace dex { 12 // Contains types that models DEX executable format data structures. 13 // See https://source.android.com/devices/tech/dalvik/dex-format 14 15 // The supported versions are 035, 037, 038, and 039. 16 17 enum class FormatId : uint8_t { 18 b, // 22b. 19 c, // 21c, 22c, 31c, 35c, 3rc, 45cc, 4rcc. 20 h, // 21h. 21 i, // 31i. 22 l, // 51l. 23 n, // 11n. 24 s, // 21s, 22s. 25 t, // 10t, 20t, 21t, 22t, 30t, 31t. 26 x, // 10x, 11x, 12x, 22x, 23x, 32x. 27 }; 28 29 struct Instruction { 30 Instruction() = default; 31 constexpr Instruction(uint8_t opcode_in, 32 uint8_t layout_in, 33 FormatId format_in, 34 uint8_t variant_in = 1) opcodeInstruction35 : opcode(opcode_in), 36 layout(layout_in), 37 format(format_in), 38 variant(variant_in) {} 39 40 // The opcode that identifies the instruction. 41 uint8_t opcode; 42 // Number of uint16_t units for the instruction. 43 uint8_t layout; 44 // Identifier that groups similar instructions, as quick filter. 45 FormatId format; 46 // Number of successive opcodes that have the same format. 47 uint8_t variant = 1; 48 }; 49 50 constexpr Instruction kByteCode[] = { 51 {0x00, 1, FormatId::x}, 52 {0x01, 1, FormatId::x}, 53 {0x02, 2, FormatId::x}, 54 {0x03, 3, FormatId::x}, 55 {0x04, 1, FormatId::x}, 56 {0x05, 2, FormatId::x}, 57 {0x06, 3, FormatId::x}, 58 {0x07, 1, FormatId::x}, 59 {0x08, 2, FormatId::x}, 60 {0x09, 3, FormatId::x}, 61 {0x0A, 1, FormatId::x}, 62 {0x0B, 1, FormatId::x}, 63 {0x0C, 1, FormatId::x}, 64 {0x0D, 1, FormatId::x}, 65 {0x0E, 1, FormatId::x}, 66 {0x0F, 1, FormatId::x}, 67 {0x10, 1, FormatId::x}, 68 {0x11, 1, FormatId::x}, 69 {0x12, 1, FormatId::n}, 70 {0x13, 2, FormatId::s}, 71 {0x14, 3, FormatId::i}, 72 {0x15, 2, FormatId::h}, 73 {0x16, 2, FormatId::s}, 74 {0x17, 3, FormatId::i}, 75 {0x18, 5, FormatId::l}, 76 {0x19, 2, FormatId::h}, 77 {0x1A, 2, FormatId::c}, 78 {0x1B, 3, FormatId::c}, 79 {0x1C, 2, FormatId::c}, 80 {0x1D, 1, FormatId::x}, 81 {0x1E, 1, FormatId::x}, 82 {0x1F, 2, FormatId::c}, 83 {0x20, 2, FormatId::c}, 84 {0x21, 1, FormatId::x}, 85 {0x22, 2, FormatId::c}, 86 {0x23, 2, FormatId::c}, 87 {0x24, 3, FormatId::c}, 88 {0x25, 3, FormatId::c}, 89 {0x26, 3, FormatId::t}, 90 {0x27, 1, FormatId::x}, 91 {0x28, 1, FormatId::t}, 92 {0x29, 2, FormatId::t}, 93 {0x2A, 3, FormatId::t}, 94 {0x2B, 3, FormatId::t}, 95 {0x2C, 3, FormatId::t}, 96 {0x2D, 2, FormatId::x, 5}, 97 {0x32, 2, FormatId::t, 6}, 98 {0x38, 2, FormatId::t, 6}, 99 // {0x3E, 1, FormatId::x, 6}, unused 100 {0x44, 2, FormatId::x, 14}, 101 {0x52, 2, FormatId::c, 14}, 102 {0x60, 2, FormatId::c, 14}, 103 {0x6E, 3, FormatId::c, 5}, 104 // {0x73, 1, FormatId::x}, unused 105 {0x74, 3, FormatId::c, 5}, 106 // {0x79, 1, FormatId::x, 2}, unused 107 {0x7B, 1, FormatId::x, 21}, 108 {0x90, 2, FormatId::x, 32}, 109 {0xB0, 1, FormatId::x, 32}, 110 {0xD0, 2, FormatId::s, 8}, 111 {0xD8, 2, FormatId::b, 11}, 112 // {0xE3, 1, FormatId::x, 29}, unused 113 {0xFA, 4, FormatId::c}, 114 {0xFB, 4, FormatId::c}, 115 {0xFC, 3, FormatId::c}, 116 {0xFD, 3, FormatId::c}, 117 {0xFE, 2, FormatId::c}, 118 {0xFF, 2, FormatId::c}, 119 }; 120 121 // Supported by MSVC, g++, and clang++. Ensures no gaps in packing. 122 #pragma pack(push, 1) 123 124 // header_item: Appears in the header section. 125 struct HeaderItem { 126 uint8_t magic[8]; 127 uint32_t checksum; 128 uint8_t signature[20]; 129 uint32_t file_size; 130 uint32_t header_size; 131 uint32_t endian_tag; 132 uint32_t link_size; 133 uint32_t link_off; 134 uint32_t map_off; 135 uint32_t string_ids_size; 136 uint32_t string_ids_off; 137 uint32_t type_ids_size; 138 uint32_t type_ids_off; 139 uint32_t proto_ids_size; 140 uint32_t proto_ids_off; 141 uint32_t field_ids_size; 142 uint32_t field_ids_off; 143 uint32_t method_ids_size; 144 uint32_t method_ids_off; 145 uint32_t class_defs_size; 146 uint32_t class_defs_off; 147 uint32_t data_size; 148 uint32_t data_off; 149 }; 150 151 // string_id_item: String identifiers list. 152 struct StringIdItem { 153 uint32_t string_data_off; 154 }; 155 156 // type_id_item: Type identifiers list. 157 struct TypeIdItem { 158 uint32_t descriptor_idx; 159 }; 160 161 // proto_id_item: Method prototype identifiers list. 162 struct ProtoIdItem { 163 uint32_t shorty_idx; 164 uint32_t return_type_idx; 165 uint32_t parameters_off; 166 }; 167 168 // field_id_item: Field identifiers list. 169 struct FieldIdItem { 170 uint16_t class_idx; 171 uint16_t type_idx; 172 uint32_t name_idx; 173 }; 174 175 // method_id_item: Method identifiers list. 176 struct MethodIdItem { 177 uint16_t class_idx; 178 uint16_t proto_idx; 179 uint32_t name_idx; 180 }; 181 182 // class_def_item: Class definitions list. 183 struct ClassDefItem { 184 uint32_t class_idx; 185 uint32_t access_flags; 186 uint32_t superclass_idx; 187 uint32_t interfaces_off; 188 uint32_t source_file_idx; 189 uint32_t annotations_off; 190 uint32_t class_data_off; 191 uint32_t static_values_off; 192 }; 193 194 // call_site_id_item: Call site identifiers list. 195 struct CallSiteIdItem { 196 uint32_t call_site_off; 197 }; 198 199 // method_handle_type: Determines the behavior of the MethodHandleItem. 200 enum class MethodHandleType : uint16_t { 201 // FieldId 202 kStaticPut = 0x00, 203 kStaticGet = 0x01, 204 kInstancePut = 0x02, 205 kInstanceGet = 0x03, 206 // MethodId 207 kInvokeStatic = 0x04, 208 kInvokeInstance = 0x05, 209 kInvokeConstructor = 0x06, 210 kInvokeDirect = 0x07, 211 kInvokeInterface = 0x08, 212 // Sentinel. If new types are added put them before this and increment. 213 kMaxMethodHandleType = 0x09 214 }; 215 216 // method_handle_item: Method handles referred within the Dex file. 217 struct MethodHandleItem { 218 uint16_t method_handle_type; 219 uint16_t unused_1; 220 uint16_t field_or_method_id; 221 uint16_t unused_2; 222 }; 223 224 // code_item: Header of a code item. 225 struct CodeItem { 226 uint16_t registers_size; 227 uint16_t ins_size; 228 uint16_t outs_size; 229 uint16_t tries_size; 230 uint32_t debug_info_off; 231 uint32_t insns_size; 232 // Variable length data follow for complete code item. 233 }; 234 235 // Number of valid type codes for map_item elements in map_list. 236 // See: https://source.android.com/devices/tech/dalvik/dex-format#type-codes 237 constexpr uint32_t kMaxItemListSize = 21; 238 239 constexpr uint16_t kTypeHeaderItem = 0x0000; 240 constexpr uint16_t kTypeStringIdItem = 0x0001; 241 constexpr uint16_t kTypeTypeIdItem = 0x0002; 242 constexpr uint16_t kTypeProtoIdItem = 0x0003; 243 constexpr uint16_t kTypeFieldIdItem = 0x0004; 244 constexpr uint16_t kTypeMethodIdItem = 0x0005; 245 constexpr uint16_t kTypeClassDefItem = 0x0006; 246 constexpr uint16_t kTypeCallSiteIdItem = 0x0007; 247 constexpr uint16_t kTypeMethodHandleItem = 0x0008; 248 constexpr uint16_t kTypeMapList = 0x1000; 249 constexpr uint16_t kTypeTypeList = 0x1001; 250 constexpr uint16_t kTypeAnnotationSetRefList = 0x1002; 251 constexpr uint16_t kTypeAnnotationSetItem = 0x1003; 252 constexpr uint16_t kTypeClassDataItem = 0x2000; 253 constexpr uint16_t kTypeCodeItem = 0x2001; 254 constexpr uint16_t kTypeStringDataItem = 0x2002; 255 constexpr uint16_t kTypeDebugInfoItem = 0x2003; 256 constexpr uint16_t kTypeAnnotationItem = 0x2004; 257 constexpr uint16_t kTypeEncodedArrayItem = 0x2005; 258 constexpr uint16_t kTypeAnnotationsDirectoryItem = 0x2006; 259 constexpr uint16_t kTypeHiddenApiClassDataItem = 0xF000; 260 261 // map_item 262 struct MapItem { 263 uint16_t type; 264 uint16_t unused; 265 uint32_t size; 266 uint32_t offset; 267 }; 268 269 // map_list 270 struct MapList { 271 uint32_t size; 272 MapItem list[kMaxItemListSize]; 273 }; 274 275 // type_item 276 struct TypeItem { 277 uint16_t type_idx; 278 }; 279 280 // annotation_set_ref_item 281 struct AnnotationSetRefItem { 282 uint32_t annotations_off; 283 }; 284 285 // annotation_off_item 286 struct AnnotationOffItem { 287 uint32_t annotation_off; 288 }; 289 290 // field_annotation 291 struct FieldAnnotation { 292 uint32_t field_idx; 293 uint32_t annotations_off; 294 }; 295 296 // method_annotation 297 struct MethodAnnotation { 298 uint32_t method_idx; 299 uint32_t annotations_off; 300 }; 301 302 // parameter_annotation 303 struct ParameterAnnotation { 304 uint32_t method_idx; 305 uint32_t annotations_off; 306 }; 307 308 // annotations_directory_item 309 struct AnnotationsDirectoryItem { 310 uint32_t class_annotations_off; 311 uint32_t fields_size; 312 uint32_t annotated_methods_size; 313 uint32_t annotated_parameters_size; 314 // FieldAnnotation field_annotations[fields_size]; 315 // MethodAnnotation method_annotations[annotated_methods_size]; 316 // ParameterAnnotation parameter_annotations[annotated_parameters_size]; 317 // All *Annotation are 8 bytes each. 318 }; 319 320 // try_item 321 struct TryItem { 322 uint32_t start_addr; 323 uint16_t insn_count; 324 uint16_t handler_off; 325 }; 326 327 #pragma pack(pop) 328 329 } // namespace dex 330 } // namespace zucchini 331 332 #endif // COMPONENTS_ZUCCHINI_TYPE_DEX_H_ 333