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_ART_DEX_FILE_LOADER_H_
18 #define ART_LIBDEXFILE_DEX_ART_DEX_FILE_LOADER_H_
19 
20 #include <cstdint>
21 #include <memory>
22 #include <string>
23 #include <vector>
24 
25 #include "base/macros.h"
26 #include "dex/dex_file_loader.h"
27 
28 namespace art {
29 
30 class DexFile;
31 class DexFileContainer;
32 class MemMap;
33 class OatDexFile;
34 class ZipArchive;
35 
36 // Class that is used to open dex files and deal with corresponding multidex and location logic.
37 class ArtDexFileLoader : public DexFileLoader {
38  public:
~ArtDexFileLoader()39   virtual ~ArtDexFileLoader() { }
40 
41   // Returns the checksums of a file for comparison with GetLocationChecksum().
42   // For .dex files, this is the single header checksum.
43   // For zip files, this is the zip entry CRC32 checksum for classes.dex and
44   // each additional multidex entry classes2.dex, classes3.dex, etc.
45   // If a valid zip_fd is provided the file content will be read directly from
46   // the descriptor and `filename` will be used as alias for error logging. If
47   // zip_fd is -1, the method will try to open the `filename` and read the
48   // content from it.
49   //
50   // The dex_locations vector will be populated with the corresponding multidex
51   // locations.
52   //
53   // Return true if the checksums could be found, false otherwise.
54   bool GetMultiDexChecksums(const char* filename,
55                             std::vector<uint32_t>* checksums,
56                             std::vector<std::string>* dex_locations,
57                             std::string* error_msg,
58                             int zip_fd = -1,
59                             bool* only_contains_uncompressed_dex = nullptr) const override;
60 
61   // Opens .dex file, backed by existing memory
62   std::unique_ptr<const DexFile> Open(
63       const uint8_t* base,
64       size_t size,
65       const std::string& location,
66       uint32_t location_checksum,
67       const OatDexFile* oat_dex_file,
68       bool verify,
69       bool verify_checksum,
70       std::string* error_msg,
71       std::unique_ptr<DexFileContainer> container = nullptr) const override;
72 
73   // Opens .dex file that has been memory-mapped by the caller.
74   std::unique_ptr<const DexFile> Open(const std::string& location,
75                                       uint32_t location_checkum,
76                                       MemMap&& mem_map,
77                                       bool verify,
78                                       bool verify_checksum,
79                                       std::string* error_msg) const;
80 
81   // Opens all .dex files found in the file, guessing the container format based on file magic.
82   bool Open(const char* filename,
83             const std::string& location,
84             bool verify,
85             bool verify_checksum,
86             std::string* error_msg,
87             std::vector<std::unique_ptr<const DexFile>>* dex_files) const;
88   bool Open(int fd,
89             const std::string& location,
90             bool verify,
91             bool verify_checksum,
92             std::string* error_msg,
93             std::vector<std::unique_ptr<const DexFile>>* dex_files) const;
94   // Opens all .dex files found in the file, guessing the container format based on file magic.
95   // If the fd is -1 then the dex files are opened using the filename; otherwise they are
96   // opened using the fd.
97   bool Open(const char* filename,
98             int fd,
99             const std::string& location,
100             bool verify,
101             bool verify_checksum,
102             std::string* error_msg,
103             std::vector<std::unique_ptr<const DexFile>>* dex_files) const;
104 
105   // Open a single dex file from an fd. This function closes the fd.
106   std::unique_ptr<const DexFile> OpenDex(int fd,
107                                          const std::string& location,
108                                          bool verify,
109                                          bool verify_checksum,
110                                          bool mmap_shared,
111                                          std::string* error_msg) const;
112 
113   // Opens dex files from within a .jar, .zip, or .apk file
114   bool OpenZip(int fd,
115                const std::string& location,
116                bool verify,
117                bool verify_checksum,
118                std::string* error_msg,
119                std::vector<std::unique_ptr<const DexFile>>* dex_files) const;
120 
121  private:
122   bool OpenWithMagic(uint32_t magic,
123                      int fd,
124                      const std::string& location,
125                      bool verify,
126                      bool verify_checksum,
127                      std::string* error_msg,
128                      std::vector<std::unique_ptr<const DexFile>>* dex_files) const;
129 
130   std::unique_ptr<const DexFile> OpenFile(int fd,
131                                           const std::string& location,
132                                           bool verify,
133                                           bool verify_checksum,
134                                           bool mmap_shared,
135                                           std::string* error_msg) const;
136 
137   // Open all classesXXX.dex files from a zip archive.
138   bool OpenAllDexFilesFromZip(const ZipArchive& zip_archive,
139                               const std::string& location,
140                               bool verify,
141                               bool verify_checksum,
142                               std::string* error_msg,
143                               std::vector<std::unique_ptr<const DexFile>>* dex_files) const;
144 
145   // Opens .dex file from the entry_name in a zip archive. error_code is undefined when non-null
146   // return.
147   std::unique_ptr<const DexFile> OpenOneDexFileFromZip(const ZipArchive& zip_archive,
148                                                        const char* entry_name,
149                                                        const std::string& location,
150                                                        bool verify,
151                                                        bool verify_checksum,
152                                                        std::string* error_msg,
153                                                        DexFileLoaderErrorCode* error_code) const;
154 
155   static std::unique_ptr<DexFile> OpenCommon(const uint8_t* base,
156                                              size_t size,
157                                              const uint8_t* data_base,
158                                              size_t data_size,
159                                              const std::string& location,
160                                              uint32_t location_checksum,
161                                              const OatDexFile* oat_dex_file,
162                                              bool verify,
163                                              bool verify_checksum,
164                                              std::string* error_msg,
165                                              std::unique_ptr<DexFileContainer> container,
166                                              VerifyResult* verify_result);
167 };
168 
169 }  // namespace art
170 
171 #endif  // ART_LIBDEXFILE_DEX_ART_DEX_FILE_LOADER_H_
172