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 kMapList                   = 0x1000;
105 constexpr u2 kTypeList                  = 0x1001;
106 constexpr u2 kAnnotationSetRefList      = 0x1002;
107 constexpr u2 kAnnotationSetItem         = 0x1003;
108 constexpr u2 kClassDataItem             = 0x2000;
109 constexpr u2 kCodeItem                  = 0x2001;
110 constexpr u2 kStringDataItem            = 0x2002;
111 constexpr u2 kDebugInfoItem             = 0x2003;
112 constexpr u2 kAnnotationItem            = 0x2004;
113 constexpr u2 kEncodedArrayItem          = 0x2005;
114 constexpr u2 kAnnotationsDirectoryItem  = 0x2006;
115 
116 // debug info opcodes
117 constexpr u1 DBG_END_SEQUENCE           = 0x00;
118 constexpr u1 DBG_ADVANCE_PC             = 0x01;
119 constexpr u1 DBG_ADVANCE_LINE           = 0x02;
120 constexpr u1 DBG_START_LOCAL            = 0x03;
121 constexpr u1 DBG_START_LOCAL_EXTENDED   = 0x04;
122 constexpr u1 DBG_END_LOCAL              = 0x05;
123 constexpr u1 DBG_RESTART_LOCAL          = 0x06;
124 constexpr u1 DBG_SET_PROLOGUE_END       = 0x07;
125 constexpr u1 DBG_SET_EPILOGUE_BEGIN     = 0x08;
126 constexpr u1 DBG_SET_FILE               = 0x09;
127 constexpr u1 DBG_FIRST_SPECIAL          = 0x0a;
128 
129 // special debug info values
130 constexpr int DBG_LINE_BASE = -4;
131 constexpr int DBG_LINE_RANGE = 15;
132 
133 // "header_item"
134 struct Header {
135   u1 magic[8];
136   u4 checksum;
137   u1 signature[kSHA1DigestLen];
138   u4 file_size;
139   u4 header_size;
140   u4 endian_tag;
141   u4 link_size;
142   u4 link_off;
143   u4 map_off;
144   u4 string_ids_size;
145   u4 string_ids_off;
146   u4 type_ids_size;
147   u4 type_ids_off;
148   u4 proto_ids_size;
149   u4 proto_ids_off;
150   u4 field_ids_size;
151   u4 field_ids_off;
152   u4 method_ids_size;
153   u4 method_ids_off;
154   u4 class_defs_size;
155   u4 class_defs_off;
156   u4 data_size;
157   u4 data_off;
158 };
159 
160 // "map_item"
161 struct MapItem {
162   u2 type;
163   u2 unused;
164   u4 size;
165   u4 offset;
166 };
167 
168 // "map_list"
169 struct MapList {
170   u4 size;
171   MapItem list[];
172 };
173 
174 // "string_id_item"
175 struct StringId {
176   u4 string_data_off;
177 };
178 
179 // "type_id_item"
180 struct TypeId {
181   u4 descriptor_idx;
182 };
183 
184 // "field_id_item"
185 struct FieldId {
186   u2 class_idx;
187   u2 type_idx;
188   u4 name_idx;
189 };
190 
191 // "method_id_item"
192 struct MethodId {
193   u2 class_idx;
194   u2 proto_idx;
195   u4 name_idx;
196 };
197 
198 // "proto_id_item"
199 struct ProtoId {
200   u4 shorty_idx;
201   u4 return_type_idx;
202   u4 parameters_off;
203 };
204 
205 // "class_def_item"
206 struct ClassDef {
207   u4 class_idx;
208   u4 access_flags;
209   u4 superclass_idx;
210   u4 interfaces_off;
211   u4 source_file_idx;
212   u4 annotations_off;
213   u4 class_data_off;
214   u4 static_values_off;
215 };
216 
217 // "type_item"
218 struct TypeItem {
219   u2 type_idx;
220 };
221 
222 // "type_list"
223 struct TypeList {
224   u4 size;
225   TypeItem list[];
226 };
227 
228 // "code_item"
229 struct Code {
230   u2 registers_size;
231   u2 ins_size;
232   u2 outs_size;
233   u2 tries_size;
234   u4 debug_info_off;
235   u4 insns_size;
236   u2 insns[];
237   // followed by optional u2 padding
238   // followed by try_item[tries_size]
239   // followed by uleb128 handlersSize
240   // followed by catch_handler_item[handlersSize]
241 };
242 
243 // "try_item"
244 struct TryBlock {
245   u4 start_addr;
246   u2 insn_count;
247   u2 handler_off;
248 };
249 
250 // "annotations_directory_item"
251 struct AnnotationsDirectoryItem {
252   u4 class_annotations_off;
253   u4 fields_size;
254   u4 methods_size;
255   u4 parameters_size;
256   // followed by FieldAnnotationsItem[fields_size]
257   // followed by MethodAnnotationsItem[methods_size]
258   // followed by ParameterAnnotationsItem[parameters_size]
259 };
260 
261 // "field_annotations_item"
262 struct FieldAnnotationsItem {
263   u4 field_idx;
264   u4 annotations_off;
265 };
266 
267 // "method_annotations_item"
268 struct MethodAnnotationsItem {
269   u4 method_idx;
270   u4 annotations_off;
271 };
272 
273 // "parameter_annotations_item"
274 struct ParameterAnnotationsItem {
275   u4 method_idx;
276   u4 annotations_off;
277 };
278 
279 // "annotation_set_ref_item"
280 struct AnnotationSetRefItem {
281   u4 annotations_off;
282 };
283 
284 // "annotation_set_ref_list"
285 struct AnnotationSetRefList {
286   u4 size;
287   AnnotationSetRefItem list[];
288 };
289 
290 // "annotation_set_item"
291 struct AnnotationSetItem {
292   u4 size;
293   u4 entries[];
294 };
295 
296 // "annotation_item"
297 struct AnnotationItem {
298   u1 visibility;
299   u1 annotation[];
300 };
301 
302 // Compute DEX checksum
303 u4 ComputeChecksum(const Header* header);
304 
305 // Converts a type descriptor to a human-readable declaration
306 std::string DescriptorToDecl(const char* descriptor);
307 
308 // Converts a type descriptor to the equivalent shorty type descriptor
309 char DescriptorToShorty(const char* descriptor);
310 
311 }  // namespace dex
312