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_DISASSEMBLER_DEX_H_
6 #define COMPONENTS_ZUCCHINI_DISASSEMBLER_DEX_H_
7 
8 #include <stdint.h>
9 
10 #include <map>
11 #include <memory>
12 #include <string>
13 #include <vector>
14 
15 #include "components/zucchini/disassembler.h"
16 #include "components/zucchini/image_utils.h"
17 #include "components/zucchini/type_dex.h"
18 
19 namespace zucchini {
20 
21 // For consistency, let "canonical order" of DEX data types be the order defined
22 // in https://source.android.com/devices/tech/dalvik/dex-format "Type Codes"
23 // section.
24 
25 class DisassemblerDex : public Disassembler {
26  public:
27   static constexpr uint16_t kVersion = 1;
28   // Pools follow canonical order.
29   enum ReferencePool : uint8_t {
30     kStringId,
31     kTypeId,
32     kProtoId,
33     kFieldId,
34     kMethodId,
35     // kClassDef,  // Unused
36     kCallSiteId,
37     kMethodHandle,
38     kTypeList,
39     kAnnotationSetRefList,
40     kAnnotionSet,
41     kClassData,
42     kCode,
43     kStringData,
44     kAnnotation,
45     kEncodedArray,
46     kAnnotationsDirectory,
47     kCallSite,
48     kNumPools
49   };
50 
51   // Types are grouped and ordered by target ReferencePool. This is required by
52   // Zucchini-apply, which visits references by type order and sequentially
53   // handles pools in the same order. Type-pool association is established in
54   // MakeReferenceGroups(), and verified by a unit test.
55   enum ReferenceType : uint8_t {
56     kTypeIdToDescriptorStringId,  // kStringId
57     kProtoIdToShortyStringId,
58     kFieldIdToNameStringId,
59     kMethodIdToNameStringId,
60     kClassDefToSourceFileStringId,
61     kCodeToStringId16,
62     kCodeToStringId32,
63 
64     kProtoIdToReturnTypeId,  // kTypeId
65     kFieldIdToClassTypeId,
66     kFieldIdToTypeId,
67     kMethodIdToClassTypeId,
68     kClassDefToClassTypeId,
69     kClassDefToSuperClassTypeId,
70     kTypeListToTypeId,
71     kCodeToTypeId,
72 
73     kCodeToProtoId,  // kProtoId
74     kMethodIdToProtoId,
75 
76     kCodeToFieldId,  // kFieldId
77     kMethodHandleToFieldId,
78     kAnnotationsDirectoryToFieldId,
79 
80     kCodeToMethodId,  // kMethodId
81     kMethodHandleToMethodId,
82     kAnnotationsDirectoryToMethodId,
83     kAnnotationsDirectoryToParameterMethodId,
84 
85     kCodeToCallSiteId,  // kCallSiteId
86 
87     kCodeToMethodHandle,  // kMethodHandle
88 
89     kProtoIdToParametersTypeList,  // kTypeList
90     kClassDefToInterfacesTypeList,
91 
92     kAnnotationsDirectoryToParameterAnnotationSetRef,  // kAnnotationSetRef,
93 
94     kAnnotationSetRefListToAnnotationSet,  // kAnnotationSet,
95     kAnnotationsDirectoryToClassAnnotationSet,
96     kAnnotationsDirectoryToFieldAnnotationSet,
97     kAnnotationsDirectoryToMethodAnnotationSet,
98 
99     kClassDefToClassData,  // kClassData
100 
101     kCodeToRelCode8,  // kCode
102     kCodeToRelCode16,
103     kCodeToRelCode32,
104 
105     kStringIdToStringData,  // kStringData
106 
107     kAnnotationSetToAnnotation,  // kAnnotation
108 
109     kClassDefToStaticValuesEncodedArray,  // kEncodedArrayItem
110 
111     kClassDefToAnnotationDirectory,  // kAnnotationsDirectory
112 
113     kCallSiteIdToCallSite,  // kCallSite
114 
115     kNumTypes
116   };
117 
118   DisassemblerDex();
119   DisassemblerDex(const DisassemblerDex&) = delete;
120   const DisassemblerDex& operator=(const DisassemblerDex&) = delete;
121   ~DisassemblerDex() override;
122 
123   // Applies quick checks to determine if |image| *may* point to the start of an
124   // executable. Returns true on success.
125   static bool QuickDetect(ConstBufferView image);
126 
127   // Disassembler:
128   ExecutableType GetExeType() const override;
129   std::string GetExeTypeString() const override;
130   std::vector<ReferenceGroup> MakeReferenceGroups() const override;
131 
132   // Functions that return reference readers. These follow canonical order of
133   // *locations* (unlike targets for ReferenceType). This allows functions with
134   // similar parsing logic to appear togeter.
135   std::unique_ptr<ReferenceReader> MakeReadStringIdToStringData(offset_t lo,
136                                                                 offset_t hi);
137   std::unique_ptr<ReferenceReader> MakeReadTypeIdToDescriptorStringId32(
138       offset_t lo,
139       offset_t hi);
140   std::unique_ptr<ReferenceReader> MakeReadProtoIdToShortyStringId32(
141       offset_t lo,
142       offset_t hi);
143   std::unique_ptr<ReferenceReader> MakeReadProtoIdToReturnTypeId32(offset_t lo,
144                                                                    offset_t hi);
145   std::unique_ptr<ReferenceReader> MakeReadProtoIdToParametersTypeList(
146       offset_t lo,
147       offset_t hi);
148   std::unique_ptr<ReferenceReader> MakeReadFieldToClassTypeId16(offset_t lo,
149                                                                 offset_t hi);
150   std::unique_ptr<ReferenceReader> MakeReadFieldToTypeId16(offset_t lo,
151                                                            offset_t hi);
152   std::unique_ptr<ReferenceReader> MakeReadFieldToNameStringId32(offset_t lo,
153                                                                  offset_t hi);
154   std::unique_ptr<ReferenceReader> MakeReadMethodIdToClassTypeId16(offset_t lo,
155                                                                    offset_t hi);
156   std::unique_ptr<ReferenceReader> MakeReadMethodIdToProtoId16(offset_t lo,
157                                                                offset_t hi);
158   std::unique_ptr<ReferenceReader> MakeReadMethodIdToNameStringId32(
159       offset_t lo,
160       offset_t hi);
161   std::unique_ptr<ReferenceReader> MakeReadClassDefToClassTypeId32(offset_t lo,
162                                                                    offset_t hi);
163   std::unique_ptr<ReferenceReader> MakeReadClassDefToSuperClassTypeId32(
164       offset_t lo,
165       offset_t hi);
166   std::unique_ptr<ReferenceReader> MakeReadClassDefToInterfacesTypeList(
167       offset_t lo,
168       offset_t hi);
169   std::unique_ptr<ReferenceReader> MakeReadClassDefToSourceFileStringId32(
170       offset_t lo,
171       offset_t hi);
172   std::unique_ptr<ReferenceReader> MakeReadClassDefToAnnotationDirectory(
173       offset_t lo,
174       offset_t hi);
175   std::unique_ptr<ReferenceReader> MakeReadClassDefToClassData(offset_t lo,
176                                                                offset_t hi);
177   std::unique_ptr<ReferenceReader> MakeReadClassDefToStaticValuesEncodedArray(
178       offset_t lo,
179       offset_t hi);
180   std::unique_ptr<ReferenceReader> MakeReadCallSiteIdToCallSite32(offset_t lo,
181                                                                   offset_t hi);
182   std::unique_ptr<ReferenceReader> MakeReadMethodHandleToFieldId16(offset_t lo,
183                                                                    offset_t hi);
184   std::unique_ptr<ReferenceReader> MakeReadMethodHandleToMethodId16(
185       offset_t lo,
186       offset_t hi);
187   std::unique_ptr<ReferenceReader> MakeReadTypeListToTypeId16(offset_t lo,
188                                                               offset_t hi);
189   std::unique_ptr<ReferenceReader> MakeReadAnnotationSetToAnnotation(
190       offset_t lo,
191       offset_t hi);
192   std::unique_ptr<ReferenceReader> MakeReadAnnotationSetRefListToAnnotationSet(
193       offset_t lo,
194       offset_t hi);
195   std::unique_ptr<ReferenceReader>
196   MakeReadAnnotationsDirectoryToClassAnnotationSet(offset_t lo, offset_t hi);
197   std::unique_ptr<ReferenceReader> MakeReadAnnotationsDirectoryToFieldId32(
198       offset_t lo,
199       offset_t hi);
200   std::unique_ptr<ReferenceReader>
201   MakeReadAnnotationsDirectoryToFieldAnnotationSet(offset_t lo, offset_t hi);
202   std::unique_ptr<ReferenceReader> MakeReadAnnotationsDirectoryToMethodId32(
203       offset_t lo,
204       offset_t hi);
205   std::unique_ptr<ReferenceReader>
206   MakeReadAnnotationsDirectoryToMethodAnnotationSet(offset_t lo, offset_t hi);
207   std::unique_ptr<ReferenceReader>
208   MakeReadAnnotationsDirectoryToParameterMethodId32(offset_t lo, offset_t hi);
209   std::unique_ptr<ReferenceReader>
210   MakeReadAnnotationsDirectoryToParameterAnnotationSetRef(offset_t lo,
211                                                           offset_t hi);
212   std::unique_ptr<ReferenceReader> MakeReadCodeToStringId16(offset_t lo,
213                                                             offset_t hi);
214   std::unique_ptr<ReferenceReader> MakeReadCodeToStringId32(offset_t lo,
215                                                             offset_t hi);
216   std::unique_ptr<ReferenceReader> MakeReadCodeToTypeId16(offset_t lo,
217                                                           offset_t hi);
218   std::unique_ptr<ReferenceReader> MakeReadCodeToProtoId16(offset_t lo,
219                                                            offset_t hi);
220   std::unique_ptr<ReferenceReader> MakeReadCodeToFieldId16(offset_t lo,
221                                                            offset_t hi);
222   std::unique_ptr<ReferenceReader> MakeReadCodeToMethodId16(offset_t lo,
223                                                             offset_t hi);
224   std::unique_ptr<ReferenceReader> MakeReadCodeToCallSiteId16(offset_t lo,
225                                                               offset_t hi);
226   std::unique_ptr<ReferenceReader> MakeReadCodeToMethodHandle16(offset_t lo,
227                                                                 offset_t hi);
228   std::unique_ptr<ReferenceReader> MakeReadCodeToRelCode8(offset_t lo,
229                                                           offset_t hi);
230   std::unique_ptr<ReferenceReader> MakeReadCodeToRelCode16(offset_t lo,
231                                                            offset_t hi);
232   std::unique_ptr<ReferenceReader> MakeReadCodeToRelCode32(offset_t lo,
233                                                            offset_t hi);
234 
235   // Functions that return reference writers. Different readers may share a
236   // common writer. Therefore these loosely follow canonical order of locations,
237   std::unique_ptr<ReferenceWriter> MakeWriteStringId16(MutableBufferView image);
238   std::unique_ptr<ReferenceWriter> MakeWriteStringId32(MutableBufferView image);
239   std::unique_ptr<ReferenceWriter> MakeWriteTypeId16(MutableBufferView image);
240   std::unique_ptr<ReferenceWriter> MakeWriteTypeId32(MutableBufferView image);
241   std::unique_ptr<ReferenceWriter> MakeWriteProtoId16(MutableBufferView image);
242   std::unique_ptr<ReferenceWriter> MakeWriteFieldId16(MutableBufferView image);
243   std::unique_ptr<ReferenceWriter> MakeWriteFieldId32(MutableBufferView image);
244   std::unique_ptr<ReferenceWriter> MakeWriteMethodId16(MutableBufferView image);
245   std::unique_ptr<ReferenceWriter> MakeWriteMethodId32(MutableBufferView image);
246   std::unique_ptr<ReferenceWriter> MakeWriteCallSiteId16(
247       MutableBufferView image);
248   std::unique_ptr<ReferenceWriter> MakeWriteMethodHandle16(
249       MutableBufferView image);
250   std::unique_ptr<ReferenceWriter> MakeWriteRelCode8(MutableBufferView image);
251   std::unique_ptr<ReferenceWriter> MakeWriteRelCode16(MutableBufferView image);
252   std::unique_ptr<ReferenceWriter> MakeWriteRelCode32(MutableBufferView image);
253   std::unique_ptr<ReferenceWriter> MakeWriteAbs32(MutableBufferView image);
254 
255  private:
256   friend Disassembler;
257   using MapItemMap = std::map<uint16_t, const dex::MapItem*>;
258 
259   // Disassembler:
260   bool Parse(ConstBufferView image) override;
261 
262   bool ParseHeader();
263 
264   const dex::HeaderItem* header_ = nullptr;
265   int dex_version_ = 0;
266   MapItemMap map_item_map_ = {};
267   dex::MapItem string_map_item_ = {};
268   dex::MapItem type_map_item_ = {};
269   dex::MapItem proto_map_item_ = {};
270   dex::MapItem field_map_item_ = {};
271   dex::MapItem method_map_item_ = {};
272   dex::MapItem class_def_map_item_ = {};
273   dex::MapItem call_site_map_item_ = {};
274   dex::MapItem method_handle_map_item_ = {};
275   dex::MapItem type_list_map_item_ = {};
276   dex::MapItem annotation_set_ref_list_map_item_ = {};
277   dex::MapItem annotation_set_map_item_ = {};
278   dex::MapItem code_map_item_ = {};
279   dex::MapItem annotations_directory_map_item_ = {};
280 
281   // Sorted list of offsets of parsed items in |image_|.
282   std::vector<offset_t> code_item_offsets_;
283   std::vector<offset_t> type_list_offsets_;
284   std::vector<offset_t> annotation_set_ref_list_offsets_;
285   std::vector<offset_t> annotation_set_offsets_;
286   std::vector<offset_t> annotations_directory_item_offsets_;
287   std::vector<offset_t> annotations_directory_item_field_annotation_offsets_;
288   std::vector<offset_t> annotations_directory_item_method_annotation_offsets_;
289   std::vector<offset_t>
290       annotations_directory_item_parameter_annotation_offsets_;
291 };
292 
293 }  // namespace zucchini
294 
295 #endif  // COMPONENTS_ZUCCHINI_DISASSEMBLER_DEX_H_
296