• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #pragma once
18 
19 #include <stdint.h>
20 #include <string>
21 
22 // Definitions for .dex file format structures and helpers.
23 //
24 // The names for the structures and fields follows the specification:
25 // https://source.android.com/devices/tech/dalvik/dex-format.html
26 
27 namespace dex {
28 
29 // These match the definitions in the VM specification
30 typedef uint8_t u1;
31 typedef uint16_t u2;
32 typedef uint32_t u4;
33 typedef uint64_t u8;
34 typedef int8_t s1;
35 typedef int16_t s2;
36 typedef int32_t s4;
37 typedef int64_t s8;
38 
39 // General constants
40 constexpr u4 kEndianConstant = 0x12345678;
41 constexpr u4 kNoIndex = 0xffffffff;
42 constexpr u4 kSHA1DigestLen = 20;
43 
44 // Annotation visibility
45 constexpr u1 kVisibilityBuild   = 0x00;
46 constexpr u1 kVisibilityRuntime = 0x01;
47 constexpr u1 kVisibilitySystem  = 0x02;
48 
49 // Special visibility: encoded_annotation, not annotation_item
50 constexpr u1 kVisibilityEncoded = 0xff;
51 
52 // encoded_value types
53 constexpr u1 kEncodedByte           = 0x00;
54 constexpr u1 kEncodedShort          = 0x02;
55 constexpr u1 kEncodedChar           = 0x03;
56 constexpr u1 kEncodedInt            = 0x04;
57 constexpr u1 kEncodedLong           = 0x06;
58 constexpr u1 kEncodedFloat          = 0x10;
59 constexpr u1 kEncodedDouble         = 0x11;
60 constexpr u1 kEncodedString         = 0x17;
61 constexpr u1 kEncodedType           = 0x18;
62 constexpr u1 kEncodedField          = 0x19;
63 constexpr u1 kEncodedMethod         = 0x1a;
64 constexpr u1 kEncodedEnum           = 0x1b;
65 constexpr u1 kEncodedArray          = 0x1c;
66 constexpr u1 kEncodedAnnotation     = 0x1d;
67 constexpr u1 kEncodedNull           = 0x1e;
68 constexpr u1 kEncodedBoolean        = 0x1f;
69 
70 // encoded_value header
71 constexpr u1 kEncodedValueTypeMask  = 0x1f;
72 constexpr u1 kEncodedValueArgShift  = 5;
73 
74 // access_flags
75 constexpr u4 kAccPublic                 = 0x0001;     // class, field, method, ic
76 constexpr u4 kAccPrivate                = 0x0002;     // field, method, ic
77 constexpr u4 kAccProtected              = 0x0004;     // field, method, ic
78 constexpr u4 kAccStatic                 = 0x0008;     // field, method, ic
79 constexpr u4 kAccFinal                  = 0x0010;     // class, field, method, ic
80 constexpr u4 kAccSynchronized           = 0x0020;     // method (only allowed on natives)
81 constexpr u4 kAccSuper                  = 0x0020;     // class (not used in dex)
82 constexpr u4 kAccVolatile               = 0x0040;     // field
83 constexpr u4 kAccBridge                 = 0x0040;     // method
84 constexpr u4 kAccTransient              = 0x0080;     // field
85 constexpr u4 kAccVarargs                = 0x0080;     // method
86 constexpr u4 kAccNative                 = 0x0100;     // method
87 constexpr u4 kAccInterface              = 0x0200;     // class, ic
88 constexpr u4 kAccAbstract               = 0x0400;     // class, method, ic
89 constexpr u4 kAccStrict                 = 0x0800;     // method
90 constexpr u4 kAccSynthetic              = 0x1000;     // class, field, method, ic
91 constexpr u4 kAccAnnotation             = 0x2000;     // class, ic
92 constexpr u4 kAccEnum                   = 0x4000;     // class, field, ic
93 constexpr u4 kAccConstructor            = 0x00010000; // method (dex only) <(cl)init>
94 constexpr u4 kAccDeclaredSynchronized   = 0x00020000; // method (dex only)
95 
96 // map_item type codes
97 constexpr u2 kHeaderItem                = 0x0000;
98 constexpr u2 kStringIdItem              = 0x0001;
99 constexpr u2 kTypeIdItem                = 0x0002;
100 constexpr u2 kProtoIdItem               = 0x0003;
101 constexpr u2 kFieldIdItem               = 0x0004;
102 constexpr u2 kMethodIdItem              = 0x0005;
103 constexpr u2 kClassDefItem              = 0x0006;
104 constexpr u2 kMethodHandleItem          = 0x0008;
105 constexpr u2 kMapList                   = 0x1000;
106 constexpr u2 kTypeList                  = 0x1001;
107 constexpr u2 kAnnotationSetRefList      = 0x1002;
108 constexpr u2 kAnnotationSetItem         = 0x1003;
109 constexpr u2 kClassDataItem             = 0x2000;
110 constexpr u2 kCodeItem                  = 0x2001;
111 constexpr u2 kStringDataItem            = 0x2002;
112 constexpr u2 kDebugInfoItem             = 0x2003;
113 constexpr u2 kAnnotationItem            = 0x2004;
114 constexpr u2 kEncodedArrayItem          = 0x2005;
115 constexpr u2 kAnnotationsDirectoryItem  = 0x2006;
116 
117 // debug info opcodes
118 constexpr u1 DBG_END_SEQUENCE           = 0x00;
119 constexpr u1 DBG_ADVANCE_PC             = 0x01;
120 constexpr u1 DBG_ADVANCE_LINE           = 0x02;
121 constexpr u1 DBG_START_LOCAL            = 0x03;
122 constexpr u1 DBG_START_LOCAL_EXTENDED   = 0x04;
123 constexpr u1 DBG_END_LOCAL              = 0x05;
124 constexpr u1 DBG_RESTART_LOCAL          = 0x06;
125 constexpr u1 DBG_SET_PROLOGUE_END       = 0x07;
126 constexpr u1 DBG_SET_EPILOGUE_BEGIN     = 0x08;
127 constexpr u1 DBG_SET_FILE               = 0x09;
128 constexpr u1 DBG_FIRST_SPECIAL          = 0x0a;
129 
130 
131 // method handle type
132 constexpr u1 METHOD_HANDLE_TYPE_STATIC_PUT = 0x00;
133 constexpr u1 METHOD_HANDLE_TYPE_STATIC_GET = 0x01;
134 constexpr u1 METHOD_HANDLE_TYPE_INSTANCE_PUT = 0x02;
135 constexpr u1 METHOD_HANDLE_TYPE_INSTANCE_GET = 0x03;
136 constexpr u1 METHOD_HANDLE_TYPE_INVOKE_STATIC = 0x04;
137 constexpr u1 METHOD_HANDLE_TYPE_INVOKE_INSTANCE = 0x05;
138 constexpr u1 METHOD_HANDLE_TYPE_INVOKE_CONSTRUCTOR = 0x06;
139 constexpr u1 METHOD_HANDLE_TYPE_INVOKE_DIRECT = 0x07;
140 constexpr u1 METHOD_HANDLE_TYPE_INVOKE_INTERFACE = 0x08;
141 
142 // special debug info values
143 constexpr int DBG_LINE_BASE = -4;
144 constexpr int DBG_LINE_RANGE = 15;
145 
146 // "header_item"
147 struct Header {
148   static constexpr size_t kV40Size = 0x70;  // Same as all previous dex versions.
149   static constexpr size_t kV41Size = 0x78;  // Added container_{size,off} fields.
150                                             // See http://go/dex-container-format
151   static constexpr size_t kMaxSize = kV41Size;
152 
153   static constexpr u4 kV41 = 41;
154   static constexpr u4 kMinVersion = 35;  // Minimum supported dex version.
155   static constexpr u4 kMaxVersion = 41;  // Maximum supported dex version.
156 
157   // Parse magic number and extract the version integer. E.g.: `dex\n123\0` returns `123`.
158   // Returns 0 upon failure.
159   static u4 GetVersion(const void* magic);
160 
GetVersionHeader161   u4 GetVersion() const {
162     return GetVersion(magic);
163   }
164 
ContainerSizeHeader165   u4 ContainerSize() const {
166     return header_size >= kV41Size ? container_size : file_size;
167   }
168 
ContainerOffHeader169   u4 ContainerOff() const {
170     return header_size >= kV41Size ? container_off : 0;
171   }
172 
SetContainerHeader173   void SetContainer(u4 off, u4 size) {
174     container_off = off;
175     container_size = size;
176   }
177 
178   u1 magic[8];
179   u4 checksum;
180   u1 signature[kSHA1DigestLen];
181   u4 file_size;
182   u4 header_size;
183   u4 endian_tag;
184   u4 link_size;
185   u4 link_off;
186   u4 map_off;
187   u4 string_ids_size;
188   u4 string_ids_off;
189   u4 type_ids_size;
190   u4 type_ids_off;
191   u4 proto_ids_size;
192   u4 proto_ids_off;
193   u4 field_ids_size;
194   u4 field_ids_off;
195   u4 method_ids_size;
196   u4 method_ids_off;
197   u4 class_defs_size;
198   u4 class_defs_off;
199   u4 data_size;
200   u4 data_off;
201 
202  private:
203   u4 container_size;
204   u4 container_off;
205 };
206 
207 // "map_item"
208 struct MapItem {
209   u2 type;
210   u2 unused;
211   u4 size;
212   u4 offset;
213 };
214 
215 // "map_list"
216 struct MapList {
217   u4 size;
218   MapItem list[];
219 };
220 
221 // "string_id_item"
222 struct StringId {
223   u4 string_data_off;
224 };
225 
226 // "type_id_item"
227 struct TypeId {
228   u4 descriptor_idx;
229 };
230 
231 // "field_id_item"
232 struct FieldId {
233   u2 class_idx;
234   u2 type_idx;
235   u4 name_idx;
236 };
237 
238 // "method_id_item"
239 struct MethodId {
240   u2 class_idx;
241   u2 proto_idx;
242   u4 name_idx;
243 };
244 
245 // "proto_id_item"
246 struct ProtoId {
247   u4 shorty_idx;
248   u4 return_type_idx;
249   u4 parameters_off;
250 };
251 
252 // "class_def_item"
253 struct ClassDef {
254   u4 class_idx;
255   u4 access_flags;
256   u4 superclass_idx;
257   u4 interfaces_off;
258   u4 source_file_idx;
259   u4 annotations_off;
260   u4 class_data_off;
261   u4 static_values_off;
262 };
263 
264 // "method_handle_item"
265 struct MethodHandle {
266   u2 method_handle_type;
267   u2 unused;
268   u2 field_or_method_id;
269   u2 unused2;
270 };
271 
272 // "type_item"
273 struct TypeItem {
274   u2 type_idx;
275 };
276 
277 // "type_list"
278 struct TypeList {
279   u4 size;
280   TypeItem list[];
281 };
282 
283 // "code_item"
284 struct Code {
285   u2 registers_size;
286   u2 ins_size;
287   u2 outs_size;
288   u2 tries_size;
289   u4 debug_info_off;
290   u4 insns_size;
291   u2 insns[];
292   // followed by optional u2 padding
293   // followed by try_item[tries_size]
294   // followed by uleb128 handlersSize
295   // followed by catch_handler_item[handlersSize]
296 };
297 
298 // "try_item"
299 struct TryBlock {
300   u4 start_addr;
301   u2 insn_count;
302   u2 handler_off;
303 };
304 
305 // "annotations_directory_item"
306 struct AnnotationsDirectoryItem {
307   u4 class_annotations_off;
308   u4 fields_size;
309   u4 methods_size;
310   u4 parameters_size;
311   // followed by FieldAnnotationsItem[fields_size]
312   // followed by MethodAnnotationsItem[methods_size]
313   // followed by ParameterAnnotationsItem[parameters_size]
314 };
315 
316 // "field_annotations_item"
317 struct FieldAnnotationsItem {
318   u4 field_idx;
319   u4 annotations_off;
320 };
321 
322 // "method_annotations_item"
323 struct MethodAnnotationsItem {
324   u4 method_idx;
325   u4 annotations_off;
326 };
327 
328 // "parameter_annotations_item"
329 struct ParameterAnnotationsItem {
330   u4 method_idx;
331   u4 annotations_off;
332 };
333 
334 // "annotation_set_ref_item"
335 struct AnnotationSetRefItem {
336   u4 annotations_off;
337 };
338 
339 // "annotation_set_ref_list"
340 struct AnnotationSetRefList {
341   u4 size;
342   AnnotationSetRefItem list[];
343 };
344 
345 // "annotation_set_item"
346 struct AnnotationSetItem {
347   u4 size;
348   u4 entries[];
349 };
350 
351 // "annotation_item"
352 struct AnnotationItem {
353   u1 visibility;
354   u1 annotation[];
355 };
356 
357 // Compute DEX checksum
358 u4 ComputeChecksum(const Header* header);
359 
360 // Converts a type descriptor to a human-readable declaration
361 std::string DescriptorToDecl(const char* descriptor);
362 
363 // Converts a type descriptor to the equivalent shorty type descriptor
364 char DescriptorToShorty(const char* descriptor);
365 
366 }  // namespace dex
367