1 /*
2  * Copyright (C) 2011 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 #include "dex_file_verifier.h"
18 
19 #include "sys/mman.h"
20 #include "zlib.h"
21 #include <functional>
22 #include <memory>
23 
24 #include "base/unix_file/fd_file.h"
25 #include "base/bit_utils.h"
26 #include "base/macros.h"
27 #include "common_runtime_test.h"
28 #include "dex_file-inl.h"
29 #include "leb128.h"
30 #include "scoped_thread_state_change.h"
31 #include "thread-inl.h"
32 
33 namespace art {
34 
35 static const uint8_t kBase64Map[256] = {
36   255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
37   255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
38   255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
39   255, 255, 255, 255, 255, 255, 255,  62, 255, 255, 255,  63,
40   52,  53,  54,  55,  56,  57,  58,  59,  60,  61, 255, 255,
41   255, 254, 255, 255, 255,   0,   1,   2,   3,   4,   5,   6,
42     7,   8,   9,  10,  11,  12,  13,  14,  15,  16,  17,  18,  // NOLINT
43    19,  20,  21,  22,  23,  24,  25, 255, 255, 255, 255, 255,  // NOLINT
44   255,  26,  27,  28,  29,  30,  31,  32,  33,  34,  35,  36,
45    37,  38,  39,  40,  41,  42,  43,  44,  45,  46,  47,  48,  // NOLINT
46    49,  50,  51, 255, 255, 255, 255, 255, 255, 255, 255, 255,  // NOLINT
47   255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
48   255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
49   255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
50   255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
51   255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
52   255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
53   255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
54   255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
55   255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
56   255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
57   255, 255, 255, 255
58 };
59 
60 // Make the Dex file version 37.
MakeDexVersion37(DexFile * dex_file)61 static void MakeDexVersion37(DexFile* dex_file) {
62   size_t offset = OFFSETOF_MEMBER(DexFile::Header, magic_) + 6;
63   CHECK_EQ(*(dex_file->Begin() + offset), '5');
64   *(const_cast<uint8_t*>(dex_file->Begin()) + offset) = '7';
65 }
66 
DecodeBase64(const char * src,size_t * dst_size)67 static inline std::unique_ptr<uint8_t[]> DecodeBase64(const char* src, size_t* dst_size) {
68   std::vector<uint8_t> tmp;
69   uint32_t t = 0, y = 0;
70   int g = 3;
71   for (size_t i = 0; src[i] != '\0'; ++i) {
72     uint8_t c = kBase64Map[src[i] & 0xFF];
73     if (c == 255) continue;
74     // the final = symbols are read and used to trim the remaining bytes
75     if (c == 254) {
76       c = 0;
77       // prevent g < 0 which would potentially allow an overflow later
78       if (--g < 0) {
79         *dst_size = 0;
80         return nullptr;
81       }
82     } else if (g != 3) {
83       // we only allow = to be at the end
84       *dst_size = 0;
85       return nullptr;
86     }
87     t = (t << 6) | c;
88     if (++y == 4) {
89       tmp.push_back((t >> 16) & 255);
90       if (g > 1) {
91         tmp.push_back((t >> 8) & 255);
92       }
93       if (g > 2) {
94         tmp.push_back(t & 255);
95       }
96       y = t = 0;
97     }
98   }
99   if (y != 0) {
100     *dst_size = 0;
101     return nullptr;
102   }
103   std::unique_ptr<uint8_t[]> dst(new uint8_t[tmp.size()]);
104   if (dst_size != nullptr) {
105     *dst_size = tmp.size();
106   } else {
107     *dst_size = 0;
108   }
109   std::copy(tmp.begin(), tmp.end(), dst.get());
110   return dst;
111 }
112 
FixUpChecksum(uint8_t * dex_file)113 static void FixUpChecksum(uint8_t* dex_file) {
114   DexFile::Header* header = reinterpret_cast<DexFile::Header*>(dex_file);
115   uint32_t expected_size = header->file_size_;
116   uint32_t adler_checksum = adler32(0L, Z_NULL, 0);
117   const uint32_t non_sum = sizeof(DexFile::Header::magic_) + sizeof(DexFile::Header::checksum_);
118   const uint8_t* non_sum_ptr = dex_file + non_sum;
119   adler_checksum = adler32(adler_checksum, non_sum_ptr, expected_size - non_sum);
120   header->checksum_ = adler_checksum;
121 }
122 
123 class DexFileVerifierTest : public CommonRuntimeTest {
124  protected:
VerifyModification(const char * dex_file_base64_content,const char * location,std::function<void (DexFile *)> f,const char * expected_error)125   void VerifyModification(const char* dex_file_base64_content,
126                           const char* location,
127                           std::function<void(DexFile*)> f,
128                           const char* expected_error) {
129     size_t length;
130     std::unique_ptr<uint8_t[]> dex_bytes = DecodeBase64(dex_file_base64_content, &length);
131     CHECK(dex_bytes != nullptr);
132     // Note: `dex_file` will be destroyed before `dex_bytes`.
133     std::unique_ptr<DexFile> dex_file(
134         new DexFile(dex_bytes.get(), length, "tmp", 0, nullptr, nullptr));
135     f(dex_file.get());
136     FixUpChecksum(const_cast<uint8_t*>(dex_file->Begin()));
137 
138     std::string error_msg;
139     bool success = DexFileVerifier::Verify(dex_file.get(),
140                                            dex_file->Begin(),
141                                            dex_file->Size(),
142                                            location,
143                                            &error_msg);
144     if (expected_error == nullptr) {
145       EXPECT_TRUE(success) << error_msg;
146     } else {
147       EXPECT_FALSE(success) << "Expected " << expected_error;
148       if (!success) {
149         EXPECT_NE(error_msg.find(expected_error), std::string::npos) << error_msg;
150       }
151     }
152   }
153 };
154 
OpenDexFileBase64(const char * base64,const char * location,std::string * error_msg)155 static std::unique_ptr<const DexFile> OpenDexFileBase64(const char* base64,
156                                                         const char* location,
157                                                         std::string* error_msg) {
158   // decode base64
159   CHECK(base64 != nullptr);
160   size_t length;
161   std::unique_ptr<uint8_t[]> dex_bytes(DecodeBase64(base64, &length));
162   CHECK(dex_bytes.get() != nullptr);
163 
164   // write to provided file
165   std::unique_ptr<File> file(OS::CreateEmptyFile(location));
166   CHECK(file.get() != nullptr);
167   if (!file->WriteFully(dex_bytes.get(), length)) {
168     PLOG(FATAL) << "Failed to write base64 as dex file";
169   }
170   if (file->FlushCloseOrErase() != 0) {
171     PLOG(FATAL) << "Could not flush and close test file.";
172   }
173   file.reset();
174 
175   // read dex file
176   ScopedObjectAccess soa(Thread::Current());
177   std::vector<std::unique_ptr<const DexFile>> tmp;
178   bool success = DexFile::Open(location, location, error_msg, &tmp);
179   CHECK(success) << error_msg;
180   EXPECT_EQ(1U, tmp.size());
181   std::unique_ptr<const DexFile> dex_file = std::move(tmp[0]);
182   EXPECT_EQ(PROT_READ, dex_file->GetPermissions());
183   EXPECT_TRUE(dex_file->IsReadOnly());
184   return dex_file;
185 }
186 
187 // To generate a base64 encoded Dex file (such as kGoodTestDex, below)
188 // from Smali files, use:
189 //
190 //   smali -o classes.dex class1.smali [class2.smali ...]
191 //   base64 classes.dex >classes.dex.base64
192 
193 // For reference.
194 static const char kGoodTestDex[] =
195     "ZGV4CjAzNQDrVbyVkxX1HljTznNf95AglkUAhQuFtmKkAgAAcAAAAHhWNBIAAAAAAAAAAAQCAAAN"
196     "AAAAcAAAAAYAAACkAAAAAgAAALwAAAABAAAA1AAAAAQAAADcAAAAAQAAAPwAAACIAQAAHAEAAFoB"
197     "AABiAQAAagEAAIEBAACVAQAAqQEAAL0BAADDAQAAzgEAANEBAADVAQAA2gEAAN8BAAABAAAAAgAA"
198     "AAMAAAAEAAAABQAAAAgAAAAIAAAABQAAAAAAAAAJAAAABQAAAFQBAAAEAAEACwAAAAAAAAAAAAAA"
199     "AAAAAAoAAAABAAEADAAAAAIAAAAAAAAAAAAAAAEAAAACAAAAAAAAAAcAAAAAAAAA8wEAAAAAAAAB"
200     "AAEAAQAAAOgBAAAEAAAAcBADAAAADgACAAAAAgAAAO0BAAAIAAAAYgAAABoBBgBuIAIAEAAOAAEA"
201     "AAADAAY8aW5pdD4ABkxUZXN0OwAVTGphdmEvaW8vUHJpbnRTdHJlYW07ABJMamF2YS9sYW5nL09i"
202     "amVjdDsAEkxqYXZhL2xhbmcvU3RyaW5nOwASTGphdmEvbGFuZy9TeXN0ZW07AARUZXN0AAlUZXN0"
203     "LmphdmEAAVYAAlZMAANmb28AA291dAAHcHJpbnRsbgABAAcOAAMABw54AAAAAgAAgYAEnAIBCbQC"
204     "AAAADQAAAAAAAAABAAAAAAAAAAEAAAANAAAAcAAAAAIAAAAGAAAApAAAAAMAAAACAAAAvAAAAAQA"
205     "AAABAAAA1AAAAAUAAAAEAAAA3AAAAAYAAAABAAAA/AAAAAEgAAACAAAAHAEAAAEQAAABAAAAVAEA"
206     "AAIgAAANAAAAWgEAAAMgAAACAAAA6AEAAAAgAAABAAAA8wEAAAAQAAABAAAABAIAAA==";
207 
TEST_F(DexFileVerifierTest,GoodDex)208 TEST_F(DexFileVerifierTest, GoodDex) {
209   ScratchFile tmp;
210   std::string error_msg;
211   std::unique_ptr<const DexFile> raw(OpenDexFileBase64(kGoodTestDex, tmp.GetFilename().c_str(),
212                                                        &error_msg));
213   ASSERT_TRUE(raw.get() != nullptr) << error_msg;
214 }
215 
TEST_F(DexFileVerifierTest,MethodId)216 TEST_F(DexFileVerifierTest, MethodId) {
217   // Class idx error.
218   VerifyModification(
219       kGoodTestDex,
220       "method_id_class_idx",
221       [](DexFile* dex_file) {
222         DexFile::MethodId* method_id = const_cast<DexFile::MethodId*>(&dex_file->GetMethodId(0));
223         method_id->class_idx_ = 0xFF;
224       },
225       "could not find declaring class for direct method index 0");
226 
227   // Proto idx error.
228   VerifyModification(
229       kGoodTestDex,
230       "method_id_proto_idx",
231       [](DexFile* dex_file) {
232         DexFile::MethodId* method_id = const_cast<DexFile::MethodId*>(&dex_file->GetMethodId(0));
233         method_id->proto_idx_ = 0xFF;
234       },
235       "inter_method_id_item proto_idx");
236 
237   // Name idx error.
238   VerifyModification(
239       kGoodTestDex,
240       "method_id_name_idx",
241       [](DexFile* dex_file) {
242         DexFile::MethodId* method_id = const_cast<DexFile::MethodId*>(&dex_file->GetMethodId(0));
243         method_id->name_idx_ = 0xFF;
244       },
245       "String index not available for method flags verification");
246 }
247 
248 // Method flags test class generated from the following smali code. The declared-synchronized
249 // flags are there to enforce a 3-byte uLEB128 encoding so we don't have to relayout
250 // the code, but we need to remove them before doing tests.
251 //
252 // .class public LMethodFlags;
253 // .super Ljava/lang/Object;
254 //
255 // .method public static constructor <clinit>()V
256 // .registers 1
257 //     return-void
258 // .end method
259 //
260 // .method public constructor <init>()V
261 // .registers 1
262 //     return-void
263 // .end method
264 //
265 // .method private declared-synchronized foo()V
266 // .registers 1
267 //     return-void
268 // .end method
269 //
270 // .method public declared-synchronized bar()V
271 // .registers 1
272 //     return-void
273 // .end method
274 
275 static const char kMethodFlagsTestDex[] =
276     "ZGV4CjAzNQCyOQrJaDBwiIWv5MIuYKXhxlLLsQcx5SwgAgAAcAAAAHhWNBIAAAAAAAAAAJgBAAAH"
277     "AAAAcAAAAAMAAACMAAAAAQAAAJgAAAAAAAAAAAAAAAQAAACkAAAAAQAAAMQAAAA8AQAA5AAAAOQA"
278     "AADuAAAA9gAAAAUBAAAZAQAAHAEAACEBAAACAAAAAwAAAAQAAAAEAAAAAgAAAAAAAAAAAAAAAAAA"
279     "AAAAAAABAAAAAAAAAAUAAAAAAAAABgAAAAAAAAABAAAAAQAAAAAAAAD/////AAAAAHoBAAAAAAAA"
280     "CDxjbGluaXQ+AAY8aW5pdD4ADUxNZXRob2RGbGFnczsAEkxqYXZhL2xhbmcvT2JqZWN0OwABVgAD"
281     "YmFyAANmb28AAAAAAAAAAQAAAAAAAAAAAAAAAQAAAA4AAAABAAEAAAAAAAAAAAABAAAADgAAAAEA"
282     "AQAAAAAAAAAAAAEAAAAOAAAAAQABAAAAAAAAAAAAAQAAAA4AAAADAQCJgASsAgGBgATAAgKCgAjU"
283     "AgKBgAjoAgAACwAAAAAAAAABAAAAAAAAAAEAAAAHAAAAcAAAAAIAAAADAAAAjAAAAAMAAAABAAAA"
284     "mAAAAAUAAAAEAAAApAAAAAYAAAABAAAAxAAAAAIgAAAHAAAA5AAAAAMQAAABAAAAKAEAAAEgAAAE"
285     "AAAALAEAAAAgAAABAAAAegEAAAAQAAABAAAAmAEAAA==";
286 
287 // Find the method data for the first method with the given name (from class 0). Note: the pointer
288 // is to the access flags, so that the caller doesn't have to handle the leb128-encoded method-index
289 // delta.
FindMethodData(const DexFile * dex_file,const char * name,uint32_t * method_idx=nullptr)290 static const uint8_t* FindMethodData(const DexFile* dex_file,
291                                      const char* name,
292                                      /*out*/ uint32_t* method_idx = nullptr) {
293   const DexFile::ClassDef& class_def = dex_file->GetClassDef(0);
294   const uint8_t* class_data = dex_file->GetClassData(class_def);
295 
296   ClassDataItemIterator it(*dex_file, class_data);
297 
298   const uint8_t* trailing = class_data;
299   // Need to manually decode the four entries. DataPointer() doesn't work for this, as the first
300   // element has already been loaded into the iterator.
301   DecodeUnsignedLeb128(&trailing);
302   DecodeUnsignedLeb128(&trailing);
303   DecodeUnsignedLeb128(&trailing);
304   DecodeUnsignedLeb128(&trailing);
305 
306   // Skip all fields.
307   while (it.HasNextStaticField() || it.HasNextInstanceField()) {
308     trailing = it.DataPointer();
309     it.Next();
310   }
311 
312   while (it.HasNextDirectMethod() || it.HasNextVirtualMethod()) {
313     uint32_t method_index = it.GetMemberIndex();
314     uint32_t name_index = dex_file->GetMethodId(method_index).name_idx_;
315     const DexFile::StringId& string_id = dex_file->GetStringId(name_index);
316     const char* str = dex_file->GetStringData(string_id);
317     if (strcmp(name, str) == 0) {
318       if (method_idx != nullptr) {
319         *method_idx = method_index;
320       }
321       DecodeUnsignedLeb128(&trailing);
322       return trailing;
323     }
324 
325     trailing = it.DataPointer();
326     it.Next();
327   }
328 
329   return nullptr;
330 }
331 
332 // Set the method flags to the given value.
SetMethodFlags(DexFile * dex_file,const char * method,uint32_t mask)333 static void SetMethodFlags(DexFile* dex_file, const char* method, uint32_t mask) {
334   uint8_t* method_flags_ptr = const_cast<uint8_t*>(FindMethodData(dex_file, method));
335   CHECK(method_flags_ptr != nullptr) << method;
336 
337     // Unroll this, as we only have three bytes, anyways.
338   uint8_t base1 = static_cast<uint8_t>(mask & 0x7F);
339   *(method_flags_ptr++) = (base1 | 0x80);
340   mask >>= 7;
341 
342   uint8_t base2 = static_cast<uint8_t>(mask & 0x7F);
343   *(method_flags_ptr++) = (base2 | 0x80);
344   mask >>= 7;
345 
346   uint8_t base3 = static_cast<uint8_t>(mask & 0x7F);
347   *method_flags_ptr = base3;
348 }
349 
GetMethodFlags(DexFile * dex_file,const char * method)350 static uint32_t GetMethodFlags(DexFile* dex_file, const char* method) {
351   const uint8_t* method_flags_ptr = const_cast<uint8_t*>(FindMethodData(dex_file, method));
352   CHECK(method_flags_ptr != nullptr) << method;
353   return DecodeUnsignedLeb128(&method_flags_ptr);
354 }
355 
356 // Apply the given mask to method flags.
ApplyMaskToMethodFlags(DexFile * dex_file,const char * method,uint32_t mask)357 static void ApplyMaskToMethodFlags(DexFile* dex_file, const char* method, uint32_t mask) {
358   uint32_t value = GetMethodFlags(dex_file, method);
359   value &= mask;
360   SetMethodFlags(dex_file, method, value);
361 }
362 
363 // Apply the given mask to method flags.
OrMaskToMethodFlags(DexFile * dex_file,const char * method,uint32_t mask)364 static void OrMaskToMethodFlags(DexFile* dex_file, const char* method, uint32_t mask) {
365   uint32_t value = GetMethodFlags(dex_file, method);
366   value |= mask;
367   SetMethodFlags(dex_file, method, value);
368 }
369 
370 // Set code_off to 0 for the method.
RemoveCode(DexFile * dex_file,const char * method)371 static void RemoveCode(DexFile* dex_file, const char* method) {
372   const uint8_t* ptr = FindMethodData(dex_file, method);
373   // Next is flags, pass.
374   DecodeUnsignedLeb128(&ptr);
375 
376   // Figure out how many bytes the code_off is.
377   const uint8_t* tmp = ptr;
378   DecodeUnsignedLeb128(&tmp);
379   size_t bytes = tmp - ptr;
380 
381   uint8_t* mod = const_cast<uint8_t*>(ptr);
382   for (size_t i = 1; i < bytes; ++i) {
383     *(mod++) = 0x80;
384   }
385   *mod = 0x00;
386 }
387 
TEST_F(DexFileVerifierTest,MethodAccessFlagsBase)388 TEST_F(DexFileVerifierTest, MethodAccessFlagsBase) {
389   // Check that it's OK when the wrong declared-synchronized flag is removed from "foo."
390   VerifyModification(
391       kMethodFlagsTestDex,
392       "method_flags_ok",
393       [](DexFile* dex_file) {
394         ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
395         ApplyMaskToMethodFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
396       },
397       nullptr);
398 }
399 
TEST_F(DexFileVerifierTest,MethodAccessFlagsConstructors)400 TEST_F(DexFileVerifierTest, MethodAccessFlagsConstructors) {
401   // Make sure we still accept constructors without their flags.
402   VerifyModification(
403       kMethodFlagsTestDex,
404       "method_flags_missing_constructor_tag_ok",
405       [](DexFile* dex_file) {
406         ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
407         ApplyMaskToMethodFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
408 
409         ApplyMaskToMethodFlags(dex_file, "<init>", ~kAccConstructor);
410         ApplyMaskToMethodFlags(dex_file, "<clinit>", ~kAccConstructor);
411       },
412       nullptr);
413 
414   constexpr const char* kConstructors[] = { "<clinit>", "<init>"};
415   for (size_t i = 0; i < 2; ++i) {
416     // Constructor with code marked native.
417     VerifyModification(
418         kMethodFlagsTestDex,
419         "method_flags_constructor_native",
420         [&](DexFile* dex_file) {
421           ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
422           ApplyMaskToMethodFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
423 
424           OrMaskToMethodFlags(dex_file, kConstructors[i], kAccNative);
425         },
426         "has code, but is marked native or abstract");
427     // Constructor with code marked abstract.
428     VerifyModification(
429         kMethodFlagsTestDex,
430         "method_flags_constructor_abstract",
431         [&](DexFile* dex_file) {
432           ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
433           ApplyMaskToMethodFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
434 
435           OrMaskToMethodFlags(dex_file, kConstructors[i], kAccAbstract);
436         },
437         "has code, but is marked native or abstract");
438     // Constructor as-is without code.
439     VerifyModification(
440         kMethodFlagsTestDex,
441         "method_flags_constructor_nocode",
442         [&](DexFile* dex_file) {
443           ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
444           ApplyMaskToMethodFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
445 
446           RemoveCode(dex_file, kConstructors[i]);
447         },
448         "has no code, but is not marked native or abstract");
449     // Constructor without code marked native.
450     VerifyModification(
451         kMethodFlagsTestDex,
452         "method_flags_constructor_native_nocode",
453         [&](DexFile* dex_file) {
454           MakeDexVersion37(dex_file);
455           ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
456           ApplyMaskToMethodFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
457 
458           OrMaskToMethodFlags(dex_file, kConstructors[i], kAccNative);
459           RemoveCode(dex_file, kConstructors[i]);
460         },
461         "must not be abstract or native");
462     // Constructor without code marked abstract.
463     VerifyModification(
464         kMethodFlagsTestDex,
465         "method_flags_constructor_abstract_nocode",
466         [&](DexFile* dex_file) {
467           MakeDexVersion37(dex_file);
468           ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
469           ApplyMaskToMethodFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
470 
471           OrMaskToMethodFlags(dex_file, kConstructors[i], kAccAbstract);
472           RemoveCode(dex_file, kConstructors[i]);
473         },
474         "must not be abstract or native");
475   }
476   // <init> may only have (modulo ignored):
477   // kAccPrivate | kAccProtected | kAccPublic | kAccStrict | kAccVarargs | kAccSynthetic
478   static constexpr uint32_t kInitAllowed[] = {
479       0,
480       kAccPrivate,
481       kAccProtected,
482       kAccPublic,
483       kAccStrict,
484       kAccVarargs,
485       kAccSynthetic
486   };
487   for (size_t i = 0; i < arraysize(kInitAllowed); ++i) {
488     VerifyModification(
489         kMethodFlagsTestDex,
490         "init_allowed_flags",
491         [&](DexFile* dex_file) {
492           ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
493           ApplyMaskToMethodFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
494 
495           ApplyMaskToMethodFlags(dex_file, "<init>", ~kAccPublic);
496           OrMaskToMethodFlags(dex_file, "<init>", kInitAllowed[i]);
497         },
498         nullptr);
499   }
500   // Only one of public-private-protected.
501   for (size_t i = 1; i < 8; ++i) {
502     if (POPCOUNT(i) < 2) {
503       continue;
504     }
505     // Technically the flags match, but just be defensive here.
506     uint32_t mask = ((i & 1) != 0 ? kAccPrivate : 0) |
507                     ((i & 2) != 0 ? kAccProtected : 0) |
508                     ((i & 4) != 0 ? kAccPublic : 0);
509     VerifyModification(
510         kMethodFlagsTestDex,
511         "init_one_of_ppp",
512         [&](DexFile* dex_file) {
513           ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
514           ApplyMaskToMethodFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
515 
516           ApplyMaskToMethodFlags(dex_file, "<init>", ~kAccPublic);
517           OrMaskToMethodFlags(dex_file, "<init>", mask);
518         },
519         "Method may have only one of public/protected/private");
520   }
521   // <init> doesn't allow
522   // kAccStatic | kAccFinal | kAccSynchronized | kAccBridge
523   // Need to handle static separately as it has its own error message.
524   VerifyModification(
525       kMethodFlagsTestDex,
526       "init_not_allowed_flags",
527       [&](DexFile* dex_file) {
528         MakeDexVersion37(dex_file);
529         ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
530         ApplyMaskToMethodFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
531 
532         ApplyMaskToMethodFlags(dex_file, "<init>", ~kAccPublic);
533         OrMaskToMethodFlags(dex_file, "<init>", kAccStatic);
534       },
535       "Constructor 1(LMethodFlags;.<init>) is not flagged correctly wrt/ static");
536   static constexpr uint32_t kInitNotAllowed[] = {
537       kAccFinal,
538       kAccSynchronized,
539       kAccBridge
540   };
541   for (size_t i = 0; i < arraysize(kInitNotAllowed); ++i) {
542     VerifyModification(
543         kMethodFlagsTestDex,
544         "init_not_allowed_flags",
545         [&](DexFile* dex_file) {
546           ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
547           ApplyMaskToMethodFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
548 
549           ApplyMaskToMethodFlags(dex_file, "<init>", ~kAccPublic);
550           OrMaskToMethodFlags(dex_file, "<init>", kInitNotAllowed[i]);
551         },
552         "Constructor 1(LMethodFlags;.<init>) flagged inappropriately");
553   }
554 }
555 
TEST_F(DexFileVerifierTest,MethodAccessFlagsMethods)556 TEST_F(DexFileVerifierTest, MethodAccessFlagsMethods) {
557   constexpr const char* kMethods[] = { "foo", "bar"};
558   for (size_t i = 0; i < arraysize(kMethods); ++i) {
559     // Make sure we reject non-constructors marked as constructors.
560     VerifyModification(
561         kMethodFlagsTestDex,
562         "method_flags_non_constructor",
563         [&](DexFile* dex_file) {
564           ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
565           ApplyMaskToMethodFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
566 
567           OrMaskToMethodFlags(dex_file, kMethods[i], kAccConstructor);
568         },
569         "is marked constructor, but doesn't match name");
570 
571     VerifyModification(
572         kMethodFlagsTestDex,
573         "method_flags_native_with_code",
574         [&](DexFile* dex_file) {
575           ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
576           ApplyMaskToMethodFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
577 
578           OrMaskToMethodFlags(dex_file, kMethods[i], kAccNative);
579         },
580         "has code, but is marked native or abstract");
581 
582     VerifyModification(
583         kMethodFlagsTestDex,
584         "method_flags_abstract_with_code",
585         [&](DexFile* dex_file) {
586           ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
587           ApplyMaskToMethodFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
588 
589           OrMaskToMethodFlags(dex_file, kMethods[i], kAccAbstract);
590         },
591         "has code, but is marked native or abstract");
592 
593     VerifyModification(
594         kMethodFlagsTestDex,
595         "method_flags_non_abstract_native_no_code",
596         [&](DexFile* dex_file) {
597           ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
598           ApplyMaskToMethodFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
599 
600           RemoveCode(dex_file, kMethods[i]);
601         },
602         "has no code, but is not marked native or abstract");
603 
604     // Abstract methods may not have the following flags.
605     constexpr uint32_t kAbstractDisallowed[] = {
606         kAccPrivate,
607         kAccStatic,
608         kAccFinal,
609         kAccNative,
610         kAccStrict,
611         kAccSynchronized,
612     };
613     for (size_t j = 0; j < arraysize(kAbstractDisallowed); ++j) {
614       VerifyModification(
615           kMethodFlagsTestDex,
616           "method_flags_abstract_and_disallowed_no_code",
617           [&](DexFile* dex_file) {
618             ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
619             ApplyMaskToMethodFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
620 
621             RemoveCode(dex_file, kMethods[i]);
622 
623             // Can't check private and static with foo, as it's in the virtual list and gives a
624             // different error.
625             if (((GetMethodFlags(dex_file, kMethods[i]) & kAccPublic) != 0) &&
626                 ((kAbstractDisallowed[j] & (kAccPrivate | kAccStatic)) != 0)) {
627               // Use another breaking flag.
628               OrMaskToMethodFlags(dex_file, kMethods[i], kAccAbstract | kAccFinal);
629             } else {
630               OrMaskToMethodFlags(dex_file, kMethods[i], kAccAbstract | kAbstractDisallowed[j]);
631             }
632           },
633           "has disallowed access flags");
634     }
635 
636     // Only one of public-private-protected.
637     for (size_t j = 1; j < 8; ++j) {
638       if (POPCOUNT(j) < 2) {
639         continue;
640       }
641       // Technically the flags match, but just be defensive here.
642       uint32_t mask = ((j & 1) != 0 ? kAccPrivate : 0) |
643                       ((j & 2) != 0 ? kAccProtected : 0) |
644                       ((j & 4) != 0 ? kAccPublic : 0);
645       VerifyModification(
646           kMethodFlagsTestDex,
647           "method_flags_one_of_ppp",
648           [&](DexFile* dex_file) {
649             ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
650             ApplyMaskToMethodFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
651 
652             ApplyMaskToMethodFlags(dex_file, kMethods[i], ~kAccPublic);
653             OrMaskToMethodFlags(dex_file, kMethods[i], mask);
654           },
655           "Method may have only one of public/protected/private");
656     }
657   }
658 }
659 
TEST_F(DexFileVerifierTest,MethodAccessFlagsIgnoredOK)660 TEST_F(DexFileVerifierTest, MethodAccessFlagsIgnoredOK) {
661   constexpr const char* kMethods[] = { "<clinit>", "<init>", "foo", "bar"};
662   for (size_t i = 0; i < arraysize(kMethods); ++i) {
663     // All interesting method flags, other flags are to be ignored.
664     constexpr uint32_t kAllMethodFlags =
665         kAccPublic |
666         kAccPrivate |
667         kAccProtected |
668         kAccStatic |
669         kAccFinal |
670         kAccSynchronized |
671         kAccBridge |
672         kAccVarargs |
673         kAccNative |
674         kAccAbstract |
675         kAccStrict |
676         kAccSynthetic;
677     constexpr uint32_t kIgnoredMask = ~kAllMethodFlags & 0xFFFF;
678     VerifyModification(
679         kMethodFlagsTestDex,
680         "method_flags_ignored",
681         [&](DexFile* dex_file) {
682           ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
683           ApplyMaskToMethodFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
684 
685           OrMaskToMethodFlags(dex_file, kMethods[i], kIgnoredMask);
686         },
687         nullptr);
688   }
689 }
690 
TEST_F(DexFileVerifierTest,B28552165)691 TEST_F(DexFileVerifierTest, B28552165) {
692   // Regression test for bad error string retrieval in different situations.
693   // Using invalid access flags to trigger the error.
694   VerifyModification(
695       kMethodFlagsTestDex,
696       "b28552165",
697       [](DexFile* dex_file) {
698         OrMaskToMethodFlags(dex_file, "foo", kAccPublic | kAccProtected);
699         uint32_t method_idx;
700         FindMethodData(dex_file, "foo", &method_idx);
701         auto* method_id = const_cast<DexFile::MethodId*>(&dex_file->GetMethodId(method_idx));
702         method_id->name_idx_ = dex_file->NumStringIds();
703       },
704       "Method may have only one of public/protected/private, LMethodFlags;.(error)");
705 }
706 
707 // Set of dex files for interface method tests. As it's not as easy to mutate method names, it's
708 // just easier to break up bad cases.
709 
710 // Standard interface. Use declared-synchronized again for 3B encoding.
711 //
712 // .class public interface LInterfaceMethodFlags;
713 // .super Ljava/lang/Object;
714 //
715 // .method public static constructor <clinit>()V
716 // .registers 1
717 //     return-void
718 // .end method
719 //
720 // .method public abstract declared-synchronized foo()V
721 // .end method
722 static const char kMethodFlagsInterface[] =
723     "ZGV4CjAzNQCOM0odZ5bws1d9GSmumXaK5iE/7XxFpOm8AQAAcAAAAHhWNBIAAAAAAAAAADQBAAAF"
724     "AAAAcAAAAAMAAACEAAAAAQAAAJAAAAAAAAAAAAAAAAIAAACcAAAAAQAAAKwAAADwAAAAzAAAAMwA"
725     "AADWAAAA7gAAAAIBAAAFAQAAAQAAAAIAAAADAAAAAwAAAAIAAAAAAAAAAAAAAAAAAAAAAAAABAAA"
726     "AAAAAAABAgAAAQAAAAAAAAD/////AAAAACIBAAAAAAAACDxjbGluaXQ+ABZMSW50ZXJmYWNlTWV0"
727     "aG9kRmxhZ3M7ABJMamF2YS9sYW5nL09iamVjdDsAAVYAA2ZvbwAAAAAAAAABAAAAAAAAAAAAAAAB"
728     "AAAADgAAAAEBAImABJACAYGICAAAAAALAAAAAAAAAAEAAAAAAAAAAQAAAAUAAABwAAAAAgAAAAMA"
729     "AACEAAAAAwAAAAEAAACQAAAABQAAAAIAAACcAAAABgAAAAEAAACsAAAAAiAAAAUAAADMAAAAAxAA"
730     "AAEAAAAMAQAAASAAAAEAAAAQAQAAACAAAAEAAAAiAQAAABAAAAEAAAA0AQAA";
731 
732 // To simplify generation of interesting "sub-states" of src_value, allow a "simple" mask to apply
733 // to a src_value, such that mask bit 0 applies to the lowest set bit in src_value, and so on.
ApplyMaskShifted(uint32_t src_value,uint32_t mask)734 static uint32_t ApplyMaskShifted(uint32_t src_value, uint32_t mask) {
735   uint32_t result = 0;
736   uint32_t mask_index = 0;
737   while (src_value != 0) {
738     uint32_t index = CTZ(src_value);
739     if (((src_value & (1 << index)) != 0) &&
740         ((mask & (1 << mask_index)) != 0)) {
741       result |= (1 << index);
742     }
743     src_value &= ~(1 << index);
744     mask_index++;
745   }
746   return result;
747 }
748 
TEST_F(DexFileVerifierTest,MethodAccessFlagsInterfaces)749 TEST_F(DexFileVerifierTest, MethodAccessFlagsInterfaces) {
750   VerifyModification(
751       kMethodFlagsInterface,
752       "method_flags_interface_ok",
753       [](DexFile* dex_file) {
754         ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
755       },
756       nullptr);
757   VerifyModification(
758       kMethodFlagsInterface,
759       "method_flags_interface_ok37",
760       [](DexFile* dex_file) {
761         MakeDexVersion37(dex_file);
762         ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
763       },
764       nullptr);
765 
766   VerifyModification(
767       kMethodFlagsInterface,
768       "method_flags_interface_non_public",
769       [](DexFile* dex_file) {
770         ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
771 
772         ApplyMaskToMethodFlags(dex_file, "foo", ~kAccPublic);
773       },
774       nullptr);  // Should be allowed in older dex versions for backwards compatibility.
775   VerifyModification(
776       kMethodFlagsInterface,
777       "method_flags_interface_non_public",
778       [](DexFile* dex_file) {
779         MakeDexVersion37(dex_file);
780         ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
781 
782         ApplyMaskToMethodFlags(dex_file, "foo", ~kAccPublic);
783       },
784       "Interface virtual method 1(LInterfaceMethodFlags;.foo) is not public");
785 
786   VerifyModification(
787       kMethodFlagsInterface,
788       "method_flags_interface_non_abstract",
789       [](DexFile* dex_file) {
790         ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
791 
792         ApplyMaskToMethodFlags(dex_file, "foo", ~kAccAbstract);
793       },
794       "Method 1(LInterfaceMethodFlags;.foo) has no code, but is not marked native or abstract");
795 
796   VerifyModification(
797       kMethodFlagsInterface,
798       "method_flags_interface_static",
799       [](DexFile* dex_file) {
800         ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
801 
802         OrMaskToMethodFlags(dex_file, "foo", kAccStatic);
803       },
804       "Direct/virtual method 1(LInterfaceMethodFlags;.foo) not in expected list 0");
805   VerifyModification(
806       kMethodFlagsInterface,
807       "method_flags_interface_private",
808       [](DexFile* dex_file) {
809         ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
810 
811         ApplyMaskToMethodFlags(dex_file, "foo", ~kAccPublic);
812         OrMaskToMethodFlags(dex_file, "foo", kAccPrivate);
813       },
814       "Direct/virtual method 1(LInterfaceMethodFlags;.foo) not in expected list 0");
815 
816   VerifyModification(
817       kMethodFlagsInterface,
818       "method_flags_interface_non_public",
819       [](DexFile* dex_file) {
820         ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
821 
822         ApplyMaskToMethodFlags(dex_file, "foo", ~kAccPublic);
823       },
824       nullptr);  // Should be allowed in older dex versions for backwards compatibility.
825   VerifyModification(
826       kMethodFlagsInterface,
827       "method_flags_interface_non_public",
828       [](DexFile* dex_file) {
829         MakeDexVersion37(dex_file);
830         ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
831 
832         ApplyMaskToMethodFlags(dex_file, "foo", ~kAccPublic);
833       },
834       "Interface virtual method 1(LInterfaceMethodFlags;.foo) is not public");
835 
836   VerifyModification(
837       kMethodFlagsInterface,
838       "method_flags_interface_protected",
839       [](DexFile* dex_file) {
840         ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
841 
842         ApplyMaskToMethodFlags(dex_file, "foo", ~kAccPublic);
843         OrMaskToMethodFlags(dex_file, "foo", kAccProtected);
844       },
845       nullptr);  // Should be allowed in older dex versions for backwards compatibility.
846   VerifyModification(
847       kMethodFlagsInterface,
848       "method_flags_interface_protected",
849       [](DexFile* dex_file) {
850         MakeDexVersion37(dex_file);
851         ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
852 
853         ApplyMaskToMethodFlags(dex_file, "foo", ~kAccPublic);
854         OrMaskToMethodFlags(dex_file, "foo", kAccProtected);
855       },
856       "Interface virtual method 1(LInterfaceMethodFlags;.foo) is not public");
857 
858   constexpr uint32_t kAllMethodFlags =
859       kAccPublic |
860       kAccPrivate |
861       kAccProtected |
862       kAccStatic |
863       kAccFinal |
864       kAccSynchronized |
865       kAccBridge |
866       kAccVarargs |
867       kAccNative |
868       kAccAbstract |
869       kAccStrict |
870       kAccSynthetic;
871   constexpr uint32_t kInterfaceMethodFlags =
872       kAccPublic | kAccAbstract | kAccVarargs | kAccBridge | kAccSynthetic;
873   constexpr uint32_t kInterfaceDisallowed = kAllMethodFlags &
874                                             ~kInterfaceMethodFlags &
875                                             // Already tested, needed to be separate.
876                                             ~kAccStatic &
877                                             ~kAccPrivate &
878                                             ~kAccProtected;
879   static_assert(kInterfaceDisallowed != 0, "There should be disallowed flags.");
880 
881   uint32_t bits = POPCOUNT(kInterfaceDisallowed);
882   for (uint32_t i = 1; i < (1u << bits); ++i) {
883     VerifyModification(
884         kMethodFlagsInterface,
885         "method_flags_interface_non_abstract",
886         [&](DexFile* dex_file) {
887           ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
888 
889           uint32_t mask = ApplyMaskShifted(kInterfaceDisallowed, i);
890           if ((mask & kAccProtected) != 0) {
891             mask &= ~kAccProtected;
892             ApplyMaskToMethodFlags(dex_file, "foo", ~kAccPublic);
893           }
894           OrMaskToMethodFlags(dex_file, "foo", mask);
895         },
896         "Abstract method 1(LInterfaceMethodFlags;.foo) has disallowed access flags");
897   }
898 }
899 
900 ///////////////////////////////////////////////////////////////////
901 
902 // Field flags.
903 
904 // Find the method data for the first method with the given name (from class 0). Note: the pointer
905 // is to the access flags, so that the caller doesn't have to handle the leb128-encoded method-index
906 // delta.
FindFieldData(const DexFile * dex_file,const char * name)907 static const uint8_t* FindFieldData(const DexFile* dex_file, const char* name) {
908   const DexFile::ClassDef& class_def = dex_file->GetClassDef(0);
909   const uint8_t* class_data = dex_file->GetClassData(class_def);
910 
911   ClassDataItemIterator it(*dex_file, class_data);
912 
913   const uint8_t* trailing = class_data;
914   // Need to manually decode the four entries. DataPointer() doesn't work for this, as the first
915   // element has already been loaded into the iterator.
916   DecodeUnsignedLeb128(&trailing);
917   DecodeUnsignedLeb128(&trailing);
918   DecodeUnsignedLeb128(&trailing);
919   DecodeUnsignedLeb128(&trailing);
920 
921   while (it.HasNextStaticField() || it.HasNextInstanceField()) {
922     uint32_t field_index = it.GetMemberIndex();
923     uint32_t name_index = dex_file->GetFieldId(field_index).name_idx_;
924     const DexFile::StringId& string_id = dex_file->GetStringId(name_index);
925     const char* str = dex_file->GetStringData(string_id);
926     if (strcmp(name, str) == 0) {
927       DecodeUnsignedLeb128(&trailing);
928       return trailing;
929     }
930 
931     trailing = it.DataPointer();
932     it.Next();
933   }
934 
935   return nullptr;
936 }
937 
938 // Set the method flags to the given value.
SetFieldFlags(DexFile * dex_file,const char * field,uint32_t mask)939 static void SetFieldFlags(DexFile* dex_file, const char* field, uint32_t mask) {
940   uint8_t* field_flags_ptr = const_cast<uint8_t*>(FindFieldData(dex_file, field));
941   CHECK(field_flags_ptr != nullptr) << field;
942 
943     // Unroll this, as we only have three bytes, anyways.
944   uint8_t base1 = static_cast<uint8_t>(mask & 0x7F);
945   *(field_flags_ptr++) = (base1 | 0x80);
946   mask >>= 7;
947 
948   uint8_t base2 = static_cast<uint8_t>(mask & 0x7F);
949   *(field_flags_ptr++) = (base2 | 0x80);
950   mask >>= 7;
951 
952   uint8_t base3 = static_cast<uint8_t>(mask & 0x7F);
953   *field_flags_ptr = base3;
954 }
955 
GetFieldFlags(DexFile * dex_file,const char * field)956 static uint32_t GetFieldFlags(DexFile* dex_file, const char* field) {
957   const uint8_t* field_flags_ptr = const_cast<uint8_t*>(FindFieldData(dex_file, field));
958   CHECK(field_flags_ptr != nullptr) << field;
959   return DecodeUnsignedLeb128(&field_flags_ptr);
960 }
961 
962 // Apply the given mask to method flags.
ApplyMaskToFieldFlags(DexFile * dex_file,const char * field,uint32_t mask)963 static void ApplyMaskToFieldFlags(DexFile* dex_file, const char* field, uint32_t mask) {
964   uint32_t value = GetFieldFlags(dex_file, field);
965   value &= mask;
966   SetFieldFlags(dex_file, field, value);
967 }
968 
969 // Apply the given mask to method flags.
OrMaskToFieldFlags(DexFile * dex_file,const char * field,uint32_t mask)970 static void OrMaskToFieldFlags(DexFile* dex_file, const char* field, uint32_t mask) {
971   uint32_t value = GetFieldFlags(dex_file, field);
972   value |= mask;
973   SetFieldFlags(dex_file, field, value);
974 }
975 
976 // Standard class. Use declared-synchronized again for 3B encoding.
977 //
978 // .class public LFieldFlags;
979 // .super Ljava/lang/Object;
980 //
981 // .field declared-synchronized public foo:I
982 //
983 // .field declared-synchronized public static bar:I
984 
985 static const char kFieldFlagsTestDex[] =
986     "ZGV4CjAzNQBtLw7hydbfv4TdXidZyzAB70W7w3vnYJRwAQAAcAAAAHhWNBIAAAAAAAAAAAABAAAF"
987     "AAAAcAAAAAMAAACEAAAAAAAAAAAAAAACAAAAkAAAAAAAAAAAAAAAAQAAAKAAAACwAAAAwAAAAMAA"
988     "AADDAAAA0QAAAOUAAADqAAAAAAAAAAEAAAACAAAAAQAAAAMAAAABAAAABAAAAAEAAAABAAAAAgAA"
989     "AAAAAAD/////AAAAAPQAAAAAAAAAAUkADExGaWVsZEZsYWdzOwASTGphdmEvbGFuZy9PYmplY3Q7"
990     "AANiYXIAA2ZvbwAAAAAAAAEBAAAAiYAIAYGACAkAAAAAAAAAAQAAAAAAAAABAAAABQAAAHAAAAAC"
991     "AAAAAwAAAIQAAAAEAAAAAgAAAJAAAAAGAAAAAQAAAKAAAAACIAAABQAAAMAAAAADEAAAAQAAAPAA"
992     "AAAAIAAAAQAAAPQAAAAAEAAAAQAAAAABAAA=";
993 
TEST_F(DexFileVerifierTest,FieldAccessFlagsBase)994 TEST_F(DexFileVerifierTest, FieldAccessFlagsBase) {
995   // Check that it's OK when the wrong declared-synchronized flag is removed from "foo."
996   VerifyModification(
997       kFieldFlagsTestDex,
998       "field_flags_ok",
999       [](DexFile* dex_file) {
1000         ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
1001         ApplyMaskToFieldFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
1002       },
1003       nullptr);
1004 }
1005 
TEST_F(DexFileVerifierTest,FieldAccessFlagsWrongList)1006 TEST_F(DexFileVerifierTest, FieldAccessFlagsWrongList) {
1007   // Mark the field so that it should appear in the opposite list (instance vs static).
1008   VerifyModification(
1009       kFieldFlagsTestDex,
1010       "field_flags_wrong_list",
1011       [](DexFile* dex_file) {
1012         ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
1013         ApplyMaskToFieldFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
1014 
1015         OrMaskToFieldFlags(dex_file, "foo", kAccStatic);
1016       },
1017       "Static/instance field not in expected list");
1018   VerifyModification(
1019       kFieldFlagsTestDex,
1020       "field_flags_wrong_list",
1021       [](DexFile* dex_file) {
1022         ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
1023         ApplyMaskToFieldFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
1024 
1025         ApplyMaskToFieldFlags(dex_file, "bar", ~kAccStatic);
1026       },
1027       "Static/instance field not in expected list");
1028 }
1029 
TEST_F(DexFileVerifierTest,FieldAccessFlagsPPP)1030 TEST_F(DexFileVerifierTest, FieldAccessFlagsPPP) {
1031   static const char* kFields[] = { "foo", "bar" };
1032   for (size_t i = 0; i < arraysize(kFields); ++i) {
1033     // Should be OK to remove public.
1034     VerifyModification(
1035         kFieldFlagsTestDex,
1036         "field_flags_non_public",
1037         [&](DexFile* dex_file) {
1038           ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
1039           ApplyMaskToFieldFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
1040 
1041           ApplyMaskToFieldFlags(dex_file, kFields[i], ~kAccPublic);
1042         },
1043         nullptr);
1044     constexpr uint32_t kAccFlags = kAccPublic | kAccPrivate | kAccProtected;
1045     uint32_t bits = POPCOUNT(kAccFlags);
1046     for (uint32_t j = 1; j < (1u << bits); ++j) {
1047       if (POPCOUNT(j) < 2) {
1048         continue;
1049       }
1050       VerifyModification(
1051            kFieldFlagsTestDex,
1052            "field_flags_ppp",
1053            [&](DexFile* dex_file) {
1054              ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
1055              ApplyMaskToFieldFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
1056 
1057              ApplyMaskToFieldFlags(dex_file, kFields[i], ~kAccPublic);
1058              uint32_t mask = ApplyMaskShifted(kAccFlags, j);
1059              OrMaskToFieldFlags(dex_file, kFields[i], mask);
1060            },
1061            "Field may have only one of public/protected/private");
1062     }
1063   }
1064 }
1065 
TEST_F(DexFileVerifierTest,FieldAccessFlagsIgnoredOK)1066 TEST_F(DexFileVerifierTest, FieldAccessFlagsIgnoredOK) {
1067   constexpr const char* kFields[] = { "foo", "bar"};
1068   for (size_t i = 0; i < arraysize(kFields); ++i) {
1069     // All interesting method flags, other flags are to be ignored.
1070     constexpr uint32_t kAllFieldFlags =
1071         kAccPublic |
1072         kAccPrivate |
1073         kAccProtected |
1074         kAccStatic |
1075         kAccFinal |
1076         kAccVolatile |
1077         kAccTransient |
1078         kAccSynthetic |
1079         kAccEnum;
1080     constexpr uint32_t kIgnoredMask = ~kAllFieldFlags & 0xFFFF;
1081     VerifyModification(
1082         kFieldFlagsTestDex,
1083         "field_flags_ignored",
1084         [&](DexFile* dex_file) {
1085           ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
1086           ApplyMaskToFieldFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
1087 
1088           OrMaskToFieldFlags(dex_file, kFields[i], kIgnoredMask);
1089         },
1090         nullptr);
1091   }
1092 }
1093 
TEST_F(DexFileVerifierTest,FieldAccessFlagsVolatileFinal)1094 TEST_F(DexFileVerifierTest, FieldAccessFlagsVolatileFinal) {
1095   constexpr const char* kFields[] = { "foo", "bar"};
1096   for (size_t i = 0; i < arraysize(kFields); ++i) {
1097     VerifyModification(
1098         kFieldFlagsTestDex,
1099         "field_flags_final_and_volatile",
1100         [&](DexFile* dex_file) {
1101           ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
1102           ApplyMaskToFieldFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
1103 
1104           OrMaskToFieldFlags(dex_file, kFields[i], kAccVolatile | kAccFinal);
1105         },
1106         "Fields may not be volatile and final");
1107   }
1108 }
1109 
1110 // Standard interface. Needs to be separate from class as interfaces do not allow instance fields.
1111 // Use declared-synchronized again for 3B encoding.
1112 //
1113 // .class public interface LInterfaceFieldFlags;
1114 // .super Ljava/lang/Object;
1115 //
1116 // .field declared-synchronized public static final foo:I
1117 
1118 static const char kFieldFlagsInterfaceTestDex[] =
1119     "ZGV4CjAzNQCVMHfEimR1zZPk6hl6O9GPAYqkl3u0umFkAQAAcAAAAHhWNBIAAAAAAAAAAPQAAAAE"
1120     "AAAAcAAAAAMAAACAAAAAAAAAAAAAAAABAAAAjAAAAAAAAAAAAAAAAQAAAJQAAACwAAAAtAAAALQA"
1121     "AAC3AAAAzgAAAOIAAAAAAAAAAQAAAAIAAAABAAAAAwAAAAEAAAABAgAAAgAAAAAAAAD/////AAAA"
1122     "AOwAAAAAAAAAAUkAFUxJbnRlcmZhY2VGaWVsZEZsYWdzOwASTGphdmEvbGFuZy9PYmplY3Q7AANm"
1123     "b28AAAAAAAABAAAAAJmACAkAAAAAAAAAAQAAAAAAAAABAAAABAAAAHAAAAACAAAAAwAAAIAAAAAE"
1124     "AAAAAQAAAIwAAAAGAAAAAQAAAJQAAAACIAAABAAAALQAAAADEAAAAQAAAOgAAAAAIAAAAQAAAOwA"
1125     "AAAAEAAAAQAAAPQAAAA=";
1126 
TEST_F(DexFileVerifierTest,FieldAccessFlagsInterface)1127 TEST_F(DexFileVerifierTest, FieldAccessFlagsInterface) {
1128   VerifyModification(
1129       kFieldFlagsInterfaceTestDex,
1130       "field_flags_interface",
1131       [](DexFile* dex_file) {
1132         ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
1133       },
1134       nullptr);
1135   VerifyModification(
1136       kFieldFlagsInterfaceTestDex,
1137       "field_flags_interface",
1138       [](DexFile* dex_file) {
1139         MakeDexVersion37(dex_file);
1140         ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
1141       },
1142       nullptr);
1143 
1144   VerifyModification(
1145       kFieldFlagsInterfaceTestDex,
1146       "field_flags_interface_non_public",
1147       [](DexFile* dex_file) {
1148         ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
1149 
1150         ApplyMaskToFieldFlags(dex_file, "foo", ~kAccPublic);
1151       },
1152       nullptr);  // Should be allowed in older dex versions for backwards compatibility.
1153   VerifyModification(
1154       kFieldFlagsInterfaceTestDex,
1155       "field_flags_interface_non_public",
1156       [](DexFile* dex_file) {
1157         MakeDexVersion37(dex_file);
1158         ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
1159 
1160         ApplyMaskToFieldFlags(dex_file, "foo", ~kAccPublic);
1161       },
1162       "Interface field is not public final static");
1163 
1164   VerifyModification(
1165       kFieldFlagsInterfaceTestDex,
1166       "field_flags_interface_non_final",
1167       [](DexFile* dex_file) {
1168         ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
1169 
1170         ApplyMaskToFieldFlags(dex_file, "foo", ~kAccFinal);
1171       },
1172       nullptr);  // Should be allowed in older dex versions for backwards compatibility.
1173   VerifyModification(
1174       kFieldFlagsInterfaceTestDex,
1175       "field_flags_interface_non_final",
1176       [](DexFile* dex_file) {
1177         MakeDexVersion37(dex_file);
1178         ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
1179 
1180         ApplyMaskToFieldFlags(dex_file, "foo", ~kAccFinal);
1181       },
1182       "Interface field is not public final static");
1183 
1184   VerifyModification(
1185       kFieldFlagsInterfaceTestDex,
1186       "field_flags_interface_protected",
1187       [](DexFile* dex_file) {
1188         ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
1189 
1190         ApplyMaskToFieldFlags(dex_file, "foo", ~kAccPublic);
1191         OrMaskToFieldFlags(dex_file, "foo", kAccProtected);
1192       },
1193       nullptr);  // Should be allowed in older dex versions for backwards compatibility.
1194   VerifyModification(
1195       kFieldFlagsInterfaceTestDex,
1196       "field_flags_interface_protected",
1197       [](DexFile* dex_file) {
1198         MakeDexVersion37(dex_file);
1199         ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
1200 
1201         ApplyMaskToFieldFlags(dex_file, "foo", ~kAccPublic);
1202         OrMaskToFieldFlags(dex_file, "foo", kAccProtected);
1203       },
1204       "Interface field is not public final static");
1205 
1206   VerifyModification(
1207       kFieldFlagsInterfaceTestDex,
1208       "field_flags_interface_private",
1209       [](DexFile* dex_file) {
1210         ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
1211 
1212         ApplyMaskToFieldFlags(dex_file, "foo", ~kAccPublic);
1213         OrMaskToFieldFlags(dex_file, "foo", kAccPrivate);
1214       },
1215       nullptr);  // Should be allowed in older dex versions for backwards compatibility.
1216   VerifyModification(
1217       kFieldFlagsInterfaceTestDex,
1218       "field_flags_interface_private",
1219       [](DexFile* dex_file) {
1220         MakeDexVersion37(dex_file);
1221         ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
1222 
1223         ApplyMaskToFieldFlags(dex_file, "foo", ~kAccPublic);
1224         OrMaskToFieldFlags(dex_file, "foo", kAccPrivate);
1225       },
1226       "Interface field is not public final static");
1227 
1228   VerifyModification(
1229       kFieldFlagsInterfaceTestDex,
1230       "field_flags_interface_synthetic",
1231       [](DexFile* dex_file) {
1232         ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
1233 
1234         OrMaskToFieldFlags(dex_file, "foo", kAccSynthetic);
1235       },
1236       nullptr);
1237 
1238   constexpr uint32_t kAllFieldFlags =
1239       kAccPublic |
1240       kAccPrivate |
1241       kAccProtected |
1242       kAccStatic |
1243       kAccFinal |
1244       kAccVolatile |
1245       kAccTransient |
1246       kAccSynthetic |
1247       kAccEnum;
1248   constexpr uint32_t kInterfaceFieldFlags = kAccPublic | kAccStatic | kAccFinal | kAccSynthetic;
1249   constexpr uint32_t kInterfaceDisallowed = kAllFieldFlags &
1250                                             ~kInterfaceFieldFlags &
1251                                             ~kAccProtected &
1252                                             ~kAccPrivate;
1253   static_assert(kInterfaceDisallowed != 0, "There should be disallowed flags.");
1254 
1255   uint32_t bits = POPCOUNT(kInterfaceDisallowed);
1256   for (uint32_t i = 1; i < (1u << bits); ++i) {
1257     VerifyModification(
1258         kFieldFlagsInterfaceTestDex,
1259         "field_flags_interface_disallowed",
1260         [&](DexFile* dex_file) {
1261           ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
1262 
1263           uint32_t mask = ApplyMaskShifted(kInterfaceDisallowed, i);
1264           if ((mask & kAccProtected) != 0) {
1265             mask &= ~kAccProtected;
1266             ApplyMaskToFieldFlags(dex_file, "foo", ~kAccPublic);
1267           }
1268           OrMaskToFieldFlags(dex_file, "foo", mask);
1269         },
1270         nullptr);  // Should be allowed in older dex versions for backwards compatibility.
1271     VerifyModification(
1272         kFieldFlagsInterfaceTestDex,
1273         "field_flags_interface_disallowed",
1274         [&](DexFile* dex_file) {
1275           MakeDexVersion37(dex_file);
1276           ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
1277 
1278           uint32_t mask = ApplyMaskShifted(kInterfaceDisallowed, i);
1279           if ((mask & kAccProtected) != 0) {
1280             mask &= ~kAccProtected;
1281             ApplyMaskToFieldFlags(dex_file, "foo", ~kAccPublic);
1282           }
1283           OrMaskToFieldFlags(dex_file, "foo", mask);
1284         },
1285         "Interface field has disallowed flag");
1286   }
1287 }
1288 
1289 // Standard bad interface. Needs to be separate from class as interfaces do not allow instance
1290 // fields. Use declared-synchronized again for 3B encoding.
1291 //
1292 // .class public interface LInterfaceFieldFlags;
1293 // .super Ljava/lang/Object;
1294 //
1295 // .field declared-synchronized public final foo:I
1296 
1297 static const char kFieldFlagsInterfaceBadTestDex[] =
1298     "ZGV4CjAzNQByMUnqYKHBkUpvvNp+9CnZ2VyDkKnRN6VkAQAAcAAAAHhWNBIAAAAAAAAAAPQAAAAE"
1299     "AAAAcAAAAAMAAACAAAAAAAAAAAAAAAABAAAAjAAAAAAAAAAAAAAAAQAAAJQAAACwAAAAtAAAALQA"
1300     "AAC3AAAAzgAAAOIAAAAAAAAAAQAAAAIAAAABAAAAAwAAAAEAAAABAgAAAgAAAAAAAAD/////AAAA"
1301     "AOwAAAAAAAAAAUkAFUxJbnRlcmZhY2VGaWVsZEZsYWdzOwASTGphdmEvbGFuZy9PYmplY3Q7AANm"
1302     "b28AAAAAAAAAAQAAAJGACAkAAAAAAAAAAQAAAAAAAAABAAAABAAAAHAAAAACAAAAAwAAAIAAAAAE"
1303     "AAAAAQAAAIwAAAAGAAAAAQAAAJQAAAACIAAABAAAALQAAAADEAAAAQAAAOgAAAAAIAAAAQAAAOwA"
1304     "AAAAEAAAAQAAAPQAAAA=";
1305 
TEST_F(DexFileVerifierTest,FieldAccessFlagsInterfaceNonStatic)1306 TEST_F(DexFileVerifierTest, FieldAccessFlagsInterfaceNonStatic) {
1307   VerifyModification(
1308       kFieldFlagsInterfaceBadTestDex,
1309       "field_flags_interface_non_static",
1310       [](DexFile* dex_file) {
1311         ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
1312       },
1313       nullptr);  // Should be allowed in older dex versions for backwards compatibility.
1314   VerifyModification(
1315       kFieldFlagsInterfaceBadTestDex,
1316       "field_flags_interface_non_static",
1317       [](DexFile* dex_file) {
1318         MakeDexVersion37(dex_file);
1319         ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
1320       },
1321       "Interface field is not public final static");
1322 }
1323 
1324 // Generated from:
1325 //
1326 // .class public LTest;
1327 // .super Ljava/lang/Object;
1328 // .source "Test.java"
1329 //
1330 // .method public constructor <init>()V
1331 //     .registers 1
1332 //
1333 //     .prologue
1334 //     .line 1
1335 //     invoke-direct {p0}, Ljava/lang/Object;-><init>()V
1336 //
1337 //     return-void
1338 // .end method
1339 //
1340 // .method public static main()V
1341 //     .registers 2
1342 //
1343 //     const-string v0, "a"
1344 //     const-string v0, "b"
1345 //     const-string v0, "c"
1346 //     const-string v0, "d"
1347 //     const-string v0, "e"
1348 //     const-string v0, "f"
1349 //     const-string v0, "g"
1350 //     const-string v0, "h"
1351 //     const-string v0, "i"
1352 //     const-string v0, "j"
1353 //     const-string v0, "k"
1354 //
1355 //     .local v1, "local_var":Ljava/lang/String;
1356 //     const-string v1, "test"
1357 // .end method
1358 
1359 static const char kDebugInfoTestDex[] =
1360     "ZGV4CjAzNQCHRkHix2eIMQgvLD/0VGrlllZLo0Rb6VyUAgAAcAAAAHhWNBIAAAAAAAAAAAwCAAAU"
1361     "AAAAcAAAAAQAAADAAAAAAQAAANAAAAAAAAAAAAAAAAMAAADcAAAAAQAAAPQAAACAAQAAFAEAABQB"
1362     "AAAcAQAAJAEAADgBAABMAQAAVwEAAFoBAABdAQAAYAEAAGMBAABmAQAAaQEAAGwBAABvAQAAcgEA"
1363     "AHUBAAB4AQAAewEAAIYBAACMAQAAAQAAAAIAAAADAAAABQAAAAUAAAADAAAAAAAAAAAAAAAAAAAA"
1364     "AAAAABIAAAABAAAAAAAAAAAAAAABAAAAAQAAAAAAAAAEAAAAAAAAAPwBAAAAAAAABjxpbml0PgAG"
1365     "TFRlc3Q7ABJMamF2YS9sYW5nL09iamVjdDsAEkxqYXZhL2xhbmcvU3RyaW5nOwAJVGVzdC5qYXZh"
1366     "AAFWAAFhAAFiAAFjAAFkAAFlAAFmAAFnAAFoAAFpAAFqAAFrAAlsb2NhbF92YXIABG1haW4ABHRl"
1367     "c3QAAAABAAcOAAAAARYDARIDAAAAAQABAAEAAACUAQAABAAAAHAQAgAAAA4AAgAAAAAAAACZAQAA"
1368     "GAAAABoABgAaAAcAGgAIABoACQAaAAoAGgALABoADAAaAA0AGgAOABoADwAaABAAGgETAAAAAgAA"
1369     "gYAEpAMBCbwDAAALAAAAAAAAAAEAAAAAAAAAAQAAABQAAABwAAAAAgAAAAQAAADAAAAAAwAAAAEA"
1370     "AADQAAAABQAAAAMAAADcAAAABgAAAAEAAAD0AAAAAiAAABQAAAAUAQAAAyAAAAIAAACUAQAAASAA"
1371     "AAIAAACkAQAAACAAAAEAAAD8AQAAABAAAAEAAAAMAgAA";
1372 
TEST_F(DexFileVerifierTest,DebugInfoTypeIdxTest)1373 TEST_F(DexFileVerifierTest, DebugInfoTypeIdxTest) {
1374   {
1375     // The input dex file should be good before modification.
1376     ScratchFile tmp;
1377     std::string error_msg;
1378     std::unique_ptr<const DexFile> raw(OpenDexFileBase64(kDebugInfoTestDex,
1379                                                          tmp.GetFilename().c_str(),
1380                                                          &error_msg));
1381     ASSERT_TRUE(raw.get() != nullptr) << error_msg;
1382   }
1383 
1384   // Modify the debug information entry.
1385   VerifyModification(
1386       kDebugInfoTestDex,
1387       "debug_start_type_idx",
1388       [](DexFile* dex_file) {
1389         *(const_cast<uint8_t*>(dex_file->Begin()) + 416) = 0x14U;
1390       },
1391       "DBG_START_LOCAL type_idx");
1392 }
1393 
TEST_F(DexFileVerifierTest,SectionAlignment)1394 TEST_F(DexFileVerifierTest, SectionAlignment) {
1395   {
1396     // The input dex file should be good before modification. Any file is fine, as long as it
1397     // uses all sections.
1398     ScratchFile tmp;
1399     std::string error_msg;
1400     std::unique_ptr<const DexFile> raw(OpenDexFileBase64(kGoodTestDex,
1401                                                          tmp.GetFilename().c_str(),
1402                                                          &error_msg));
1403     ASSERT_TRUE(raw.get() != nullptr) << error_msg;
1404   }
1405 
1406   // Modify all section offsets to be unaligned.
1407   constexpr size_t kSections = 7;
1408   for (size_t i = 0; i < kSections; ++i) {
1409     VerifyModification(
1410         kGoodTestDex,
1411         "section_align",
1412         [&](DexFile* dex_file) {
1413           DexFile::Header* header = const_cast<DexFile::Header*>(
1414               reinterpret_cast<const DexFile::Header*>(dex_file->Begin()));
1415           uint32_t* off_ptr;
1416           switch (i) {
1417             case 0:
1418               off_ptr = &header->map_off_;
1419               break;
1420             case 1:
1421               off_ptr = &header->string_ids_off_;
1422               break;
1423             case 2:
1424               off_ptr = &header->type_ids_off_;
1425               break;
1426             case 3:
1427               off_ptr = &header->proto_ids_off_;
1428               break;
1429             case 4:
1430               off_ptr = &header->field_ids_off_;
1431               break;
1432             case 5:
1433               off_ptr = &header->method_ids_off_;
1434               break;
1435             case 6:
1436               off_ptr = &header->class_defs_off_;
1437               break;
1438 
1439             static_assert(kSections == 7, "kSections is wrong");
1440             default:
1441               LOG(FATAL) << "Unexpected section";
1442               UNREACHABLE();
1443           }
1444           ASSERT_TRUE(off_ptr != nullptr);
1445           ASSERT_NE(*off_ptr, 0U) << i;  // Should already contain a value (in use).
1446           (*off_ptr)++;                  // Add one, which should misalign it (all the sections
1447                                          // above are aligned by 4).
1448         },
1449         "should be aligned by 4 for");
1450   }
1451 }
1452 
1453 // Generated from
1454 //
1455 // .class LOverloading;
1456 //
1457 // .super Ljava/lang/Object;
1458 //
1459 // .method public static foo()V
1460 // .registers 1
1461 //     return-void
1462 // .end method
1463 //
1464 // .method public static foo(I)V
1465 // .registers 1
1466 //     return-void
1467 // .end method
1468 static const char kProtoOrderingTestDex[] =
1469     "ZGV4CjAzNQA1L+ABE6voQ9Lr4Ci//efB53oGnDr5PinsAQAAcAAAAHhWNBIAAAAAAAAAAFgBAAAG"
1470     "AAAAcAAAAAQAAACIAAAAAgAAAJgAAAAAAAAAAAAAAAIAAACwAAAAAQAAAMAAAAAMAQAA4AAAAOAA"
1471     "AADjAAAA8gAAAAYBAAAJAQAADQEAAAAAAAABAAAAAgAAAAMAAAADAAAAAwAAAAAAAAAEAAAAAwAA"
1472     "ABQBAAABAAAABQAAAAEAAQAFAAAAAQAAAAAAAAACAAAAAAAAAP////8AAAAASgEAAAAAAAABSQAN"
1473     "TE92ZXJsb2FkaW5nOwASTGphdmEvbGFuZy9PYmplY3Q7AAFWAAJWSQADZm9vAAAAAQAAAAAAAAAA"
1474     "AAAAAAAAAAEAAAAAAAAAAAAAAAEAAAAOAAAAAQABAAAAAAAAAAAAAQAAAA4AAAACAAAJpAIBCbgC"
1475     "AAAMAAAAAAAAAAEAAAAAAAAAAQAAAAYAAABwAAAAAgAAAAQAAACIAAAAAwAAAAIAAACYAAAABQAA"
1476     "AAIAAACwAAAABgAAAAEAAADAAAAAAiAAAAYAAADgAAAAARAAAAEAAAAUAQAAAxAAAAIAAAAcAQAA"
1477     "ASAAAAIAAAAkAQAAACAAAAEAAABKAQAAABAAAAEAAABYAQAA";
1478 
TEST_F(DexFileVerifierTest,ProtoOrdering)1479 TEST_F(DexFileVerifierTest, ProtoOrdering) {
1480   {
1481     // The input dex file should be good before modification.
1482     ScratchFile tmp;
1483     std::string error_msg;
1484     std::unique_ptr<const DexFile> raw(OpenDexFileBase64(kProtoOrderingTestDex,
1485                                                          tmp.GetFilename().c_str(),
1486                                                          &error_msg));
1487     ASSERT_TRUE(raw.get() != nullptr) << error_msg;
1488   }
1489 
1490   // Modify the order of the ProtoIds for two overloads of "foo" with the
1491   // same return type and one having longer parameter list than the other.
1492   for (size_t i = 0; i != 2; ++i) {
1493     VerifyModification(
1494         kProtoOrderingTestDex,
1495         "proto_ordering",
1496         [i](DexFile* dex_file) {
1497           uint32_t method_idx;
1498           const uint8_t* data = FindMethodData(dex_file, "foo", &method_idx);
1499           CHECK(data != nullptr);
1500           // There should be 2 methods called "foo".
1501           CHECK_LT(method_idx + 1u, dex_file->NumMethodIds());
1502           CHECK_EQ(dex_file->GetMethodId(method_idx).name_idx_,
1503                    dex_file->GetMethodId(method_idx + 1).name_idx_);
1504           CHECK_EQ(dex_file->GetMethodId(method_idx).proto_idx_ + 1u,
1505                    dex_file->GetMethodId(method_idx + 1).proto_idx_);
1506           // Their return types should be the same.
1507           uint32_t proto1_idx = dex_file->GetMethodId(method_idx).proto_idx_;
1508           const DexFile::ProtoId& proto1 = dex_file->GetProtoId(proto1_idx);
1509           const DexFile::ProtoId& proto2 = dex_file->GetProtoId(proto1_idx + 1u);
1510           CHECK_EQ(proto1.return_type_idx_, proto2.return_type_idx_);
1511           // And the first should not have any parameters while the second should have some.
1512           CHECK(!DexFileParameterIterator(*dex_file, proto1).HasNext());
1513           CHECK(DexFileParameterIterator(*dex_file, proto2).HasNext());
1514           if (i == 0) {
1515             // Swap the proto parameters and shorties to break the ordering.
1516             std::swap(const_cast<uint32_t&>(proto1.parameters_off_),
1517                       const_cast<uint32_t&>(proto2.parameters_off_));
1518             std::swap(const_cast<uint32_t&>(proto1.shorty_idx_),
1519                       const_cast<uint32_t&>(proto2.shorty_idx_));
1520           } else {
1521             // Copy the proto parameters and shorty to create duplicate proto id.
1522             const_cast<uint32_t&>(proto1.parameters_off_) = proto2.parameters_off_;
1523             const_cast<uint32_t&>(proto1.shorty_idx_) = proto2.shorty_idx_;
1524           }
1525         },
1526         "Out-of-order proto_id arguments");
1527   }
1528 }
1529 
1530 // To generate a base64 encoded Dex file version 037 from Smali files, use:
1531 //
1532 //   smali --api-level 24 -o classes.dex class1.smali [class2.smali ...]
1533 //   base64 classes.dex >classes.dex.base64
1534 
1535 // Dex file version 037 generated from:
1536 //
1537 //   .class public LB28685551;
1538 //   .super LB28685551;
1539 
1540 static const char kClassExtendsItselfTestDex[] =
1541     "ZGV4CjAzNwDeGbgRg1kb6swszpcTWrrOAALB++F4OPT0AAAAcAAAAHhWNBIAAAAAAAAAAKgAAAAB"
1542     "AAAAcAAAAAEAAAB0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAHgAAABcAAAAmAAAAJgA"
1543     "AAAAAAAAAAAAAAEAAAAAAAAAAAAAAP////8AAAAAAAAAAAAAAAALTEIyODY4NTU1MTsAAAAABgAA"
1544     "AAAAAAABAAAAAAAAAAEAAAABAAAAcAAAAAIAAAABAAAAdAAAAAYAAAABAAAAeAAAAAIgAAABAAAA"
1545     "mAAAAAAQAAABAAAAqAAAAA==";
1546 
TEST_F(DexFileVerifierTest,ClassExtendsItself)1547 TEST_F(DexFileVerifierTest, ClassExtendsItself) {
1548   VerifyModification(
1549       kClassExtendsItselfTestDex,
1550       "class_extends_itself",
1551       [](DexFile* dex_file ATTRIBUTE_UNUSED) { /* empty */ },
1552       "Class with same type idx as its superclass: '0'");
1553 }
1554 
1555 // Dex file version 037 generated from:
1556 //
1557 //   .class public LFoo;
1558 //   .super LBar;
1559 //
1560 // and:
1561 //
1562 //    .class public LBar;
1563 //    .super LFoo;
1564 
1565 static const char kClassesExtendOneAnotherTestDex[] =
1566     "ZGV4CjAzNwBXHSrwpDMwRBkg+L+JeQCuFNRLhQ86duEcAQAAcAAAAHhWNBIAAAAAAAAAANAAAAAC"
1567     "AAAAcAAAAAIAAAB4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAIAAAABcAAAAwAAAAMAA"
1568     "AADHAAAAAAAAAAEAAAABAAAAAQAAAAAAAAAAAAAA/////wAAAAAAAAAAAAAAAAAAAAABAAAAAQAA"
1569     "AAAAAAD/////AAAAAAAAAAAAAAAABUxCYXI7AAVMRm9vOwAAAAYAAAAAAAAAAQAAAAAAAAABAAAA"
1570     "AgAAAHAAAAACAAAAAgAAAHgAAAAGAAAAAgAAAIAAAAACIAAAAgAAAMAAAAAAEAAAAQAAANAAAAA=";
1571 
TEST_F(DexFileVerifierTest,ClassesExtendOneAnother)1572 TEST_F(DexFileVerifierTest, ClassesExtendOneAnother) {
1573   VerifyModification(
1574       kClassesExtendOneAnotherTestDex,
1575       "classes_extend_one_another",
1576       [](DexFile* dex_file ATTRIBUTE_UNUSED) { /* empty */ },
1577       "Invalid class definition ordering: class with type idx: '1' defined before"
1578       " superclass with type idx: '0'");
1579 }
1580 
1581 // Dex file version 037 generated from:
1582 //
1583 //   .class public LAll;
1584 //   .super LYour;
1585 //
1586 // and:
1587 //
1588 //   .class public LYour;
1589 //   .super LBase;
1590 //
1591 // and:
1592 //
1593 //   .class public LBase;
1594 //   .super LAll;
1595 
1596 static const char kCircularClassInheritanceTestDex[] =
1597     "ZGV4CjAzNwBMJxgP0SJz6oLXnKfl+J7lSEORLRwF5LNMAQAAcAAAAHhWNBIAAAAAAAAAAAABAAAD"
1598     "AAAAcAAAAAMAAAB8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAIgAAABkAAAA6AAAAOgA"
1599     "AADvAAAA9wAAAAAAAAABAAAAAgAAAAEAAAABAAAAAAAAAAAAAAD/////AAAAAAAAAAAAAAAAAgAA"
1600     "AAEAAAABAAAAAAAAAP////8AAAAAAAAAAAAAAAAAAAAAAQAAAAIAAAAAAAAA/////wAAAAAAAAAA"
1601     "AAAAAAVMQWxsOwAGTEJhc2U7AAZMWW91cjsAAAYAAAAAAAAAAQAAAAAAAAABAAAAAwAAAHAAAAAC"
1602     "AAAAAwAAAHwAAAAGAAAAAwAAAIgAAAACIAAAAwAAAOgAAAAAEAAAAQAAAAABAAA=";
1603 
TEST_F(DexFileVerifierTest,CircularClassInheritance)1604 TEST_F(DexFileVerifierTest, CircularClassInheritance) {
1605   VerifyModification(
1606       kCircularClassInheritanceTestDex,
1607       "circular_class_inheritance",
1608       [](DexFile* dex_file ATTRIBUTE_UNUSED) { /* empty */ },
1609       "Invalid class definition ordering: class with type idx: '1' defined before"
1610       " superclass with type idx: '0'");
1611 }
1612 
1613 // Dex file version 037 generated from:
1614 //
1615 //   .class public abstract interface LInterfaceImplementsItself;
1616 //   .super Ljava/lang/Object;
1617 //   .implements LInterfaceImplementsItself;
1618 
1619 static const char kInterfaceImplementsItselfTestDex[] =
1620     "ZGV4CjAzNwCKKrjatp8XbXl5S/bEVJnqaBhjZkQY4440AQAAcAAAAHhWNBIAAAAAAAAAANwAAAAC"
1621     "AAAAcAAAAAIAAAB4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAIAAAACUAAAAoAAAAKAA"
1622     "AAC9AAAAAAAAAAEAAAAAAAAAAQYAAAEAAADUAAAA/////wAAAAAAAAAAAAAAABtMSW50ZXJmYWNl"
1623     "SW1wbGVtZW50c0l0c2VsZjsAEkxqYXZhL2xhbmcvT2JqZWN0OwAAAAABAAAAAAAAAAcAAAAAAAAA"
1624     "AQAAAAAAAAABAAAAAgAAAHAAAAACAAAAAgAAAHgAAAAGAAAAAQAAAIAAAAACIAAAAgAAAKAAAAAB"
1625     "EAAAAQAAANQAAAAAEAAAAQAAANwAAAA=";
1626 
TEST_F(DexFileVerifierTest,InterfaceImplementsItself)1627 TEST_F(DexFileVerifierTest, InterfaceImplementsItself) {
1628   VerifyModification(
1629       kInterfaceImplementsItselfTestDex,
1630       "interface_implements_itself",
1631       [](DexFile* dex_file ATTRIBUTE_UNUSED) { /* empty */ },
1632       "Class with same type idx as implemented interface: '0'");
1633 }
1634 
1635 // Dex file version 037 generated from:
1636 //
1637 //   .class public abstract interface LPing;
1638 //   .super Ljava/lang/Object;
1639 //   .implements LPong;
1640 //
1641 // and:
1642 //
1643 //   .class public abstract interface LPong;
1644 //   .super Ljava/lang/Object;
1645 //   .implements LPing;
1646 
1647 static const char kInterfacesImplementOneAnotherTestDex[] =
1648     "ZGV4CjAzNwD0Kk9sxlYdg3Dy1Cff0gQCuJAQfEP6ohZUAQAAcAAAAHhWNBIAAAAAAAAAAPwAAAAD"
1649     "AAAAcAAAAAMAAAB8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAIgAAACMAAAAyAAAAMgA"
1650     "AADQAAAA2AAAAAAAAAABAAAAAgAAAAEAAAABBgAAAgAAAOwAAAD/////AAAAAAAAAAAAAAAAAAAA"
1651     "AAEGAAACAAAA9AAAAP////8AAAAAAAAAAAAAAAAGTFBpbmc7AAZMUG9uZzsAEkxqYXZhL2xhbmcv"
1652     "T2JqZWN0OwABAAAAAAAAAAEAAAABAAAABwAAAAAAAAABAAAAAAAAAAEAAAADAAAAcAAAAAIAAAAD"
1653     "AAAAfAAAAAYAAAACAAAAiAAAAAIgAAADAAAAyAAAAAEQAAACAAAA7AAAAAAQAAABAAAA/AAAAA==";
1654 
TEST_F(DexFileVerifierTest,InterfacesImplementOneAnother)1655 TEST_F(DexFileVerifierTest, InterfacesImplementOneAnother) {
1656   VerifyModification(
1657       kInterfacesImplementOneAnotherTestDex,
1658       "interfaces_implement_one_another",
1659       [](DexFile* dex_file ATTRIBUTE_UNUSED) { /* empty */ },
1660       "Invalid class definition ordering: class with type idx: '1' defined before"
1661       " implemented interface with type idx: '0'");
1662 }
1663 
1664 // Dex file version 037 generated from:
1665 //
1666 //   .class public abstract interface LA;
1667 //   .super Ljava/lang/Object;
1668 //   .implements LB;
1669 //
1670 // and:
1671 //
1672 //   .class public abstract interface LB;
1673 //   .super Ljava/lang/Object;
1674 //   .implements LC;
1675 //
1676 // and:
1677 //
1678 //   .class public abstract interface LC;
1679 //   .super Ljava/lang/Object;
1680 //   .implements LA;
1681 
1682 static const char kCircularInterfaceImplementationTestDex[] =
1683     "ZGV4CjAzNwCzKmD5Fol6XAU6ichYHcUTIP7Z7MdTcEmEAQAAcAAAAHhWNBIAAAAAAAAAACwBAAAE"
1684     "AAAAcAAAAAQAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAJAAAACUAAAA8AAAAPAA"
1685     "AAD1AAAA+gAAAP8AAAAAAAAAAQAAAAIAAAADAAAAAgAAAAEGAAADAAAAHAEAAP////8AAAAAAAAA"
1686     "AAAAAAABAAAAAQYAAAMAAAAUAQAA/////wAAAAAAAAAAAAAAAAAAAAABBgAAAwAAACQBAAD/////"
1687     "AAAAAAAAAAAAAAAAA0xBOwADTEI7AANMQzsAEkxqYXZhL2xhbmcvT2JqZWN0OwAAAQAAAAIAAAAB"
1688     "AAAAAAAAAAEAAAABAAAABwAAAAAAAAABAAAAAAAAAAEAAAAEAAAAcAAAAAIAAAAEAAAAgAAAAAYA"
1689     "AAADAAAAkAAAAAIgAAAEAAAA8AAAAAEQAAADAAAAFAEAAAAQAAABAAAALAEAAA==";
1690 
TEST_F(DexFileVerifierTest,CircularInterfaceImplementation)1691 TEST_F(DexFileVerifierTest, CircularInterfaceImplementation) {
1692   VerifyModification(
1693       kCircularInterfaceImplementationTestDex,
1694       "circular_interface_implementation",
1695       [](DexFile* dex_file ATTRIBUTE_UNUSED) { /* empty */ },
1696       "Invalid class definition ordering: class with type idx: '2' defined before"
1697       " implemented interface with type idx: '0'");
1698 }
1699 
1700 }  // namespace art
1701