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