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 #ifndef ART_LIBDEXFILE_DEX_DEX_FILE_LOADER_H_ 18 #define ART_LIBDEXFILE_DEX_DEX_FILE_LOADER_H_ 19 20 #include <cstdint> 21 #include <memory> 22 #include <string> 23 #include <vector> 24 25 namespace art { 26 27 class DexFile; 28 class DexFileContainer; 29 class MemMap; 30 class OatDexFile; 31 32 class DexZipArchive; 33 34 enum class DexFileLoaderErrorCode { 35 kNoError, 36 kEntryNotFound, 37 kExtractToMemoryError, 38 kDexFileError, 39 kMakeReadOnlyError, 40 kVerifyError 41 }; 42 43 // Class that is used to open dex files and deal with corresponding multidex and location logic. 44 class DexFileLoader { 45 public: 46 // name of the DexFile entry within a zip archive 47 static constexpr const char* kClassesDex = "classes.dex"; 48 49 // The separator character in MultiDex locations. 50 static constexpr char kMultiDexSeparator = '!'; 51 52 // Return true if the magic is valid for dex or cdex. 53 static bool IsMagicValid(uint32_t magic); 54 static bool IsMagicValid(const uint8_t* magic); 55 56 // Return true if the corresponding version and magic is valid. 57 static bool IsVersionAndMagicValid(const uint8_t* magic); 58 59 // Check whether a location denotes a multidex dex file. This is a very simple check: returns 60 // whether the string contains the separator character. 61 static bool IsMultiDexLocation(const char* location); 62 63 // Return the name of the index-th classes.dex in a multidex zip file. This is classes.dex for 64 // index == 0, and classes{index + 1}.dex else. 65 static std::string GetMultiDexClassesDexName(size_t index); 66 67 // Return the (possibly synthetic) dex location for a multidex entry. This is dex_location for 68 // index == 0, and dex_location + multi-dex-separator + GetMultiDexClassesDexName(index) else. 69 static std::string GetMultiDexLocation(size_t index, const char* dex_location); 70 71 // Returns the canonical form of the given dex location. 72 // 73 // There are different flavors of "dex locations" as follows: 74 // the file name of a dex file: 75 // The actual file path that the dex file has on disk. 76 // dex_location: 77 // This acts as a key for the class linker to know which dex file to load. 78 // It may correspond to either an old odex file or a particular dex file 79 // inside an oat file. In the first case it will also match the file name 80 // of the dex file. In the second case (oat) it will include the file name 81 // and possibly some multidex annotation to uniquely identify it. 82 // canonical_dex_location: 83 // the dex_location where its file name part has been made canonical. 84 static std::string GetDexCanonicalLocation(const char* dex_location); 85 86 // For normal dex files, location and base location coincide. If a dex file is part of a multidex 87 // archive, the base location is the name of the originating jar/apk, stripped of any internal 88 // classes*.dex path. GetBaseLocation(const char * location)89 static std::string GetBaseLocation(const char* location) { 90 const char* pos = strrchr(location, kMultiDexSeparator); 91 return (pos == nullptr) ? location : std::string(location, pos - location); 92 } 93 GetBaseLocation(const std::string & location)94 static std::string GetBaseLocation(const std::string& location) { 95 return GetBaseLocation(location.c_str()); 96 } 97 98 // Returns the '!classes*.dex' part of the dex location. Returns an empty 99 // string if there is no multidex suffix for the given location. 100 // The kMultiDexSeparator is included in the returned suffix. GetMultiDexSuffix(const std::string & location)101 static std::string GetMultiDexSuffix(const std::string& location) { 102 size_t pos = location.rfind(kMultiDexSeparator); 103 return (pos == std::string::npos) ? std::string() : location.substr(pos); 104 } 105 ~DexFileLoader()106 virtual ~DexFileLoader() { } 107 108 // Returns the checksums of a file for comparison with GetLocationChecksum(). 109 // For .dex files, this is the single header checksum. 110 // For zip files, this is the zip entry CRC32 checksum for classes.dex and 111 // each additional multidex entry classes2.dex, classes3.dex, etc. 112 // If a valid zip_fd is provided the file content will be read directly from 113 // the descriptor and `filename` will be used as alias for error logging. If 114 // zip_fd is -1, the method will try to open the `filename` and read the 115 // content from it. 116 // 117 // The dex_locations vector will be populated with the corresponding multidex 118 // locations. 119 // 120 // Return true if the checksums could be found, false otherwise. 121 virtual bool GetMultiDexChecksums(const char* filename, 122 std::vector<uint32_t>* checksums, 123 std::vector<std::string>* dex_locations, 124 std::string* error_msg, 125 int zip_fd = -1, 126 bool* zip_file_only_contains_uncompress_dex = nullptr) const; 127 128 // Opens .dex file, backed by existing vector memory. 129 static std::unique_ptr<const DexFile> Open( 130 const std::string& location, 131 uint32_t location_checksum, 132 std::vector<uint8_t>&& memory, 133 const OatDexFile* oat_dex_file, 134 bool verify, 135 bool verify_checksum, 136 std::string* error_msg); 137 138 // Opens .dex file, backed by existing memory. 139 virtual std::unique_ptr<const DexFile> Open( 140 const uint8_t* base, 141 size_t size, 142 const std::string& location, 143 uint32_t location_checksum, 144 const OatDexFile* oat_dex_file, 145 bool verify, 146 bool verify_checksum, 147 std::string* error_msg, 148 std::unique_ptr<DexFileContainer> container = nullptr) const; 149 150 // Open a dex file with a separate data section. 151 virtual std::unique_ptr<const DexFile> OpenWithDataSection( 152 const uint8_t* base, 153 size_t size, 154 const uint8_t* data_base, 155 size_t data_size, 156 const std::string& location, 157 uint32_t location_checksum, 158 const OatDexFile* oat_dex_file, 159 bool verify, 160 bool verify_checksum, 161 std::string* error_msg) const; 162 163 164 // Opens all .dex files found in the memory map, guessing the container format based on file 165 // extension. 166 virtual bool OpenAll(const uint8_t* base, 167 size_t size, 168 const std::string& location, 169 bool verify, 170 bool verify_checksum, 171 DexFileLoaderErrorCode* error_code, 172 std::string* error_msg, 173 std::vector<std::unique_ptr<const DexFile>>* dex_files) const; 174 175 protected: 176 enum class VerifyResult { // private 177 kVerifyNotAttempted, 178 kVerifySucceeded, 179 kVerifyFailed 180 }; 181 182 static std::unique_ptr<DexFile> OpenCommon(const uint8_t* base, 183 size_t size, 184 const uint8_t* data_base, 185 size_t data_size, 186 const std::string& location, 187 uint32_t location_checksum, 188 const OatDexFile* oat_dex_file, 189 bool verify, 190 bool verify_checksum, 191 std::string* error_msg, 192 std::unique_ptr<DexFileContainer> container, 193 VerifyResult* verify_result); 194 195 private: 196 // Open all classesXXX.dex files from a zip archive. 197 bool OpenAllDexFilesFromZip(const DexZipArchive& zip_archive, 198 const std::string& location, 199 bool verify, 200 bool verify_checksum, 201 DexFileLoaderErrorCode* error_code, 202 std::string* error_msg, 203 std::vector<std::unique_ptr<const DexFile>>* dex_files) const; 204 205 // Opens .dex file from the entry_name in a zip archive. error_code is undefined when non-null 206 // return. 207 std::unique_ptr<const DexFile> OpenOneDexFileFromZip(const DexZipArchive& zip_archive, 208 const char* entry_name, 209 const std::string& location, 210 bool verify, 211 bool verify_checksum, 212 DexFileLoaderErrorCode* error_code, 213 std::string* error_msg) const; 214 }; 215 216 } // namespace art 217 218 #endif // ART_LIBDEXFILE_DEX_DEX_FILE_LOADER_H_ 219