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