blob: d9d93b20aeada540641603c3d4516c4c796f0d48 [file] [log] [blame]
Etienne Pierre-Dorayfff1ca32018-03-29 13:33:46 +00001// 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>
Samuel Huanga8a2a942018-04-09 15:18:17 +000011#include <memory>
Etienne Pierre-Dorayfff1ca32018-03-29 13:33:46 +000012#include <string>
13#include <vector>
14
Etienne Pierre-Dorayfff1ca32018-03-29 13:33:46 +000015#include "components/zucchini/disassembler.h"
16#include "components/zucchini/image_utils.h"
17#include "components/zucchini/type_dex.h"
18
19namespace 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
25class DisassemblerDex : public Disassembler {
26 public:
Etienne Pierre-dorayb90a9472021-10-28 21:16:04 +000027 static constexpr uint16_t kVersion = 1;
Samuel Huanga8a2a942018-04-09 15:18:17 +000028 // Pools follow canonical order.
29 enum ReferencePool : uint8_t {
30 kStringId,
31 kTypeId,
32 kProtoId,
33 kFieldId,
34 kMethodId,
Calder Kitagawa18379912018-06-05 14:10:29 +000035 // kClassDef, // Unused
ckitagawa26518ff2021-09-03 15:48:28 +000036 kCallSiteId,
ckitagawa1269b5c2021-09-07 21:12:21 +000037 kMethodHandle,
Samuel Huanga8a2a942018-04-09 15:18:17 +000038 kTypeList,
Calder Kitagawa18379912018-06-05 14:10:29 +000039 kAnnotationSetRefList,
40 kAnnotionSet,
41 kClassData,
Samuel Huanga8a2a942018-04-09 15:18:17 +000042 kCode,
43 kStringData,
Calder Kitagawa18379912018-06-05 14:10:29 +000044 kAnnotation,
45 kEncodedArray,
46 kAnnotationsDirectory,
ckitagawa26518ff2021-09-03 15:48:28 +000047 kCallSite,
Samuel Huanga8a2a942018-04-09 15:18:17 +000048 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 {
Calder Kitagawa18379912018-06-05 14:10:29 +000056 kTypeIdToDescriptorStringId, // kStringId
57 kProtoIdToShortyStringId,
58 kFieldIdToNameStringId,
59 kMethodIdToNameStringId,
60 kClassDefToSourceFileStringId,
Samuel Huanga8a2a942018-04-09 15:18:17 +000061 kCodeToStringId16,
62 kCodeToStringId32,
63
Calder Kitagawa18379912018-06-05 14:10:29 +000064 kProtoIdToReturnTypeId, // kTypeId
65 kFieldIdToClassTypeId,
Samuel Huanga8a2a942018-04-09 15:18:17 +000066 kFieldIdToTypeId,
Calder Kitagawa18379912018-06-05 14:10:29 +000067 kMethodIdToClassTypeId,
68 kClassDefToClassTypeId,
69 kClassDefToSuperClassTypeId,
Calder Kitagawa6b80ac72018-06-11 13:54:24 +000070 kTypeListToTypeId,
Samuel Huanga8a2a942018-04-09 15:18:17 +000071 kCodeToTypeId,
72
ckitagawa26518ff2021-09-03 15:48:28 +000073 kCodeToProtoId, // kProtoId
74 kMethodIdToProtoId,
Calder Kitagawa18379912018-06-05 14:10:29 +000075
Samuel Huanga8a2a942018-04-09 15:18:17 +000076 kCodeToFieldId, // kFieldId
ckitagawa26518ff2021-09-03 15:48:28 +000077 kMethodHandleToFieldId,
Calder Kitagawa1b257092018-06-12 14:37:39 +000078 kAnnotationsDirectoryToFieldId,
Samuel Huanga8a2a942018-04-09 15:18:17 +000079
80 kCodeToMethodId, // kMethodId
ckitagawa26518ff2021-09-03 15:48:28 +000081 kMethodHandleToMethodId,
Calder Kitagawa1b257092018-06-12 14:37:39 +000082 kAnnotationsDirectoryToMethodId,
83 kAnnotationsDirectoryToParameterMethodId,
Samuel Huanga8a2a942018-04-09 15:18:17 +000084
ckitagawa26518ff2021-09-03 15:48:28 +000085 kCodeToCallSiteId, // kCallSiteId
86
ckitagawa1269b5c2021-09-07 21:12:21 +000087 kCodeToMethodHandle, // kMethodHandle
88
Calder Kitagawa18379912018-06-05 14:10:29 +000089 kProtoIdToParametersTypeList, // kTypeList
90 kClassDefToInterfacesTypeList,
91
Calder Kitagawa1b257092018-06-12 14:37:39 +000092 kAnnotationsDirectoryToParameterAnnotationSetRef, // kAnnotationSetRef,
Calder Kitagawa18379912018-06-05 14:10:29 +000093
Calder Kitagawa6b80ac72018-06-11 13:54:24 +000094 kAnnotationSetRefListToAnnotationSet, // kAnnotationSet,
Calder Kitagawa1b257092018-06-12 14:37:39 +000095 kAnnotationsDirectoryToClassAnnotationSet,
96 kAnnotationsDirectoryToFieldAnnotationSet,
97 kAnnotationsDirectoryToMethodAnnotationSet,
Calder Kitagawa18379912018-06-05 14:10:29 +000098
99 kClassDefToClassData, // kClassData
100
101 kCodeToRelCode8, // kCode
102 kCodeToRelCode16,
Samuel Huanga8a2a942018-04-09 15:18:17 +0000103 kCodeToRelCode32,
104
105 kStringIdToStringData, // kStringData
106
Calder Kitagawa6b80ac72018-06-11 13:54:24 +0000107 kAnnotationSetToAnnotation, // kAnnotation
Calder Kitagawa18379912018-06-05 14:10:29 +0000108
109 kClassDefToStaticValuesEncodedArray, // kEncodedArrayItem
110
111 kClassDefToAnnotationDirectory, // kAnnotationsDirectory
112
ckitagawa26518ff2021-09-03 15:48:28 +0000113 kCallSiteIdToCallSite, // kCallSite
Calder Kitagawa18379912018-06-05 14:10:29 +0000114
Samuel Huanga8a2a942018-04-09 15:18:17 +0000115 kNumTypes
116 };
117
Etienne Pierre-Dorayfff1ca32018-03-29 13:33:46 +0000118 DisassemblerDex();
Samuel Huangf137bf42021-08-13 15:42:26 +0000119 DisassemblerDex(const DisassemblerDex&) = delete;
120 const DisassemblerDex& operator=(const DisassemblerDex&) = delete;
Etienne Pierre-Dorayfff1ca32018-03-29 13:33:46 +0000121 ~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
Samuel Huanga8a2a942018-04-09 15:18:17 +0000132 // 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);
Calder Kitagawa18379912018-06-05 14:10:29 +0000137 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);
Samuel Huanga8a2a942018-04-09 15:18:17 +0000148 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);
Calder Kitagawa18379912018-06-05 14:10:29 +0000154 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);
ckitagawa26518ff2021-09-03 15:48:28 +0000180 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);
Calder Kitagawa6b80ac72018-06-11 13:54:24 +0000187 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);
Calder Kitagawa1b257092018-06-12 14:37:39 +0000195 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);
Samuel Huanga8a2a942018-04-09 15:18:17 +0000212 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);
ckitagawa26518ff2021-09-03 15:48:28 +0000218 std::unique_ptr<ReferenceReader> MakeReadCodeToProtoId16(offset_t lo,
219 offset_t hi);
Samuel Huanga8a2a942018-04-09 15:18:17 +0000220 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);
ckitagawa26518ff2021-09-03 15:48:28 +0000224 std::unique_ptr<ReferenceReader> MakeReadCodeToCallSiteId16(offset_t lo,
225 offset_t hi);
ckitagawa1269b5c2021-09-07 21:12:21 +0000226 std::unique_ptr<ReferenceReader> MakeReadCodeToMethodHandle16(offset_t lo,
227 offset_t hi);
Calder Kitagawa18379912018-06-05 14:10:29 +0000228 std::unique_ptr<ReferenceReader> MakeReadCodeToRelCode8(offset_t lo,
229 offset_t hi);
Samuel Huanga8a2a942018-04-09 15:18:17 +0000230 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);
Calder Kitagawa18379912018-06-05 14:10:29 +0000240 std::unique_ptr<ReferenceWriter> MakeWriteTypeId32(MutableBufferView image);
241 std::unique_ptr<ReferenceWriter> MakeWriteProtoId16(MutableBufferView image);
Samuel Huanga8a2a942018-04-09 15:18:17 +0000242 std::unique_ptr<ReferenceWriter> MakeWriteFieldId16(MutableBufferView image);
Calder Kitagawa18379912018-06-05 14:10:29 +0000243 std::unique_ptr<ReferenceWriter> MakeWriteFieldId32(MutableBufferView image);
Samuel Huanga8a2a942018-04-09 15:18:17 +0000244 std::unique_ptr<ReferenceWriter> MakeWriteMethodId16(MutableBufferView image);
Calder Kitagawa18379912018-06-05 14:10:29 +0000245 std::unique_ptr<ReferenceWriter> MakeWriteMethodId32(MutableBufferView image);
ckitagawa26518ff2021-09-03 15:48:28 +0000246 std::unique_ptr<ReferenceWriter> MakeWriteCallSiteId16(
247 MutableBufferView image);
ckitagawa1269b5c2021-09-07 21:12:21 +0000248 std::unique_ptr<ReferenceWriter> MakeWriteMethodHandle16(
249 MutableBufferView image);
Calder Kitagawa18379912018-06-05 14:10:29 +0000250 std::unique_ptr<ReferenceWriter> MakeWriteRelCode8(MutableBufferView image);
Samuel Huanga8a2a942018-04-09 15:18:17 +0000251 std::unique_ptr<ReferenceWriter> MakeWriteRelCode16(MutableBufferView image);
252 std::unique_ptr<ReferenceWriter> MakeWriteRelCode32(MutableBufferView image);
253 std::unique_ptr<ReferenceWriter> MakeWriteAbs32(MutableBufferView image);
254
Etienne Pierre-Dorayfff1ca32018-03-29 13:33:46 +0000255 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_ = {};
Calder Kitagawa18379912018-06-05 14:10:29 +0000269 dex::MapItem proto_map_item_ = {};
Etienne Pierre-Dorayfff1ca32018-03-29 13:33:46 +0000270 dex::MapItem field_map_item_ = {};
271 dex::MapItem method_map_item_ = {};
Calder Kitagawa18379912018-06-05 14:10:29 +0000272 dex::MapItem class_def_map_item_ = {};
ckitagawa26518ff2021-09-03 15:48:28 +0000273 dex::MapItem call_site_map_item_ = {};
274 dex::MapItem method_handle_map_item_ = {};
Calder Kitagawa6b80ac72018-06-11 13:54:24 +0000275 dex::MapItem type_list_map_item_ = {};
Calder Kitagawa6b80ac72018-06-11 13:54:24 +0000276 dex::MapItem annotation_set_ref_list_map_item_ = {};
277 dex::MapItem annotation_set_map_item_ = {};
ckitagawa26518ff2021-09-03 15:48:28 +0000278 dex::MapItem code_map_item_ = {};
Calder Kitagawa1b257092018-06-12 14:37:39 +0000279 dex::MapItem annotations_directory_map_item_ = {};
Calder Kitagawa6b80ac72018-06-11 13:54:24 +0000280
281 // Sorted list of offsets of parsed items in |image_|.
Etienne Pierre-Dorayfff1ca32018-03-29 13:33:46 +0000282 std::vector<offset_t> code_item_offsets_;
Calder Kitagawa6b80ac72018-06-11 13:54:24 +0000283 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_;
Calder Kitagawa1b257092018-06-12 14:37:39 +0000286 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_;
Etienne Pierre-Dorayfff1ca32018-03-29 13:33:46 +0000291};
292
293} // namespace zucchini
294
295#endif // COMPONENTS_ZUCCHINI_DISASSEMBLER_DEX_H_