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