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 "dex_file_types.h"
30 #include "leb128.h"
31 #include "scoped_thread_state_change-inl.h"
32 #include "thread-inl.h"
33 #include "utils.h"
34
35 namespace art {
36
37 // Make the Dex file version 37.
MakeDexVersion37(DexFile * dex_file)38 static void MakeDexVersion37(DexFile* dex_file) {
39 size_t offset = OFFSETOF_MEMBER(DexFile::Header, magic_) + 6;
40 CHECK_EQ(*(dex_file->Begin() + offset), '5');
41 *(const_cast<uint8_t*>(dex_file->Begin()) + offset) = '7';
42 }
43
FixUpChecksum(uint8_t * dex_file)44 static void FixUpChecksum(uint8_t* dex_file) {
45 DexFile::Header* header = reinterpret_cast<DexFile::Header*>(dex_file);
46 uint32_t expected_size = header->file_size_;
47 uint32_t adler_checksum = adler32(0L, Z_NULL, 0);
48 const uint32_t non_sum = sizeof(DexFile::Header::magic_) + sizeof(DexFile::Header::checksum_);
49 const uint8_t* non_sum_ptr = dex_file + non_sum;
50 adler_checksum = adler32(adler_checksum, non_sum_ptr, expected_size - non_sum);
51 header->checksum_ = adler_checksum;
52 }
53
54 class DexFileVerifierTest : public CommonRuntimeTest {
55 protected:
GetDexFile(const uint8_t * dex_bytes,size_t length)56 DexFile* GetDexFile(const uint8_t* dex_bytes, size_t length) {
57 return new DexFile(dex_bytes, length, "tmp", 0, nullptr);
58 }
59
VerifyModification(const char * dex_file_base64_content,const char * location,const std::function<void (DexFile *)> & f,const char * expected_error)60 void VerifyModification(const char* dex_file_base64_content,
61 const char* location,
62 const std::function<void(DexFile*)>& f,
63 const char* expected_error) {
64 size_t length;
65 std::unique_ptr<uint8_t[]> dex_bytes(DecodeBase64(dex_file_base64_content, &length));
66 CHECK(dex_bytes != nullptr);
67 // Note: `dex_file` will be destroyed before `dex_bytes`.
68 std::unique_ptr<DexFile> dex_file(GetDexFile(dex_bytes.get(), length));
69 f(dex_file.get());
70 FixUpChecksum(const_cast<uint8_t*>(dex_file->Begin()));
71
72 static constexpr bool kVerifyChecksum = true;
73 std::string error_msg;
74 bool success = DexFileVerifier::Verify(dex_file.get(),
75 dex_file->Begin(),
76 dex_file->Size(),
77 location,
78 kVerifyChecksum,
79 &error_msg);
80 if (expected_error == nullptr) {
81 EXPECT_TRUE(success) << error_msg;
82 } else {
83 EXPECT_FALSE(success) << "Expected " << expected_error;
84 if (!success) {
85 EXPECT_NE(error_msg.find(expected_error), std::string::npos) << error_msg;
86 }
87 }
88 }
89 };
90
OpenDexFileBase64(const char * base64,const char * location,std::string * error_msg)91 static std::unique_ptr<const DexFile> OpenDexFileBase64(const char* base64,
92 const char* location,
93 std::string* error_msg) {
94 // decode base64
95 CHECK(base64 != nullptr);
96 size_t length;
97 std::unique_ptr<uint8_t[]> dex_bytes(DecodeBase64(base64, &length));
98 CHECK(dex_bytes.get() != nullptr);
99
100 // write to provided file
101 std::unique_ptr<File> file(OS::CreateEmptyFile(location));
102 CHECK(file.get() != nullptr);
103 if (!file->WriteFully(dex_bytes.get(), length)) {
104 PLOG(FATAL) << "Failed to write base64 as dex file";
105 }
106 if (file->FlushCloseOrErase() != 0) {
107 PLOG(FATAL) << "Could not flush and close test file.";
108 }
109 file.reset();
110
111 // read dex file
112 ScopedObjectAccess soa(Thread::Current());
113 std::vector<std::unique_ptr<const DexFile>> tmp;
114 bool success = DexFile::Open(location, location, true, error_msg, &tmp);
115 CHECK(success) << error_msg;
116 EXPECT_EQ(1U, tmp.size());
117 std::unique_ptr<const DexFile> dex_file = std::move(tmp[0]);
118 EXPECT_EQ(PROT_READ, dex_file->GetPermissions());
119 EXPECT_TRUE(dex_file->IsReadOnly());
120 return dex_file;
121 }
122
123 // To generate a base64 encoded Dex file (such as kGoodTestDex, below)
124 // from Smali files, use:
125 //
126 // smali -o classes.dex class1.smali [class2.smali ...]
127 // base64 classes.dex >classes.dex.base64
128
129 // For reference.
130 static const char kGoodTestDex[] =
131 "ZGV4CjAzNQDrVbyVkxX1HljTznNf95AglkUAhQuFtmKkAgAAcAAAAHhWNBIAAAAAAAAAAAQCAAAN"
132 "AAAAcAAAAAYAAACkAAAAAgAAALwAAAABAAAA1AAAAAQAAADcAAAAAQAAAPwAAACIAQAAHAEAAFoB"
133 "AABiAQAAagEAAIEBAACVAQAAqQEAAL0BAADDAQAAzgEAANEBAADVAQAA2gEAAN8BAAABAAAAAgAA"
134 "AAMAAAAEAAAABQAAAAgAAAAIAAAABQAAAAAAAAAJAAAABQAAAFQBAAAEAAEACwAAAAAAAAAAAAAA"
135 "AAAAAAoAAAABAAEADAAAAAIAAAAAAAAAAAAAAAEAAAACAAAAAAAAAAcAAAAAAAAA8wEAAAAAAAAB"
136 "AAEAAQAAAOgBAAAEAAAAcBADAAAADgACAAAAAgAAAO0BAAAIAAAAYgAAABoBBgBuIAIAEAAOAAEA"
137 "AAADAAY8aW5pdD4ABkxUZXN0OwAVTGphdmEvaW8vUHJpbnRTdHJlYW07ABJMamF2YS9sYW5nL09i"
138 "amVjdDsAEkxqYXZhL2xhbmcvU3RyaW5nOwASTGphdmEvbGFuZy9TeXN0ZW07AARUZXN0AAlUZXN0"
139 "LmphdmEAAVYAAlZMAANmb28AA291dAAHcHJpbnRsbgABAAcOAAMABw54AAAAAgAAgYAEnAIBCbQC"
140 "AAAADQAAAAAAAAABAAAAAAAAAAEAAAANAAAAcAAAAAIAAAAGAAAApAAAAAMAAAACAAAAvAAAAAQA"
141 "AAABAAAA1AAAAAUAAAAEAAAA3AAAAAYAAAABAAAA/AAAAAEgAAACAAAAHAEAAAEQAAABAAAAVAEA"
142 "AAIgAAANAAAAWgEAAAMgAAACAAAA6AEAAAAgAAABAAAA8wEAAAAQAAABAAAABAIAAA==";
143
TEST_F(DexFileVerifierTest,GoodDex)144 TEST_F(DexFileVerifierTest, GoodDex) {
145 ScratchFile tmp;
146 std::string error_msg;
147 std::unique_ptr<const DexFile> raw(OpenDexFileBase64(kGoodTestDex, tmp.GetFilename().c_str(),
148 &error_msg));
149 ASSERT_TRUE(raw.get() != nullptr) << error_msg;
150 }
151
TEST_F(DexFileVerifierTest,MethodId)152 TEST_F(DexFileVerifierTest, MethodId) {
153 // Class idx error.
154 VerifyModification(
155 kGoodTestDex,
156 "method_id_class_idx",
157 [](DexFile* dex_file) {
158 DexFile::MethodId* method_id = const_cast<DexFile::MethodId*>(&dex_file->GetMethodId(0));
159 method_id->class_idx_ = dex::TypeIndex(0xFF);
160 },
161 "could not find declaring class for direct method index 0");
162
163 // Proto idx error.
164 VerifyModification(
165 kGoodTestDex,
166 "method_id_proto_idx",
167 [](DexFile* dex_file) {
168 DexFile::MethodId* method_id = const_cast<DexFile::MethodId*>(&dex_file->GetMethodId(0));
169 method_id->proto_idx_ = 0xFF;
170 },
171 "inter_method_id_item proto_idx");
172
173 // Name idx error.
174 VerifyModification(
175 kGoodTestDex,
176 "method_id_name_idx",
177 [](DexFile* dex_file) {
178 DexFile::MethodId* method_id = const_cast<DexFile::MethodId*>(&dex_file->GetMethodId(0));
179 method_id->name_idx_ = dex::StringIndex(0xFF);
180 },
181 "String index not available for method flags verification");
182 }
183
184 // Method flags test class generated from the following smali code. The declared-synchronized
185 // flags are there to enforce a 3-byte uLEB128 encoding so we don't have to relayout
186 // the code, but we need to remove them before doing tests.
187 //
188 // .class public LMethodFlags;
189 // .super Ljava/lang/Object;
190 //
191 // .method public static constructor <clinit>()V
192 // .registers 1
193 // return-void
194 // .end method
195 //
196 // .method public constructor <init>()V
197 // .registers 1
198 // return-void
199 // .end method
200 //
201 // .method private declared-synchronized foo()V
202 // .registers 1
203 // return-void
204 // .end method
205 //
206 // .method public declared-synchronized bar()V
207 // .registers 1
208 // return-void
209 // .end method
210
211 static const char kMethodFlagsTestDex[] =
212 "ZGV4CjAzNQCyOQrJaDBwiIWv5MIuYKXhxlLLsQcx5SwgAgAAcAAAAHhWNBIAAAAAAAAAAJgBAAAH"
213 "AAAAcAAAAAMAAACMAAAAAQAAAJgAAAAAAAAAAAAAAAQAAACkAAAAAQAAAMQAAAA8AQAA5AAAAOQA"
214 "AADuAAAA9gAAAAUBAAAZAQAAHAEAACEBAAACAAAAAwAAAAQAAAAEAAAAAgAAAAAAAAAAAAAAAAAA"
215 "AAAAAAABAAAAAAAAAAUAAAAAAAAABgAAAAAAAAABAAAAAQAAAAAAAAD/////AAAAAHoBAAAAAAAA"
216 "CDxjbGluaXQ+AAY8aW5pdD4ADUxNZXRob2RGbGFnczsAEkxqYXZhL2xhbmcvT2JqZWN0OwABVgAD"
217 "YmFyAANmb28AAAAAAAAAAQAAAAAAAAAAAAAAAQAAAA4AAAABAAEAAAAAAAAAAAABAAAADgAAAAEA"
218 "AQAAAAAAAAAAAAEAAAAOAAAAAQABAAAAAAAAAAAAAQAAAA4AAAADAQCJgASsAgGBgATAAgKCgAjU"
219 "AgKBgAjoAgAACwAAAAAAAAABAAAAAAAAAAEAAAAHAAAAcAAAAAIAAAADAAAAjAAAAAMAAAABAAAA"
220 "mAAAAAUAAAAEAAAApAAAAAYAAAABAAAAxAAAAAIgAAAHAAAA5AAAAAMQAAABAAAAKAEAAAEgAAAE"
221 "AAAALAEAAAAgAAABAAAAegEAAAAQAAABAAAAmAEAAA==";
222
223 // Find the method data for the first method with the given name (from class 0). Note: the pointer
224 // is to the access flags, so that the caller doesn't have to handle the leb128-encoded method-index
225 // delta.
FindMethodData(const DexFile * dex_file,const char * name,uint32_t * method_idx=nullptr)226 static const uint8_t* FindMethodData(const DexFile* dex_file,
227 const char* name,
228 /*out*/ uint32_t* method_idx = nullptr) {
229 const DexFile::ClassDef& class_def = dex_file->GetClassDef(0);
230 const uint8_t* class_data = dex_file->GetClassData(class_def);
231
232 ClassDataItemIterator it(*dex_file, class_data);
233
234 const uint8_t* trailing = class_data;
235 // Need to manually decode the four entries. DataPointer() doesn't work for this, as the first
236 // element has already been loaded into the iterator.
237 DecodeUnsignedLeb128(&trailing);
238 DecodeUnsignedLeb128(&trailing);
239 DecodeUnsignedLeb128(&trailing);
240 DecodeUnsignedLeb128(&trailing);
241
242 // Skip all fields.
243 while (it.HasNextStaticField() || it.HasNextInstanceField()) {
244 trailing = it.DataPointer();
245 it.Next();
246 }
247
248 while (it.HasNextDirectMethod() || it.HasNextVirtualMethod()) {
249 uint32_t method_index = it.GetMemberIndex();
250 dex::StringIndex name_index = dex_file->GetMethodId(method_index).name_idx_;
251 const DexFile::StringId& string_id = dex_file->GetStringId(name_index);
252 const char* str = dex_file->GetStringData(string_id);
253 if (strcmp(name, str) == 0) {
254 if (method_idx != nullptr) {
255 *method_idx = method_index;
256 }
257 DecodeUnsignedLeb128(&trailing);
258 return trailing;
259 }
260
261 trailing = it.DataPointer();
262 it.Next();
263 }
264
265 return nullptr;
266 }
267
268 // Set the method flags to the given value.
SetMethodFlags(DexFile * dex_file,const char * method,uint32_t mask)269 static void SetMethodFlags(DexFile* dex_file, const char* method, uint32_t mask) {
270 uint8_t* method_flags_ptr = const_cast<uint8_t*>(FindMethodData(dex_file, method));
271 CHECK(method_flags_ptr != nullptr) << method;
272
273 // Unroll this, as we only have three bytes, anyways.
274 uint8_t base1 = static_cast<uint8_t>(mask & 0x7F);
275 *(method_flags_ptr++) = (base1 | 0x80);
276 mask >>= 7;
277
278 uint8_t base2 = static_cast<uint8_t>(mask & 0x7F);
279 *(method_flags_ptr++) = (base2 | 0x80);
280 mask >>= 7;
281
282 uint8_t base3 = static_cast<uint8_t>(mask & 0x7F);
283 *method_flags_ptr = base3;
284 }
285
GetMethodFlags(DexFile * dex_file,const char * method)286 static uint32_t GetMethodFlags(DexFile* dex_file, const char* method) {
287 const uint8_t* method_flags_ptr = const_cast<uint8_t*>(FindMethodData(dex_file, method));
288 CHECK(method_flags_ptr != nullptr) << method;
289 return DecodeUnsignedLeb128(&method_flags_ptr);
290 }
291
292 // Apply the given mask to method flags.
ApplyMaskToMethodFlags(DexFile * dex_file,const char * method,uint32_t mask)293 static void ApplyMaskToMethodFlags(DexFile* dex_file, const char* method, uint32_t mask) {
294 uint32_t value = GetMethodFlags(dex_file, method);
295 value &= mask;
296 SetMethodFlags(dex_file, method, value);
297 }
298
299 // Apply the given mask to method flags.
OrMaskToMethodFlags(DexFile * dex_file,const char * method,uint32_t mask)300 static void OrMaskToMethodFlags(DexFile* dex_file, const char* method, uint32_t mask) {
301 uint32_t value = GetMethodFlags(dex_file, method);
302 value |= mask;
303 SetMethodFlags(dex_file, method, value);
304 }
305
306 // Set code_off to 0 for the method.
RemoveCode(DexFile * dex_file,const char * method)307 static void RemoveCode(DexFile* dex_file, const char* method) {
308 const uint8_t* ptr = FindMethodData(dex_file, method);
309 // Next is flags, pass.
310 DecodeUnsignedLeb128(&ptr);
311
312 // Figure out how many bytes the code_off is.
313 const uint8_t* tmp = ptr;
314 DecodeUnsignedLeb128(&tmp);
315 size_t bytes = tmp - ptr;
316
317 uint8_t* mod = const_cast<uint8_t*>(ptr);
318 for (size_t i = 1; i < bytes; ++i) {
319 *(mod++) = 0x80;
320 }
321 *mod = 0x00;
322 }
323
TEST_F(DexFileVerifierTest,MethodAccessFlagsBase)324 TEST_F(DexFileVerifierTest, MethodAccessFlagsBase) {
325 // Check that it's OK when the wrong declared-synchronized flag is removed from "foo."
326 VerifyModification(
327 kMethodFlagsTestDex,
328 "method_flags_ok",
329 [](DexFile* dex_file) {
330 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
331 ApplyMaskToMethodFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
332 },
333 nullptr);
334 }
335
TEST_F(DexFileVerifierTest,MethodAccessFlagsConstructors)336 TEST_F(DexFileVerifierTest, MethodAccessFlagsConstructors) {
337 // Make sure we still accept constructors without their flags.
338 VerifyModification(
339 kMethodFlagsTestDex,
340 "method_flags_missing_constructor_tag_ok",
341 [](DexFile* dex_file) {
342 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
343 ApplyMaskToMethodFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
344
345 ApplyMaskToMethodFlags(dex_file, "<init>", ~kAccConstructor);
346 ApplyMaskToMethodFlags(dex_file, "<clinit>", ~kAccConstructor);
347 },
348 nullptr);
349
350 constexpr const char* kConstructors[] = { "<clinit>", "<init>"};
351 for (size_t i = 0; i < 2; ++i) {
352 // Constructor with code marked native.
353 VerifyModification(
354 kMethodFlagsTestDex,
355 "method_flags_constructor_native",
356 [&](DexFile* dex_file) {
357 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
358 ApplyMaskToMethodFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
359
360 OrMaskToMethodFlags(dex_file, kConstructors[i], kAccNative);
361 },
362 "has code, but is marked native or abstract");
363 // Constructor with code marked abstract.
364 VerifyModification(
365 kMethodFlagsTestDex,
366 "method_flags_constructor_abstract",
367 [&](DexFile* dex_file) {
368 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
369 ApplyMaskToMethodFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
370
371 OrMaskToMethodFlags(dex_file, kConstructors[i], kAccAbstract);
372 },
373 "has code, but is marked native or abstract");
374 // Constructor as-is without code.
375 VerifyModification(
376 kMethodFlagsTestDex,
377 "method_flags_constructor_nocode",
378 [&](DexFile* dex_file) {
379 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
380 ApplyMaskToMethodFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
381
382 RemoveCode(dex_file, kConstructors[i]);
383 },
384 "has no code, but is not marked native or abstract");
385 // Constructor without code marked native.
386 VerifyModification(
387 kMethodFlagsTestDex,
388 "method_flags_constructor_native_nocode",
389 [&](DexFile* dex_file) {
390 MakeDexVersion37(dex_file);
391 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
392 ApplyMaskToMethodFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
393
394 OrMaskToMethodFlags(dex_file, kConstructors[i], kAccNative);
395 RemoveCode(dex_file, kConstructors[i]);
396 },
397 "must not be abstract or native");
398 // Constructor without code marked abstract.
399 VerifyModification(
400 kMethodFlagsTestDex,
401 "method_flags_constructor_abstract_nocode",
402 [&](DexFile* dex_file) {
403 MakeDexVersion37(dex_file);
404 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
405 ApplyMaskToMethodFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
406
407 OrMaskToMethodFlags(dex_file, kConstructors[i], kAccAbstract);
408 RemoveCode(dex_file, kConstructors[i]);
409 },
410 "must not be abstract or native");
411 }
412 // <init> may only have (modulo ignored):
413 // kAccPrivate | kAccProtected | kAccPublic | kAccStrict | kAccVarargs | kAccSynthetic
414 static constexpr uint32_t kInitAllowed[] = {
415 0,
416 kAccPrivate,
417 kAccProtected,
418 kAccPublic,
419 kAccStrict,
420 kAccVarargs,
421 kAccSynthetic
422 };
423 for (size_t i = 0; i < arraysize(kInitAllowed); ++i) {
424 VerifyModification(
425 kMethodFlagsTestDex,
426 "init_allowed_flags",
427 [&](DexFile* dex_file) {
428 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
429 ApplyMaskToMethodFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
430
431 ApplyMaskToMethodFlags(dex_file, "<init>", ~kAccPublic);
432 OrMaskToMethodFlags(dex_file, "<init>", kInitAllowed[i]);
433 },
434 nullptr);
435 }
436 // Only one of public-private-protected.
437 for (size_t i = 1; i < 8; ++i) {
438 if (POPCOUNT(i) < 2) {
439 continue;
440 }
441 // Technically the flags match, but just be defensive here.
442 uint32_t mask = ((i & 1) != 0 ? kAccPrivate : 0) |
443 ((i & 2) != 0 ? kAccProtected : 0) |
444 ((i & 4) != 0 ? kAccPublic : 0);
445 VerifyModification(
446 kMethodFlagsTestDex,
447 "init_one_of_ppp",
448 [&](DexFile* dex_file) {
449 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
450 ApplyMaskToMethodFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
451
452 ApplyMaskToMethodFlags(dex_file, "<init>", ~kAccPublic);
453 OrMaskToMethodFlags(dex_file, "<init>", mask);
454 },
455 "Method may have only one of public/protected/private");
456 }
457 // <init> doesn't allow
458 // kAccStatic | kAccFinal | kAccSynchronized | kAccBridge
459 // Need to handle static separately as it has its own error message.
460 VerifyModification(
461 kMethodFlagsTestDex,
462 "init_not_allowed_flags",
463 [&](DexFile* dex_file) {
464 MakeDexVersion37(dex_file);
465 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
466 ApplyMaskToMethodFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
467
468 ApplyMaskToMethodFlags(dex_file, "<init>", ~kAccPublic);
469 OrMaskToMethodFlags(dex_file, "<init>", kAccStatic);
470 },
471 "Constructor 1(LMethodFlags;.<init>) is not flagged correctly wrt/ static");
472 static constexpr uint32_t kInitNotAllowed[] = {
473 kAccFinal,
474 kAccSynchronized,
475 kAccBridge
476 };
477 for (size_t i = 0; i < arraysize(kInitNotAllowed); ++i) {
478 VerifyModification(
479 kMethodFlagsTestDex,
480 "init_not_allowed_flags",
481 [&](DexFile* dex_file) {
482 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
483 ApplyMaskToMethodFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
484
485 ApplyMaskToMethodFlags(dex_file, "<init>", ~kAccPublic);
486 OrMaskToMethodFlags(dex_file, "<init>", kInitNotAllowed[i]);
487 },
488 "Constructor 1(LMethodFlags;.<init>) flagged inappropriately");
489 }
490 }
491
TEST_F(DexFileVerifierTest,MethodAccessFlagsMethods)492 TEST_F(DexFileVerifierTest, MethodAccessFlagsMethods) {
493 constexpr const char* kMethods[] = { "foo", "bar"};
494 for (size_t i = 0; i < arraysize(kMethods); ++i) {
495 // Make sure we reject non-constructors marked as constructors.
496 VerifyModification(
497 kMethodFlagsTestDex,
498 "method_flags_non_constructor",
499 [&](DexFile* dex_file) {
500 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
501 ApplyMaskToMethodFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
502
503 OrMaskToMethodFlags(dex_file, kMethods[i], kAccConstructor);
504 },
505 "is marked constructor, but doesn't match name");
506
507 VerifyModification(
508 kMethodFlagsTestDex,
509 "method_flags_native_with_code",
510 [&](DexFile* dex_file) {
511 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
512 ApplyMaskToMethodFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
513
514 OrMaskToMethodFlags(dex_file, kMethods[i], kAccNative);
515 },
516 "has code, but is marked native or abstract");
517
518 VerifyModification(
519 kMethodFlagsTestDex,
520 "method_flags_abstract_with_code",
521 [&](DexFile* dex_file) {
522 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
523 ApplyMaskToMethodFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
524
525 OrMaskToMethodFlags(dex_file, kMethods[i], kAccAbstract);
526 },
527 "has code, but is marked native or abstract");
528
529 VerifyModification(
530 kMethodFlagsTestDex,
531 "method_flags_non_abstract_native_no_code",
532 [&](DexFile* dex_file) {
533 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
534 ApplyMaskToMethodFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
535
536 RemoveCode(dex_file, kMethods[i]);
537 },
538 "has no code, but is not marked native or abstract");
539
540 // Abstract methods may not have the following flags.
541 constexpr uint32_t kAbstractDisallowed[] = {
542 kAccPrivate,
543 kAccStatic,
544 kAccFinal,
545 kAccNative,
546 kAccStrict,
547 kAccSynchronized,
548 };
549 for (size_t j = 0; j < arraysize(kAbstractDisallowed); ++j) {
550 VerifyModification(
551 kMethodFlagsTestDex,
552 "method_flags_abstract_and_disallowed_no_code",
553 [&](DexFile* dex_file) {
554 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
555 ApplyMaskToMethodFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
556
557 RemoveCode(dex_file, kMethods[i]);
558
559 // Can't check private and static with foo, as it's in the virtual list and gives a
560 // different error.
561 if (((GetMethodFlags(dex_file, kMethods[i]) & kAccPublic) != 0) &&
562 ((kAbstractDisallowed[j] & (kAccPrivate | kAccStatic)) != 0)) {
563 // Use another breaking flag.
564 OrMaskToMethodFlags(dex_file, kMethods[i], kAccAbstract | kAccFinal);
565 } else {
566 OrMaskToMethodFlags(dex_file, kMethods[i], kAccAbstract | kAbstractDisallowed[j]);
567 }
568 },
569 "has disallowed access flags");
570 }
571
572 // Only one of public-private-protected.
573 for (size_t j = 1; j < 8; ++j) {
574 if (POPCOUNT(j) < 2) {
575 continue;
576 }
577 // Technically the flags match, but just be defensive here.
578 uint32_t mask = ((j & 1) != 0 ? kAccPrivate : 0) |
579 ((j & 2) != 0 ? kAccProtected : 0) |
580 ((j & 4) != 0 ? kAccPublic : 0);
581 VerifyModification(
582 kMethodFlagsTestDex,
583 "method_flags_one_of_ppp",
584 [&](DexFile* dex_file) {
585 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
586 ApplyMaskToMethodFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
587
588 ApplyMaskToMethodFlags(dex_file, kMethods[i], ~kAccPublic);
589 OrMaskToMethodFlags(dex_file, kMethods[i], mask);
590 },
591 "Method may have only one of public/protected/private");
592 }
593 }
594 }
595
TEST_F(DexFileVerifierTest,MethodAccessFlagsIgnoredOK)596 TEST_F(DexFileVerifierTest, MethodAccessFlagsIgnoredOK) {
597 constexpr const char* kMethods[] = { "<clinit>", "<init>", "foo", "bar"};
598 for (size_t i = 0; i < arraysize(kMethods); ++i) {
599 // All interesting method flags, other flags are to be ignored.
600 constexpr uint32_t kAllMethodFlags =
601 kAccPublic |
602 kAccPrivate |
603 kAccProtected |
604 kAccStatic |
605 kAccFinal |
606 kAccSynchronized |
607 kAccBridge |
608 kAccVarargs |
609 kAccNative |
610 kAccAbstract |
611 kAccStrict |
612 kAccSynthetic;
613 constexpr uint32_t kIgnoredMask = ~kAllMethodFlags & 0xFFFF;
614 VerifyModification(
615 kMethodFlagsTestDex,
616 "method_flags_ignored",
617 [&](DexFile* dex_file) {
618 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
619 ApplyMaskToMethodFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
620
621 OrMaskToMethodFlags(dex_file, kMethods[i], kIgnoredMask);
622 },
623 nullptr);
624 }
625 }
626
TEST_F(DexFileVerifierTest,B28552165)627 TEST_F(DexFileVerifierTest, B28552165) {
628 // Regression test for bad error string retrieval in different situations.
629 // Using invalid access flags to trigger the error.
630 VerifyModification(
631 kMethodFlagsTestDex,
632 "b28552165",
633 [](DexFile* dex_file) {
634 OrMaskToMethodFlags(dex_file, "foo", kAccPublic | kAccProtected);
635 },
636 "Method may have only one of public/protected/private, LMethodFlags;.foo");
637 }
638
639 // Set of dex files for interface method tests. As it's not as easy to mutate method names, it's
640 // just easier to break up bad cases.
641
642 // Standard interface. Use declared-synchronized again for 3B encoding.
643 //
644 // .class public interface LInterfaceMethodFlags;
645 // .super Ljava/lang/Object;
646 //
647 // .method public static constructor <clinit>()V
648 // .registers 1
649 // return-void
650 // .end method
651 //
652 // .method public abstract declared-synchronized foo()V
653 // .end method
654 static const char kMethodFlagsInterface[] =
655 "ZGV4CjAzNQCOM0odZ5bws1d9GSmumXaK5iE/7XxFpOm8AQAAcAAAAHhWNBIAAAAAAAAAADQBAAAF"
656 "AAAAcAAAAAMAAACEAAAAAQAAAJAAAAAAAAAAAAAAAAIAAACcAAAAAQAAAKwAAADwAAAAzAAAAMwA"
657 "AADWAAAA7gAAAAIBAAAFAQAAAQAAAAIAAAADAAAAAwAAAAIAAAAAAAAAAAAAAAAAAAAAAAAABAAA"
658 "AAAAAAABAgAAAQAAAAAAAAD/////AAAAACIBAAAAAAAACDxjbGluaXQ+ABZMSW50ZXJmYWNlTWV0"
659 "aG9kRmxhZ3M7ABJMamF2YS9sYW5nL09iamVjdDsAAVYAA2ZvbwAAAAAAAAABAAAAAAAAAAAAAAAB"
660 "AAAADgAAAAEBAImABJACAYGICAAAAAALAAAAAAAAAAEAAAAAAAAAAQAAAAUAAABwAAAAAgAAAAMA"
661 "AACEAAAAAwAAAAEAAACQAAAABQAAAAIAAACcAAAABgAAAAEAAACsAAAAAiAAAAUAAADMAAAAAxAA"
662 "AAEAAAAMAQAAASAAAAEAAAAQAQAAACAAAAEAAAAiAQAAABAAAAEAAAA0AQAA";
663
664 // To simplify generation of interesting "sub-states" of src_value, allow a "simple" mask to apply
665 // 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)666 static uint32_t ApplyMaskShifted(uint32_t src_value, uint32_t mask) {
667 uint32_t result = 0;
668 uint32_t mask_index = 0;
669 while (src_value != 0) {
670 uint32_t index = CTZ(src_value);
671 if (((src_value & (1 << index)) != 0) &&
672 ((mask & (1 << mask_index)) != 0)) {
673 result |= (1 << index);
674 }
675 src_value &= ~(1 << index);
676 mask_index++;
677 }
678 return result;
679 }
680
TEST_F(DexFileVerifierTest,MethodAccessFlagsInterfaces)681 TEST_F(DexFileVerifierTest, MethodAccessFlagsInterfaces) {
682 VerifyModification(
683 kMethodFlagsInterface,
684 "method_flags_interface_ok",
685 [](DexFile* dex_file) {
686 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
687 },
688 nullptr);
689 VerifyModification(
690 kMethodFlagsInterface,
691 "method_flags_interface_ok37",
692 [](DexFile* dex_file) {
693 MakeDexVersion37(dex_file);
694 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
695 },
696 nullptr);
697
698 VerifyModification(
699 kMethodFlagsInterface,
700 "method_flags_interface_non_public",
701 [](DexFile* dex_file) {
702 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
703
704 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccPublic);
705 },
706 nullptr); // Should be allowed in older dex versions for backwards compatibility.
707 VerifyModification(
708 kMethodFlagsInterface,
709 "method_flags_interface_non_public",
710 [](DexFile* dex_file) {
711 MakeDexVersion37(dex_file);
712 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
713
714 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccPublic);
715 },
716 "Interface virtual method 1(LInterfaceMethodFlags;.foo) is not public");
717
718 VerifyModification(
719 kMethodFlagsInterface,
720 "method_flags_interface_non_abstract",
721 [](DexFile* dex_file) {
722 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
723
724 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccAbstract);
725 },
726 "Method 1(LInterfaceMethodFlags;.foo) has no code, but is not marked native or abstract");
727
728 VerifyModification(
729 kMethodFlagsInterface,
730 "method_flags_interface_static",
731 [](DexFile* dex_file) {
732 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
733
734 OrMaskToMethodFlags(dex_file, "foo", kAccStatic);
735 },
736 "Direct/virtual method 1(LInterfaceMethodFlags;.foo) not in expected list 0");
737 VerifyModification(
738 kMethodFlagsInterface,
739 "method_flags_interface_private",
740 [](DexFile* dex_file) {
741 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
742
743 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccPublic);
744 OrMaskToMethodFlags(dex_file, "foo", kAccPrivate);
745 },
746 "Direct/virtual method 1(LInterfaceMethodFlags;.foo) not in expected list 0");
747
748 VerifyModification(
749 kMethodFlagsInterface,
750 "method_flags_interface_non_public",
751 [](DexFile* dex_file) {
752 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
753
754 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccPublic);
755 },
756 nullptr); // Should be allowed in older dex versions for backwards compatibility.
757 VerifyModification(
758 kMethodFlagsInterface,
759 "method_flags_interface_non_public",
760 [](DexFile* dex_file) {
761 MakeDexVersion37(dex_file);
762 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
763
764 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccPublic);
765 },
766 "Interface virtual method 1(LInterfaceMethodFlags;.foo) is not public");
767
768 VerifyModification(
769 kMethodFlagsInterface,
770 "method_flags_interface_protected",
771 [](DexFile* dex_file) {
772 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
773
774 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccPublic);
775 OrMaskToMethodFlags(dex_file, "foo", kAccProtected);
776 },
777 nullptr); // Should be allowed in older dex versions for backwards compatibility.
778 VerifyModification(
779 kMethodFlagsInterface,
780 "method_flags_interface_protected",
781 [](DexFile* dex_file) {
782 MakeDexVersion37(dex_file);
783 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
784
785 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccPublic);
786 OrMaskToMethodFlags(dex_file, "foo", kAccProtected);
787 },
788 "Interface virtual method 1(LInterfaceMethodFlags;.foo) is not public");
789
790 constexpr uint32_t kAllMethodFlags =
791 kAccPublic |
792 kAccPrivate |
793 kAccProtected |
794 kAccStatic |
795 kAccFinal |
796 kAccSynchronized |
797 kAccBridge |
798 kAccVarargs |
799 kAccNative |
800 kAccAbstract |
801 kAccStrict |
802 kAccSynthetic;
803 constexpr uint32_t kInterfaceMethodFlags =
804 kAccPublic | kAccAbstract | kAccVarargs | kAccBridge | kAccSynthetic;
805 constexpr uint32_t kInterfaceDisallowed = kAllMethodFlags &
806 ~kInterfaceMethodFlags &
807 // Already tested, needed to be separate.
808 ~kAccStatic &
809 ~kAccPrivate &
810 ~kAccProtected;
811 static_assert(kInterfaceDisallowed != 0, "There should be disallowed flags.");
812
813 uint32_t bits = POPCOUNT(kInterfaceDisallowed);
814 for (uint32_t i = 1; i < (1u << bits); ++i) {
815 VerifyModification(
816 kMethodFlagsInterface,
817 "method_flags_interface_non_abstract",
818 [&](DexFile* dex_file) {
819 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
820
821 uint32_t mask = ApplyMaskShifted(kInterfaceDisallowed, i);
822 if ((mask & kAccProtected) != 0) {
823 mask &= ~kAccProtected;
824 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccPublic);
825 }
826 OrMaskToMethodFlags(dex_file, "foo", mask);
827 },
828 "Abstract method 1(LInterfaceMethodFlags;.foo) has disallowed access flags");
829 }
830 }
831
832 ///////////////////////////////////////////////////////////////////
833
834 // Field flags.
835
836 // Find the method data for the first method with the given name (from class 0). Note: the pointer
837 // is to the access flags, so that the caller doesn't have to handle the leb128-encoded method-index
838 // delta.
FindFieldData(const DexFile * dex_file,const char * name)839 static const uint8_t* FindFieldData(const DexFile* dex_file, const char* name) {
840 const DexFile::ClassDef& class_def = dex_file->GetClassDef(0);
841 const uint8_t* class_data = dex_file->GetClassData(class_def);
842
843 ClassDataItemIterator it(*dex_file, class_data);
844
845 const uint8_t* trailing = class_data;
846 // Need to manually decode the four entries. DataPointer() doesn't work for this, as the first
847 // element has already been loaded into the iterator.
848 DecodeUnsignedLeb128(&trailing);
849 DecodeUnsignedLeb128(&trailing);
850 DecodeUnsignedLeb128(&trailing);
851 DecodeUnsignedLeb128(&trailing);
852
853 while (it.HasNextStaticField() || it.HasNextInstanceField()) {
854 uint32_t field_index = it.GetMemberIndex();
855 dex::StringIndex name_index = dex_file->GetFieldId(field_index).name_idx_;
856 const DexFile::StringId& string_id = dex_file->GetStringId(name_index);
857 const char* str = dex_file->GetStringData(string_id);
858 if (strcmp(name, str) == 0) {
859 DecodeUnsignedLeb128(&trailing);
860 return trailing;
861 }
862
863 trailing = it.DataPointer();
864 it.Next();
865 }
866
867 return nullptr;
868 }
869
870 // Set the method flags to the given value.
SetFieldFlags(DexFile * dex_file,const char * field,uint32_t mask)871 static void SetFieldFlags(DexFile* dex_file, const char* field, uint32_t mask) {
872 uint8_t* field_flags_ptr = const_cast<uint8_t*>(FindFieldData(dex_file, field));
873 CHECK(field_flags_ptr != nullptr) << field;
874
875 // Unroll this, as we only have three bytes, anyways.
876 uint8_t base1 = static_cast<uint8_t>(mask & 0x7F);
877 *(field_flags_ptr++) = (base1 | 0x80);
878 mask >>= 7;
879
880 uint8_t base2 = static_cast<uint8_t>(mask & 0x7F);
881 *(field_flags_ptr++) = (base2 | 0x80);
882 mask >>= 7;
883
884 uint8_t base3 = static_cast<uint8_t>(mask & 0x7F);
885 *field_flags_ptr = base3;
886 }
887
GetFieldFlags(DexFile * dex_file,const char * field)888 static uint32_t GetFieldFlags(DexFile* dex_file, const char* field) {
889 const uint8_t* field_flags_ptr = const_cast<uint8_t*>(FindFieldData(dex_file, field));
890 CHECK(field_flags_ptr != nullptr) << field;
891 return DecodeUnsignedLeb128(&field_flags_ptr);
892 }
893
894 // Apply the given mask to method flags.
ApplyMaskToFieldFlags(DexFile * dex_file,const char * field,uint32_t mask)895 static void ApplyMaskToFieldFlags(DexFile* dex_file, const char* field, uint32_t mask) {
896 uint32_t value = GetFieldFlags(dex_file, field);
897 value &= mask;
898 SetFieldFlags(dex_file, field, value);
899 }
900
901 // Apply the given mask to method flags.
OrMaskToFieldFlags(DexFile * dex_file,const char * field,uint32_t mask)902 static void OrMaskToFieldFlags(DexFile* dex_file, const char* field, uint32_t mask) {
903 uint32_t value = GetFieldFlags(dex_file, field);
904 value |= mask;
905 SetFieldFlags(dex_file, field, value);
906 }
907
908 // Standard class. Use declared-synchronized again for 3B encoding.
909 //
910 // .class public LFieldFlags;
911 // .super Ljava/lang/Object;
912 //
913 // .field declared-synchronized public foo:I
914 //
915 // .field declared-synchronized public static bar:I
916
917 static const char kFieldFlagsTestDex[] =
918 "ZGV4CjAzNQBtLw7hydbfv4TdXidZyzAB70W7w3vnYJRwAQAAcAAAAHhWNBIAAAAAAAAAAAABAAAF"
919 "AAAAcAAAAAMAAACEAAAAAAAAAAAAAAACAAAAkAAAAAAAAAAAAAAAAQAAAKAAAACwAAAAwAAAAMAA"
920 "AADDAAAA0QAAAOUAAADqAAAAAAAAAAEAAAACAAAAAQAAAAMAAAABAAAABAAAAAEAAAABAAAAAgAA"
921 "AAAAAAD/////AAAAAPQAAAAAAAAAAUkADExGaWVsZEZsYWdzOwASTGphdmEvbGFuZy9PYmplY3Q7"
922 "AANiYXIAA2ZvbwAAAAAAAAEBAAAAiYAIAYGACAkAAAAAAAAAAQAAAAAAAAABAAAABQAAAHAAAAAC"
923 "AAAAAwAAAIQAAAAEAAAAAgAAAJAAAAAGAAAAAQAAAKAAAAACIAAABQAAAMAAAAADEAAAAQAAAPAA"
924 "AAAAIAAAAQAAAPQAAAAAEAAAAQAAAAABAAA=";
925
TEST_F(DexFileVerifierTest,FieldAccessFlagsBase)926 TEST_F(DexFileVerifierTest, FieldAccessFlagsBase) {
927 // Check that it's OK when the wrong declared-synchronized flag is removed from "foo."
928 VerifyModification(
929 kFieldFlagsTestDex,
930 "field_flags_ok",
931 [](DexFile* dex_file) {
932 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
933 ApplyMaskToFieldFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
934 },
935 nullptr);
936 }
937
TEST_F(DexFileVerifierTest,FieldAccessFlagsWrongList)938 TEST_F(DexFileVerifierTest, FieldAccessFlagsWrongList) {
939 // Mark the field so that it should appear in the opposite list (instance vs static).
940 VerifyModification(
941 kFieldFlagsTestDex,
942 "field_flags_wrong_list",
943 [](DexFile* dex_file) {
944 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
945 ApplyMaskToFieldFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
946
947 OrMaskToFieldFlags(dex_file, "foo", kAccStatic);
948 },
949 "Static/instance field not in expected list");
950 VerifyModification(
951 kFieldFlagsTestDex,
952 "field_flags_wrong_list",
953 [](DexFile* dex_file) {
954 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
955 ApplyMaskToFieldFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
956
957 ApplyMaskToFieldFlags(dex_file, "bar", ~kAccStatic);
958 },
959 "Static/instance field not in expected list");
960 }
961
TEST_F(DexFileVerifierTest,FieldAccessFlagsPPP)962 TEST_F(DexFileVerifierTest, FieldAccessFlagsPPP) {
963 static const char* kFields[] = { "foo", "bar" };
964 for (size_t i = 0; i < arraysize(kFields); ++i) {
965 // Should be OK to remove public.
966 VerifyModification(
967 kFieldFlagsTestDex,
968 "field_flags_non_public",
969 [&](DexFile* dex_file) {
970 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
971 ApplyMaskToFieldFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
972
973 ApplyMaskToFieldFlags(dex_file, kFields[i], ~kAccPublic);
974 },
975 nullptr);
976 constexpr uint32_t kAccFlags = kAccPublic | kAccPrivate | kAccProtected;
977 uint32_t bits = POPCOUNT(kAccFlags);
978 for (uint32_t j = 1; j < (1u << bits); ++j) {
979 if (POPCOUNT(j) < 2) {
980 continue;
981 }
982 VerifyModification(
983 kFieldFlagsTestDex,
984 "field_flags_ppp",
985 [&](DexFile* dex_file) {
986 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
987 ApplyMaskToFieldFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
988
989 ApplyMaskToFieldFlags(dex_file, kFields[i], ~kAccPublic);
990 uint32_t mask = ApplyMaskShifted(kAccFlags, j);
991 OrMaskToFieldFlags(dex_file, kFields[i], mask);
992 },
993 "Field may have only one of public/protected/private");
994 }
995 }
996 }
997
TEST_F(DexFileVerifierTest,FieldAccessFlagsIgnoredOK)998 TEST_F(DexFileVerifierTest, FieldAccessFlagsIgnoredOK) {
999 constexpr const char* kFields[] = { "foo", "bar"};
1000 for (size_t i = 0; i < arraysize(kFields); ++i) {
1001 // All interesting method flags, other flags are to be ignored.
1002 constexpr uint32_t kAllFieldFlags =
1003 kAccPublic |
1004 kAccPrivate |
1005 kAccProtected |
1006 kAccStatic |
1007 kAccFinal |
1008 kAccVolatile |
1009 kAccTransient |
1010 kAccSynthetic |
1011 kAccEnum;
1012 constexpr uint32_t kIgnoredMask = ~kAllFieldFlags & 0xFFFF;
1013 VerifyModification(
1014 kFieldFlagsTestDex,
1015 "field_flags_ignored",
1016 [&](DexFile* dex_file) {
1017 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
1018 ApplyMaskToFieldFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
1019
1020 OrMaskToFieldFlags(dex_file, kFields[i], kIgnoredMask);
1021 },
1022 nullptr);
1023 }
1024 }
1025
TEST_F(DexFileVerifierTest,FieldAccessFlagsVolatileFinal)1026 TEST_F(DexFileVerifierTest, FieldAccessFlagsVolatileFinal) {
1027 constexpr const char* kFields[] = { "foo", "bar"};
1028 for (size_t i = 0; i < arraysize(kFields); ++i) {
1029 VerifyModification(
1030 kFieldFlagsTestDex,
1031 "field_flags_final_and_volatile",
1032 [&](DexFile* dex_file) {
1033 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
1034 ApplyMaskToFieldFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
1035
1036 OrMaskToFieldFlags(dex_file, kFields[i], kAccVolatile | kAccFinal);
1037 },
1038 "Fields may not be volatile and final");
1039 }
1040 }
1041
1042 // Standard interface. Needs to be separate from class as interfaces do not allow instance fields.
1043 // Use declared-synchronized again for 3B encoding.
1044 //
1045 // .class public interface LInterfaceFieldFlags;
1046 // .super Ljava/lang/Object;
1047 //
1048 // .field declared-synchronized public static final foo:I
1049
1050 static const char kFieldFlagsInterfaceTestDex[] =
1051 "ZGV4CjAzNQCVMHfEimR1zZPk6hl6O9GPAYqkl3u0umFkAQAAcAAAAHhWNBIAAAAAAAAAAPQAAAAE"
1052 "AAAAcAAAAAMAAACAAAAAAAAAAAAAAAABAAAAjAAAAAAAAAAAAAAAAQAAAJQAAACwAAAAtAAAALQA"
1053 "AAC3AAAAzgAAAOIAAAAAAAAAAQAAAAIAAAABAAAAAwAAAAEAAAABAgAAAgAAAAAAAAD/////AAAA"
1054 "AOwAAAAAAAAAAUkAFUxJbnRlcmZhY2VGaWVsZEZsYWdzOwASTGphdmEvbGFuZy9PYmplY3Q7AANm"
1055 "b28AAAAAAAABAAAAAJmACAkAAAAAAAAAAQAAAAAAAAABAAAABAAAAHAAAAACAAAAAwAAAIAAAAAE"
1056 "AAAAAQAAAIwAAAAGAAAAAQAAAJQAAAACIAAABAAAALQAAAADEAAAAQAAAOgAAAAAIAAAAQAAAOwA"
1057 "AAAAEAAAAQAAAPQAAAA=";
1058
TEST_F(DexFileVerifierTest,FieldAccessFlagsInterface)1059 TEST_F(DexFileVerifierTest, FieldAccessFlagsInterface) {
1060 VerifyModification(
1061 kFieldFlagsInterfaceTestDex,
1062 "field_flags_interface",
1063 [](DexFile* dex_file) {
1064 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
1065 },
1066 nullptr);
1067 VerifyModification(
1068 kFieldFlagsInterfaceTestDex,
1069 "field_flags_interface",
1070 [](DexFile* dex_file) {
1071 MakeDexVersion37(dex_file);
1072 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
1073 },
1074 nullptr);
1075
1076 VerifyModification(
1077 kFieldFlagsInterfaceTestDex,
1078 "field_flags_interface_non_public",
1079 [](DexFile* dex_file) {
1080 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
1081
1082 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccPublic);
1083 },
1084 nullptr); // Should be allowed in older dex versions for backwards compatibility.
1085 VerifyModification(
1086 kFieldFlagsInterfaceTestDex,
1087 "field_flags_interface_non_public",
1088 [](DexFile* dex_file) {
1089 MakeDexVersion37(dex_file);
1090 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
1091
1092 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccPublic);
1093 },
1094 "Interface field is not public final static");
1095
1096 VerifyModification(
1097 kFieldFlagsInterfaceTestDex,
1098 "field_flags_interface_non_final",
1099 [](DexFile* dex_file) {
1100 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
1101
1102 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccFinal);
1103 },
1104 nullptr); // Should be allowed in older dex versions for backwards compatibility.
1105 VerifyModification(
1106 kFieldFlagsInterfaceTestDex,
1107 "field_flags_interface_non_final",
1108 [](DexFile* dex_file) {
1109 MakeDexVersion37(dex_file);
1110 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
1111
1112 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccFinal);
1113 },
1114 "Interface field is not public final static");
1115
1116 VerifyModification(
1117 kFieldFlagsInterfaceTestDex,
1118 "field_flags_interface_protected",
1119 [](DexFile* dex_file) {
1120 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
1121
1122 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccPublic);
1123 OrMaskToFieldFlags(dex_file, "foo", kAccProtected);
1124 },
1125 nullptr); // Should be allowed in older dex versions for backwards compatibility.
1126 VerifyModification(
1127 kFieldFlagsInterfaceTestDex,
1128 "field_flags_interface_protected",
1129 [](DexFile* dex_file) {
1130 MakeDexVersion37(dex_file);
1131 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
1132
1133 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccPublic);
1134 OrMaskToFieldFlags(dex_file, "foo", kAccProtected);
1135 },
1136 "Interface field is not public final static");
1137
1138 VerifyModification(
1139 kFieldFlagsInterfaceTestDex,
1140 "field_flags_interface_private",
1141 [](DexFile* dex_file) {
1142 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
1143
1144 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccPublic);
1145 OrMaskToFieldFlags(dex_file, "foo", kAccPrivate);
1146 },
1147 nullptr); // Should be allowed in older dex versions for backwards compatibility.
1148 VerifyModification(
1149 kFieldFlagsInterfaceTestDex,
1150 "field_flags_interface_private",
1151 [](DexFile* dex_file) {
1152 MakeDexVersion37(dex_file);
1153 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
1154
1155 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccPublic);
1156 OrMaskToFieldFlags(dex_file, "foo", kAccPrivate);
1157 },
1158 "Interface field is not public final static");
1159
1160 VerifyModification(
1161 kFieldFlagsInterfaceTestDex,
1162 "field_flags_interface_synthetic",
1163 [](DexFile* dex_file) {
1164 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
1165
1166 OrMaskToFieldFlags(dex_file, "foo", kAccSynthetic);
1167 },
1168 nullptr);
1169
1170 constexpr uint32_t kAllFieldFlags =
1171 kAccPublic |
1172 kAccPrivate |
1173 kAccProtected |
1174 kAccStatic |
1175 kAccFinal |
1176 kAccVolatile |
1177 kAccTransient |
1178 kAccSynthetic |
1179 kAccEnum;
1180 constexpr uint32_t kInterfaceFieldFlags = kAccPublic | kAccStatic | kAccFinal | kAccSynthetic;
1181 constexpr uint32_t kInterfaceDisallowed = kAllFieldFlags &
1182 ~kInterfaceFieldFlags &
1183 ~kAccProtected &
1184 ~kAccPrivate;
1185 static_assert(kInterfaceDisallowed != 0, "There should be disallowed flags.");
1186
1187 uint32_t bits = POPCOUNT(kInterfaceDisallowed);
1188 for (uint32_t i = 1; i < (1u << bits); ++i) {
1189 VerifyModification(
1190 kFieldFlagsInterfaceTestDex,
1191 "field_flags_interface_disallowed",
1192 [&](DexFile* dex_file) {
1193 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
1194
1195 uint32_t mask = ApplyMaskShifted(kInterfaceDisallowed, i);
1196 if ((mask & kAccProtected) != 0) {
1197 mask &= ~kAccProtected;
1198 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccPublic);
1199 }
1200 OrMaskToFieldFlags(dex_file, "foo", mask);
1201 },
1202 nullptr); // Should be allowed in older dex versions for backwards compatibility.
1203 VerifyModification(
1204 kFieldFlagsInterfaceTestDex,
1205 "field_flags_interface_disallowed",
1206 [&](DexFile* dex_file) {
1207 MakeDexVersion37(dex_file);
1208 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
1209
1210 uint32_t mask = ApplyMaskShifted(kInterfaceDisallowed, i);
1211 if ((mask & kAccProtected) != 0) {
1212 mask &= ~kAccProtected;
1213 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccPublic);
1214 }
1215 OrMaskToFieldFlags(dex_file, "foo", mask);
1216 },
1217 "Interface field has disallowed flag");
1218 }
1219 }
1220
1221 // Standard bad interface. Needs to be separate from class as interfaces do not allow instance
1222 // fields. Use declared-synchronized again for 3B encoding.
1223 //
1224 // .class public interface LInterfaceFieldFlags;
1225 // .super Ljava/lang/Object;
1226 //
1227 // .field declared-synchronized public final foo:I
1228
1229 static const char kFieldFlagsInterfaceBadTestDex[] =
1230 "ZGV4CjAzNQByMUnqYKHBkUpvvNp+9CnZ2VyDkKnRN6VkAQAAcAAAAHhWNBIAAAAAAAAAAPQAAAAE"
1231 "AAAAcAAAAAMAAACAAAAAAAAAAAAAAAABAAAAjAAAAAAAAAAAAAAAAQAAAJQAAACwAAAAtAAAALQA"
1232 "AAC3AAAAzgAAAOIAAAAAAAAAAQAAAAIAAAABAAAAAwAAAAEAAAABAgAAAgAAAAAAAAD/////AAAA"
1233 "AOwAAAAAAAAAAUkAFUxJbnRlcmZhY2VGaWVsZEZsYWdzOwASTGphdmEvbGFuZy9PYmplY3Q7AANm"
1234 "b28AAAAAAAAAAQAAAJGACAkAAAAAAAAAAQAAAAAAAAABAAAABAAAAHAAAAACAAAAAwAAAIAAAAAE"
1235 "AAAAAQAAAIwAAAAGAAAAAQAAAJQAAAACIAAABAAAALQAAAADEAAAAQAAAOgAAAAAIAAAAQAAAOwA"
1236 "AAAAEAAAAQAAAPQAAAA=";
1237
TEST_F(DexFileVerifierTest,FieldAccessFlagsInterfaceNonStatic)1238 TEST_F(DexFileVerifierTest, FieldAccessFlagsInterfaceNonStatic) {
1239 VerifyModification(
1240 kFieldFlagsInterfaceBadTestDex,
1241 "field_flags_interface_non_static",
1242 [](DexFile* dex_file) {
1243 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
1244 },
1245 nullptr); // Should be allowed in older dex versions for backwards compatibility.
1246 VerifyModification(
1247 kFieldFlagsInterfaceBadTestDex,
1248 "field_flags_interface_non_static",
1249 [](DexFile* dex_file) {
1250 MakeDexVersion37(dex_file);
1251 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
1252 },
1253 "Interface field is not public final static");
1254 }
1255
1256 // Generated from:
1257 //
1258 // .class public LTest;
1259 // .super Ljava/lang/Object;
1260 // .source "Test.java"
1261 //
1262 // .method public constructor <init>()V
1263 // .registers 1
1264 //
1265 // .prologue
1266 // .line 1
1267 // invoke-direct {p0}, Ljava/lang/Object;-><init>()V
1268 //
1269 // return-void
1270 // .end method
1271 //
1272 // .method public static main()V
1273 // .registers 2
1274 //
1275 // const-string v0, "a"
1276 // const-string v0, "b"
1277 // const-string v0, "c"
1278 // const-string v0, "d"
1279 // const-string v0, "e"
1280 // const-string v0, "f"
1281 // const-string v0, "g"
1282 // const-string v0, "h"
1283 // const-string v0, "i"
1284 // const-string v0, "j"
1285 // const-string v0, "k"
1286 //
1287 // .local v1, "local_var":Ljava/lang/String;
1288 // const-string v1, "test"
1289 // .end method
1290
1291 static const char kDebugInfoTestDex[] =
1292 "ZGV4CjAzNQCHRkHix2eIMQgvLD/0VGrlllZLo0Rb6VyUAgAAcAAAAHhWNBIAAAAAAAAAAAwCAAAU"
1293 "AAAAcAAAAAQAAADAAAAAAQAAANAAAAAAAAAAAAAAAAMAAADcAAAAAQAAAPQAAACAAQAAFAEAABQB"
1294 "AAAcAQAAJAEAADgBAABMAQAAVwEAAFoBAABdAQAAYAEAAGMBAABmAQAAaQEAAGwBAABvAQAAcgEA"
1295 "AHUBAAB4AQAAewEAAIYBAACMAQAAAQAAAAIAAAADAAAABQAAAAUAAAADAAAAAAAAAAAAAAAAAAAA"
1296 "AAAAABIAAAABAAAAAAAAAAAAAAABAAAAAQAAAAAAAAAEAAAAAAAAAPwBAAAAAAAABjxpbml0PgAG"
1297 "TFRlc3Q7ABJMamF2YS9sYW5nL09iamVjdDsAEkxqYXZhL2xhbmcvU3RyaW5nOwAJVGVzdC5qYXZh"
1298 "AAFWAAFhAAFiAAFjAAFkAAFlAAFmAAFnAAFoAAFpAAFqAAFrAAlsb2NhbF92YXIABG1haW4ABHRl"
1299 "c3QAAAABAAcOAAAAARYDARIDAAAAAQABAAEAAACUAQAABAAAAHAQAgAAAA4AAgAAAAAAAACZAQAA"
1300 "GAAAABoABgAaAAcAGgAIABoACQAaAAoAGgALABoADAAaAA0AGgAOABoADwAaABAAGgETAAAAAgAA"
1301 "gYAEpAMBCbwDAAALAAAAAAAAAAEAAAAAAAAAAQAAABQAAABwAAAAAgAAAAQAAADAAAAAAwAAAAEA"
1302 "AADQAAAABQAAAAMAAADcAAAABgAAAAEAAAD0AAAAAiAAABQAAAAUAQAAAyAAAAIAAACUAQAAASAA"
1303 "AAIAAACkAQAAACAAAAEAAAD8AQAAABAAAAEAAAAMAgAA";
1304
TEST_F(DexFileVerifierTest,DebugInfoTypeIdxTest)1305 TEST_F(DexFileVerifierTest, DebugInfoTypeIdxTest) {
1306 {
1307 // The input dex file should be good before modification.
1308 ScratchFile tmp;
1309 std::string error_msg;
1310 std::unique_ptr<const DexFile> raw(OpenDexFileBase64(kDebugInfoTestDex,
1311 tmp.GetFilename().c_str(),
1312 &error_msg));
1313 ASSERT_TRUE(raw.get() != nullptr) << error_msg;
1314 }
1315
1316 // Modify the debug information entry.
1317 VerifyModification(
1318 kDebugInfoTestDex,
1319 "debug_start_type_idx",
1320 [](DexFile* dex_file) {
1321 *(const_cast<uint8_t*>(dex_file->Begin()) + 416) = 0x14U;
1322 },
1323 "DBG_START_LOCAL type_idx");
1324 }
1325
TEST_F(DexFileVerifierTest,SectionAlignment)1326 TEST_F(DexFileVerifierTest, SectionAlignment) {
1327 {
1328 // The input dex file should be good before modification. Any file is fine, as long as it
1329 // uses all sections.
1330 ScratchFile tmp;
1331 std::string error_msg;
1332 std::unique_ptr<const DexFile> raw(OpenDexFileBase64(kGoodTestDex,
1333 tmp.GetFilename().c_str(),
1334 &error_msg));
1335 ASSERT_TRUE(raw.get() != nullptr) << error_msg;
1336 }
1337
1338 // Modify all section offsets to be unaligned.
1339 constexpr size_t kSections = 7;
1340 for (size_t i = 0; i < kSections; ++i) {
1341 VerifyModification(
1342 kGoodTestDex,
1343 "section_align",
1344 [&](DexFile* dex_file) {
1345 DexFile::Header* header = const_cast<DexFile::Header*>(
1346 reinterpret_cast<const DexFile::Header*>(dex_file->Begin()));
1347 uint32_t* off_ptr;
1348 switch (i) {
1349 case 0:
1350 off_ptr = &header->map_off_;
1351 break;
1352 case 1:
1353 off_ptr = &header->string_ids_off_;
1354 break;
1355 case 2:
1356 off_ptr = &header->type_ids_off_;
1357 break;
1358 case 3:
1359 off_ptr = &header->proto_ids_off_;
1360 break;
1361 case 4:
1362 off_ptr = &header->field_ids_off_;
1363 break;
1364 case 5:
1365 off_ptr = &header->method_ids_off_;
1366 break;
1367 case 6:
1368 off_ptr = &header->class_defs_off_;
1369 break;
1370
1371 static_assert(kSections == 7, "kSections is wrong");
1372 default:
1373 LOG(FATAL) << "Unexpected section";
1374 UNREACHABLE();
1375 }
1376 ASSERT_TRUE(off_ptr != nullptr);
1377 ASSERT_NE(*off_ptr, 0U) << i; // Should already contain a value (in use).
1378 (*off_ptr)++; // Add one, which should misalign it (all the sections
1379 // above are aligned by 4).
1380 },
1381 "should be aligned by 4 for");
1382 }
1383 }
1384
1385 // Generated from
1386 //
1387 // .class LOverloading;
1388 //
1389 // .super Ljava/lang/Object;
1390 //
1391 // .method public static foo()V
1392 // .registers 1
1393 // return-void
1394 // .end method
1395 //
1396 // .method public static foo(I)V
1397 // .registers 1
1398 // return-void
1399 // .end method
1400 static const char kProtoOrderingTestDex[] =
1401 "ZGV4CjAzNQA1L+ABE6voQ9Lr4Ci//efB53oGnDr5PinsAQAAcAAAAHhWNBIAAAAAAAAAAFgBAAAG"
1402 "AAAAcAAAAAQAAACIAAAAAgAAAJgAAAAAAAAAAAAAAAIAAACwAAAAAQAAAMAAAAAMAQAA4AAAAOAA"
1403 "AADjAAAA8gAAAAYBAAAJAQAADQEAAAAAAAABAAAAAgAAAAMAAAADAAAAAwAAAAAAAAAEAAAAAwAA"
1404 "ABQBAAABAAAABQAAAAEAAQAFAAAAAQAAAAAAAAACAAAAAAAAAP////8AAAAASgEAAAAAAAABSQAN"
1405 "TE92ZXJsb2FkaW5nOwASTGphdmEvbGFuZy9PYmplY3Q7AAFWAAJWSQADZm9vAAAAAQAAAAAAAAAA"
1406 "AAAAAAAAAAEAAAAAAAAAAAAAAAEAAAAOAAAAAQABAAAAAAAAAAAAAQAAAA4AAAACAAAJpAIBCbgC"
1407 "AAAMAAAAAAAAAAEAAAAAAAAAAQAAAAYAAABwAAAAAgAAAAQAAACIAAAAAwAAAAIAAACYAAAABQAA"
1408 "AAIAAACwAAAABgAAAAEAAADAAAAAAiAAAAYAAADgAAAAARAAAAEAAAAUAQAAAxAAAAIAAAAcAQAA"
1409 "ASAAAAIAAAAkAQAAACAAAAEAAABKAQAAABAAAAEAAABYAQAA";
1410
TEST_F(DexFileVerifierTest,ProtoOrdering)1411 TEST_F(DexFileVerifierTest, ProtoOrdering) {
1412 {
1413 // The input dex file should be good before modification.
1414 ScratchFile tmp;
1415 std::string error_msg;
1416 std::unique_ptr<const DexFile> raw(OpenDexFileBase64(kProtoOrderingTestDex,
1417 tmp.GetFilename().c_str(),
1418 &error_msg));
1419 ASSERT_TRUE(raw.get() != nullptr) << error_msg;
1420 }
1421
1422 // Modify the order of the ProtoIds for two overloads of "foo" with the
1423 // same return type and one having longer parameter list than the other.
1424 for (size_t i = 0; i != 2; ++i) {
1425 VerifyModification(
1426 kProtoOrderingTestDex,
1427 "proto_ordering",
1428 [i](DexFile* dex_file) {
1429 uint32_t method_idx;
1430 const uint8_t* data = FindMethodData(dex_file, "foo", &method_idx);
1431 CHECK(data != nullptr);
1432 // There should be 2 methods called "foo".
1433 CHECK_LT(method_idx + 1u, dex_file->NumMethodIds());
1434 CHECK_EQ(dex_file->GetMethodId(method_idx).name_idx_,
1435 dex_file->GetMethodId(method_idx + 1).name_idx_);
1436 CHECK_EQ(dex_file->GetMethodId(method_idx).proto_idx_ + 1u,
1437 dex_file->GetMethodId(method_idx + 1).proto_idx_);
1438 // Their return types should be the same.
1439 uint32_t proto1_idx = dex_file->GetMethodId(method_idx).proto_idx_;
1440 const DexFile::ProtoId& proto1 = dex_file->GetProtoId(proto1_idx);
1441 const DexFile::ProtoId& proto2 = dex_file->GetProtoId(proto1_idx + 1u);
1442 CHECK_EQ(proto1.return_type_idx_, proto2.return_type_idx_);
1443 // And the first should not have any parameters while the second should have some.
1444 CHECK(!DexFileParameterIterator(*dex_file, proto1).HasNext());
1445 CHECK(DexFileParameterIterator(*dex_file, proto2).HasNext());
1446 if (i == 0) {
1447 // Swap the proto parameters and shorties to break the ordering.
1448 std::swap(const_cast<uint32_t&>(proto1.parameters_off_),
1449 const_cast<uint32_t&>(proto2.parameters_off_));
1450 std::swap(const_cast<dex::StringIndex&>(proto1.shorty_idx_),
1451 const_cast<dex::StringIndex&>(proto2.shorty_idx_));
1452 } else {
1453 // Copy the proto parameters and shorty to create duplicate proto id.
1454 const_cast<uint32_t&>(proto1.parameters_off_) = proto2.parameters_off_;
1455 const_cast<dex::StringIndex&>(proto1.shorty_idx_) = proto2.shorty_idx_;
1456 }
1457 },
1458 "Out-of-order proto_id arguments");
1459 }
1460 }
1461
1462 // To generate a base64 encoded Dex file version 037 from Smali files, use:
1463 //
1464 // smali --api-level 24 -o classes.dex class1.smali [class2.smali ...]
1465 // base64 classes.dex >classes.dex.base64
1466
1467 // Dex file version 037 generated from:
1468 //
1469 // .class public LB28685551;
1470 // .super LB28685551;
1471
1472 static const char kClassExtendsItselfTestDex[] =
1473 "ZGV4CjAzNwDeGbgRg1kb6swszpcTWrrOAALB++F4OPT0AAAAcAAAAHhWNBIAAAAAAAAAAKgAAAAB"
1474 "AAAAcAAAAAEAAAB0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAHgAAABcAAAAmAAAAJgA"
1475 "AAAAAAAAAAAAAAEAAAAAAAAAAAAAAP////8AAAAAAAAAAAAAAAALTEIyODY4NTU1MTsAAAAABgAA"
1476 "AAAAAAABAAAAAAAAAAEAAAABAAAAcAAAAAIAAAABAAAAdAAAAAYAAAABAAAAeAAAAAIgAAABAAAA"
1477 "mAAAAAAQAAABAAAAqAAAAA==";
1478
TEST_F(DexFileVerifierTest,ClassExtendsItself)1479 TEST_F(DexFileVerifierTest, ClassExtendsItself) {
1480 VerifyModification(
1481 kClassExtendsItselfTestDex,
1482 "class_extends_itself",
1483 [](DexFile* dex_file ATTRIBUTE_UNUSED) { /* empty */ },
1484 "Class with same type idx as its superclass: '0'");
1485 }
1486
1487 // Dex file version 037 generated from:
1488 //
1489 // .class public LFoo;
1490 // .super LBar;
1491 //
1492 // and:
1493 //
1494 // .class public LBar;
1495 // .super LFoo;
1496
1497 static const char kClassesExtendOneAnotherTestDex[] =
1498 "ZGV4CjAzNwBXHSrwpDMwRBkg+L+JeQCuFNRLhQ86duEcAQAAcAAAAHhWNBIAAAAAAAAAANAAAAAC"
1499 "AAAAcAAAAAIAAAB4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAIAAAABcAAAAwAAAAMAA"
1500 "AADHAAAAAAAAAAEAAAABAAAAAQAAAAAAAAAAAAAA/////wAAAAAAAAAAAAAAAAAAAAABAAAAAQAA"
1501 "AAAAAAD/////AAAAAAAAAAAAAAAABUxCYXI7AAVMRm9vOwAAAAYAAAAAAAAAAQAAAAAAAAABAAAA"
1502 "AgAAAHAAAAACAAAAAgAAAHgAAAAGAAAAAgAAAIAAAAACIAAAAgAAAMAAAAAAEAAAAQAAANAAAAA=";
1503
TEST_F(DexFileVerifierTest,ClassesExtendOneAnother)1504 TEST_F(DexFileVerifierTest, ClassesExtendOneAnother) {
1505 VerifyModification(
1506 kClassesExtendOneAnotherTestDex,
1507 "classes_extend_one_another",
1508 [](DexFile* dex_file ATTRIBUTE_UNUSED) { /* empty */ },
1509 "Invalid class definition ordering: class with type idx: '1' defined before"
1510 " superclass with type idx: '0'");
1511 }
1512
1513 // Dex file version 037 generated from:
1514 //
1515 // .class public LAll;
1516 // .super LYour;
1517 //
1518 // and:
1519 //
1520 // .class public LYour;
1521 // .super LBase;
1522 //
1523 // and:
1524 //
1525 // .class public LBase;
1526 // .super LAll;
1527
1528 static const char kCircularClassInheritanceTestDex[] =
1529 "ZGV4CjAzNwBMJxgP0SJz6oLXnKfl+J7lSEORLRwF5LNMAQAAcAAAAHhWNBIAAAAAAAAAAAABAAAD"
1530 "AAAAcAAAAAMAAAB8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAIgAAABkAAAA6AAAAOgA"
1531 "AADvAAAA9wAAAAAAAAABAAAAAgAAAAEAAAABAAAAAAAAAAAAAAD/////AAAAAAAAAAAAAAAAAgAA"
1532 "AAEAAAABAAAAAAAAAP////8AAAAAAAAAAAAAAAAAAAAAAQAAAAIAAAAAAAAA/////wAAAAAAAAAA"
1533 "AAAAAAVMQWxsOwAGTEJhc2U7AAZMWW91cjsAAAYAAAAAAAAAAQAAAAAAAAABAAAAAwAAAHAAAAAC"
1534 "AAAAAwAAAHwAAAAGAAAAAwAAAIgAAAACIAAAAwAAAOgAAAAAEAAAAQAAAAABAAA=";
1535
TEST_F(DexFileVerifierTest,CircularClassInheritance)1536 TEST_F(DexFileVerifierTest, CircularClassInheritance) {
1537 VerifyModification(
1538 kCircularClassInheritanceTestDex,
1539 "circular_class_inheritance",
1540 [](DexFile* dex_file ATTRIBUTE_UNUSED) { /* empty */ },
1541 "Invalid class definition ordering: class with type idx: '1' defined before"
1542 " superclass with type idx: '0'");
1543 }
1544
1545 // Dex file version 037 generated from:
1546 //
1547 // .class public abstract interface LInterfaceImplementsItself;
1548 // .super Ljava/lang/Object;
1549 // .implements LInterfaceImplementsItself;
1550
1551 static const char kInterfaceImplementsItselfTestDex[] =
1552 "ZGV4CjAzNwCKKrjatp8XbXl5S/bEVJnqaBhjZkQY4440AQAAcAAAAHhWNBIAAAAAAAAAANwAAAAC"
1553 "AAAAcAAAAAIAAAB4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAIAAAACUAAAAoAAAAKAA"
1554 "AAC9AAAAAAAAAAEAAAAAAAAAAQYAAAEAAADUAAAA/////wAAAAAAAAAAAAAAABtMSW50ZXJmYWNl"
1555 "SW1wbGVtZW50c0l0c2VsZjsAEkxqYXZhL2xhbmcvT2JqZWN0OwAAAAABAAAAAAAAAAcAAAAAAAAA"
1556 "AQAAAAAAAAABAAAAAgAAAHAAAAACAAAAAgAAAHgAAAAGAAAAAQAAAIAAAAACIAAAAgAAAKAAAAAB"
1557 "EAAAAQAAANQAAAAAEAAAAQAAANwAAAA=";
1558
TEST_F(DexFileVerifierTest,InterfaceImplementsItself)1559 TEST_F(DexFileVerifierTest, InterfaceImplementsItself) {
1560 VerifyModification(
1561 kInterfaceImplementsItselfTestDex,
1562 "interface_implements_itself",
1563 [](DexFile* dex_file ATTRIBUTE_UNUSED) { /* empty */ },
1564 "Class with same type idx as implemented interface: '0'");
1565 }
1566
1567 // Dex file version 037 generated from:
1568 //
1569 // .class public abstract interface LPing;
1570 // .super Ljava/lang/Object;
1571 // .implements LPong;
1572 //
1573 // and:
1574 //
1575 // .class public abstract interface LPong;
1576 // .super Ljava/lang/Object;
1577 // .implements LPing;
1578
1579 static const char kInterfacesImplementOneAnotherTestDex[] =
1580 "ZGV4CjAzNwD0Kk9sxlYdg3Dy1Cff0gQCuJAQfEP6ohZUAQAAcAAAAHhWNBIAAAAAAAAAAPwAAAAD"
1581 "AAAAcAAAAAMAAAB8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAIgAAACMAAAAyAAAAMgA"
1582 "AADQAAAA2AAAAAAAAAABAAAAAgAAAAEAAAABBgAAAgAAAOwAAAD/////AAAAAAAAAAAAAAAAAAAA"
1583 "AAEGAAACAAAA9AAAAP////8AAAAAAAAAAAAAAAAGTFBpbmc7AAZMUG9uZzsAEkxqYXZhL2xhbmcv"
1584 "T2JqZWN0OwABAAAAAAAAAAEAAAABAAAABwAAAAAAAAABAAAAAAAAAAEAAAADAAAAcAAAAAIAAAAD"
1585 "AAAAfAAAAAYAAAACAAAAiAAAAAIgAAADAAAAyAAAAAEQAAACAAAA7AAAAAAQAAABAAAA/AAAAA==";
1586
TEST_F(DexFileVerifierTest,InterfacesImplementOneAnother)1587 TEST_F(DexFileVerifierTest, InterfacesImplementOneAnother) {
1588 VerifyModification(
1589 kInterfacesImplementOneAnotherTestDex,
1590 "interfaces_implement_one_another",
1591 [](DexFile* dex_file ATTRIBUTE_UNUSED) { /* empty */ },
1592 "Invalid class definition ordering: class with type idx: '1' defined before"
1593 " implemented interface with type idx: '0'");
1594 }
1595
1596 // Dex file version 037 generated from:
1597 //
1598 // .class public abstract interface LA;
1599 // .super Ljava/lang/Object;
1600 // .implements LB;
1601 //
1602 // and:
1603 //
1604 // .class public abstract interface LB;
1605 // .super Ljava/lang/Object;
1606 // .implements LC;
1607 //
1608 // and:
1609 //
1610 // .class public abstract interface LC;
1611 // .super Ljava/lang/Object;
1612 // .implements LA;
1613
1614 static const char kCircularInterfaceImplementationTestDex[] =
1615 "ZGV4CjAzNwCzKmD5Fol6XAU6ichYHcUTIP7Z7MdTcEmEAQAAcAAAAHhWNBIAAAAAAAAAACwBAAAE"
1616 "AAAAcAAAAAQAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAJAAAACUAAAA8AAAAPAA"
1617 "AAD1AAAA+gAAAP8AAAAAAAAAAQAAAAIAAAADAAAAAgAAAAEGAAADAAAAHAEAAP////8AAAAAAAAA"
1618 "AAAAAAABAAAAAQYAAAMAAAAUAQAA/////wAAAAAAAAAAAAAAAAAAAAABBgAAAwAAACQBAAD/////"
1619 "AAAAAAAAAAAAAAAAA0xBOwADTEI7AANMQzsAEkxqYXZhL2xhbmcvT2JqZWN0OwAAAQAAAAIAAAAB"
1620 "AAAAAAAAAAEAAAABAAAABwAAAAAAAAABAAAAAAAAAAEAAAAEAAAAcAAAAAIAAAAEAAAAgAAAAAYA"
1621 "AAADAAAAkAAAAAIgAAAEAAAA8AAAAAEQAAADAAAAFAEAAAAQAAABAAAALAEAAA==";
1622
TEST_F(DexFileVerifierTest,CircularInterfaceImplementation)1623 TEST_F(DexFileVerifierTest, CircularInterfaceImplementation) {
1624 VerifyModification(
1625 kCircularInterfaceImplementationTestDex,
1626 "circular_interface_implementation",
1627 [](DexFile* dex_file ATTRIBUTE_UNUSED) { /* empty */ },
1628 "Invalid class definition ordering: class with type idx: '2' defined before"
1629 " implemented interface with type idx: '0'");
1630 }
1631
TEST_F(DexFileVerifierTest,Checksum)1632 TEST_F(DexFileVerifierTest, Checksum) {
1633 size_t length;
1634 std::unique_ptr<uint8_t[]> dex_bytes(DecodeBase64(kGoodTestDex, &length));
1635 CHECK(dex_bytes != nullptr);
1636 // Note: `dex_file` will be destroyed before `dex_bytes`.
1637 std::unique_ptr<DexFile> dex_file(GetDexFile(dex_bytes.get(), length));
1638 std::string error_msg;
1639
1640 // Good checksum: all pass.
1641 EXPECT_TRUE(DexFileVerifier::Verify(dex_file.get(),
1642 dex_file->Begin(),
1643 dex_file->Size(),
1644 "good checksum, no verify",
1645 /*verify_checksum*/ false,
1646 &error_msg));
1647 EXPECT_TRUE(DexFileVerifier::Verify(dex_file.get(),
1648 dex_file->Begin(),
1649 dex_file->Size(),
1650 "good checksum, verify",
1651 /*verify_checksum*/ true,
1652 &error_msg));
1653
1654 // Bad checksum: !verify_checksum passes verify_checksum fails.
1655 DexFile::Header* header = reinterpret_cast<DexFile::Header*>(
1656 const_cast<uint8_t*>(dex_file->Begin()));
1657 header->checksum_ = 0;
1658 EXPECT_TRUE(DexFileVerifier::Verify(dex_file.get(),
1659 dex_file->Begin(),
1660 dex_file->Size(),
1661 "bad checksum, no verify",
1662 /*verify_checksum*/ false,
1663 &error_msg));
1664 EXPECT_FALSE(DexFileVerifier::Verify(dex_file.get(),
1665 dex_file->Begin(),
1666 dex_file->Size(),
1667 "bad checksum, verify",
1668 /*verify_checksum*/ true,
1669 &error_msg));
1670 EXPECT_NE(error_msg.find("Bad checksum"), std::string::npos) << error_msg;
1671 }
1672
TEST_F(DexFileVerifierTest,BadStaticMethodName)1673 TEST_F(DexFileVerifierTest, BadStaticMethodName) {
1674 // Generated DEX file version (037) from:
1675 //
1676 // .class public LBadName;
1677 // .super Ljava/lang/Object;
1678 //
1679 // .method public static <bad_name> (II)V
1680 // .registers 2
1681 // .prologue
1682 // return-void
1683 // .end method
1684 //
1685 // .method public constructor <init>()V
1686 // .registers 1
1687 // .prologue
1688 // .line 1
1689 // invoke-direct {p0}, Ljava/lang/Object;-><init>()V
1690 // return-void
1691 // .end method
1692 //
1693 static const char kDexBase64[] =
1694 "ZGV4CjAzNwC2NYlwyxEc/h6hv+hMeUVQPtiX6MQBcfgwAgAAcAAAAHhWNBIAAAAAAAAAAJABAAAI"
1695 "AAAAcAAAAAQAAACQAAAAAgAAAKAAAAAAAAAAAAAAAAMAAAC4AAAAAQAAANAAAABAAQAA8AAAAPAA"
1696 "AAD8AAAABAEAABIBAAAVAQAAIAEAADQBAAA3AQAAAwAAAAQAAAAFAAAABgAAAAYAAAADAAAAAAAA"
1697 "AAcAAAADAAAAPAEAAAEAAQAAAAAAAQAAAAEAAAACAAAAAQAAAAEAAAABAAAAAgAAAAAAAAACAAAA"
1698 "AAAAAIABAAAAAAAACjxiYWRfbmFtZT4ABjxpbml0PgAMQmFkTmFtZS5qYXZhAAFJAAlMQmFkTmFt"
1699 "ZTsAEkxqYXZhL2xhbmcvT2JqZWN0OwABVgADVklJAAIAAAAAAAAAAAAAAAACAAAHAAEABw4AAAIA"
1700 "AgAAAAAASAEAAAEAAAAOAAAAAQABAAEAAABOAQAABAAAAHAQAgAAAA4AAAACAAAJ1AIBgYAE6AIA"
1701 "AA0AAAAAAAAAAQAAAAAAAAABAAAACAAAAHAAAAACAAAABAAAAJAAAAADAAAAAgAAAKAAAAAFAAAA"
1702 "AwAAALgAAAAGAAAAAQAAANAAAAACIAAACAAAAPAAAAABEAAAAQAAADwBAAADEAAAAQAAAEQBAAAD"
1703 "IAAAAgAAAEgBAAABIAAAAgAAAFQBAAAAIAAAAQAAAIABAAAAEAAAAQAAAJABAAA=";
1704
1705 size_t length;
1706 std::unique_ptr<uint8_t[]> dex_bytes(DecodeBase64(kDexBase64, &length));
1707 CHECK(dex_bytes != nullptr);
1708 // Note: `dex_file` will be destroyed before `dex_bytes`.
1709 std::unique_ptr<DexFile> dex_file(GetDexFile(dex_bytes.get(), length));
1710 std::string error_msg;
1711 EXPECT_FALSE(DexFileVerifier::Verify(dex_file.get(),
1712 dex_file->Begin(),
1713 dex_file->Size(),
1714 "bad static method name",
1715 /*verify_checksum*/ true,
1716 &error_msg));
1717 }
1718
TEST_F(DexFileVerifierTest,BadVirtualMethodName)1719 TEST_F(DexFileVerifierTest, BadVirtualMethodName) {
1720 // Generated DEX file version (037) from:
1721 //
1722 // .class public LBadVirtualName;
1723 // .super Ljava/lang/Object;
1724 //
1725 // .method public <bad_name> (II)V
1726 // .registers 2
1727 // return-void
1728 // .end method
1729 //
1730 // .method public constructor <init>()V
1731 // .registers 1
1732 // invoke-direct {p0}, Ljava/lang/Object;-><init>()V
1733 // return-void
1734 // .end method
1735 //
1736 static const char kDexBase64[] =
1737 "ZGV4CjAzNwDcPC8B2E7kYTZmeHX2u2IqrpWV9EXBHpE8AgAAcAAAAHhWNBIAAAAAAAAAAJwBAAAI"
1738 "AAAAcAAAAAQAAACQAAAAAgAAAKAAAAAAAAAAAAAAAAMAAAC4AAAAAQAAANAAAABMAQAA8AAAAPAA"
1739 "AAD8AAAABAEAABkBAAAcAQAALgEAAEIBAABFAQAAAwAAAAQAAAAFAAAABgAAAAYAAAADAAAAAAAA"
1740 "AAcAAAADAAAATAEAAAEAAQAAAAAAAQAAAAEAAAACAAAAAQAAAAEAAAABAAAAAgAAAAAAAAACAAAA"
1741 "AAAAAI4BAAAAAAAACjxiYWRfbmFtZT4ABjxpbml0PgATQmFkVmlydHVhbE5hbWUuamF2YQABSQAQ"
1742 "TEJhZFZpcnR1YWxOYW1lOwASTGphdmEvbGFuZy9PYmplY3Q7AAFWAANWSUkAAAACAAAAAAAAAAAA"
1743 "AAABAAcOAAACAAAHAAABAAEAAQAAAFgBAAAEAAAAcBACAAAADgADAAMAAAAAAF0BAAABAAAADgAA"
1744 "AAEBAYGABOQCAAH8Ag0AAAAAAAAAAQAAAAAAAAABAAAACAAAAHAAAAACAAAABAAAAJAAAAADAAAA"
1745 "AgAAAKAAAAAFAAAAAwAAALgAAAAGAAAAAQAAANAAAAACIAAACAAAAPAAAAABEAAAAQAAAEwBAAAD"
1746 "EAAAAQAAAFQBAAADIAAAAgAAAFgBAAABIAAAAgAAAGQBAAAAIAAAAQAAAI4BAAAAEAAAAQAAAJwB"
1747 "AAA=";
1748
1749 size_t length;
1750 std::unique_ptr<uint8_t[]> dex_bytes(DecodeBase64(kDexBase64, &length));
1751 CHECK(dex_bytes != nullptr);
1752 // Note: `dex_file` will be destroyed before `dex_bytes`.
1753 std::unique_ptr<DexFile> dex_file(GetDexFile(dex_bytes.get(), length));
1754 std::string error_msg;
1755 EXPECT_FALSE(DexFileVerifier::Verify(dex_file.get(),
1756 dex_file->Begin(),
1757 dex_file->Size(),
1758 "bad virtual method name",
1759 /*verify_checksum*/ true,
1760 &error_msg));
1761 }
1762
TEST_F(DexFileVerifierTest,BadClinitSignature)1763 TEST_F(DexFileVerifierTest, BadClinitSignature) {
1764 // Generated DEX file version (037) from:
1765 //
1766 // .class public LOneClinitBadSig;
1767 // .super Ljava/lang/Object;
1768 //
1769 // .method public static constructor <clinit>(II)V
1770 // .registers 2
1771 // return-void
1772 // .end method
1773 //
1774 // .method public constructor <init>()V
1775 // .registers 1
1776 // invoke-direct {p0}, Ljava/lang/Object;-><init>()V
1777 // return-void
1778 // .end method
1779 //
1780 static const char kDexBase64[] =
1781 "ZGV4CjAzNwBNOwTbfJmWq5eMOlxUY4EICGiEGJMVg8RAAgAAcAAAAHhWNBIAAAAAAAAAAKABAAAI"
1782 "AAAAcAAAAAQAAACQAAAAAgAAAKAAAAAAAAAAAAAAAAMAAAC4AAAAAQAAANAAAABQAQAA8AAAAPAA"
1783 "AAD6AAAAAgEAAAUBAAAYAQAALAEAAEIBAABFAQAAAgAAAAMAAAAEAAAABgAAAAYAAAADAAAAAAAA"
1784 "AAcAAAADAAAATAEAAAEAAQAAAAAAAQAAAAEAAAACAAAAAQAAAAEAAAABAAAAAgAAAAAAAAAFAAAA"
1785 "AAAAAJABAAAAAAAACDxjbGluaXQ+AAY8aW5pdD4AAUkAEUxPbmVDbGluaXRCYWRTaWc7ABJMamF2"
1786 "YS9sYW5nL09iamVjdDsAFE9uZUNsaW5pdEJhZFNpZy5qYXZhAAFWAANWSUkAAAACAAAAAAAAAAAA"
1787 "AAAAAgAABwABAAcOAAACAAIAAAAAAFgBAAABAAAADgAAAAEAAQABAAAAXgEAAAQAAABwEAIAAAAO"
1788 "AAAAAgAAiYAE5AIBgYAE+AINAAAAAAAAAAEAAAAAAAAAAQAAAAgAAABwAAAAAgAAAAQAAACQAAAA"
1789 "AwAAAAIAAACgAAAABQAAAAMAAAC4AAAABgAAAAEAAADQAAAAAiAAAAgAAADwAAAAARAAAAEAAABM"
1790 "AQAAAxAAAAEAAABUAQAAAyAAAAIAAABYAQAAASAAAAIAAABkAQAAACAAAAEAAACQAQAAABAAAAEA"
1791 "AACgAQAA";
1792
1793 size_t length;
1794 std::unique_ptr<uint8_t[]> dex_bytes(DecodeBase64(kDexBase64, &length));
1795 CHECK(dex_bytes != nullptr);
1796 // Note: `dex_file` will be destroyed before `dex_bytes`.
1797 std::unique_ptr<DexFile> dex_file(GetDexFile(dex_bytes.get(), length));
1798 std::string error_msg;
1799 EXPECT_FALSE(DexFileVerifier::Verify(dex_file.get(),
1800 dex_file->Begin(),
1801 dex_file->Size(),
1802 "bad clinit signature",
1803 /*verify_checksum*/ true,
1804 &error_msg));
1805 }
1806
TEST_F(DexFileVerifierTest,BadClinitSignatureAgain)1807 TEST_F(DexFileVerifierTest, BadClinitSignatureAgain) {
1808 // Generated DEX file version (037) from:
1809 //
1810 // .class public LOneClinitBadSigAgain;
1811 // .super Ljava/lang/Object;
1812 //
1813 // .method public static constructor <clinit>()I
1814 // .registers 1
1815 // const/4 v0, 1
1816 // return v0
1817 // .end method
1818 //
1819 // .method public constructor <init>()V
1820 // .registers 1
1821 // invoke-direct {p0}, Ljava/lang/Object;-><init>()V
1822 // return-void
1823 // .end method
1824 //
1825 static const char kDexBase64[] =
1826 "ZGV4CjAzNwBfPcPu5NVwKUqZIu/YR8xqVlVD5UzTk0gEAgAAcAAAAHhWNBIAAAAAAAAAAIgBAAAH"
1827 "AAAAcAAAAAQAAACMAAAAAgAAAJwAAAAAAAAAAAAAAAMAAAC0AAAAAQAAAMwAAAAYAQAA7AAAAOwA"
1828 "AAD2AAAA/gAAAAEBAAAZAQAALQEAAEgBAAACAAAAAwAAAAQAAAAGAAAAAgAAAAAAAAAAAAAABgAA"
1829 "AAMAAAAAAAAAAQAAAAAAAAABAAEAAQAAAAIAAQABAAAAAQAAAAEAAAACAAAAAAAAAAUAAAAAAAAA"
1830 "eAEAAAAAAAAIPGNsaW5pdD4ABjxpbml0PgABSQAWTE9uZUNsaW5pdEJhZFNpZ0FnYWluOwASTGph"
1831 "dmEvbGFuZy9PYmplY3Q7ABlPbmVDbGluaXRCYWRTaWdBZ2Fpbi5qYXZhAAFWAAABAAAAAAAAAAAA"
1832 "AAACAAAAEhAPAAEAAQABAAAAAAAAAAQAAABwEAIAAAAOAAAAAgAAiYAEzAIBgYAE4AIKAAAAAAAA"
1833 "AAEAAAAAAAAAAQAAAAcAAABwAAAAAgAAAAQAAACMAAAAAwAAAAIAAACcAAAABQAAAAMAAAC0AAAA"
1834 "BgAAAAEAAADMAAAAAiAAAAcAAADsAAAAASAAAAIAAABMAQAAACAAAAEAAAB4AQAAABAAAAEAAACI"
1835 "AQAA";
1836
1837 size_t length;
1838 std::unique_ptr<uint8_t[]> dex_bytes(DecodeBase64(kDexBase64, &length));
1839 CHECK(dex_bytes != nullptr);
1840 // Note: `dex_file` will be destroyed before `dex_bytes`.
1841 std::unique_ptr<DexFile> dex_file(GetDexFile(dex_bytes.get(), length));
1842 std::string error_msg;
1843 EXPECT_FALSE(DexFileVerifier::Verify(dex_file.get(),
1844 dex_file->Begin(),
1845 dex_file->Size(),
1846 "bad clinit signature",
1847 /*verify_checksum*/ true,
1848 &error_msg));
1849 }
1850
TEST_F(DexFileVerifierTest,BadInitSignature)1851 TEST_F(DexFileVerifierTest, BadInitSignature) {
1852 // Generated DEX file version (037) from:
1853 //
1854 // .class public LBadInitSig;
1855 // .super Ljava/lang/Object;
1856 //
1857 // .method public constructor <init>()I
1858 // .registers 1
1859 // invoke-direct {p0}, Ljava/lang/Object;-><init>()V
1860 // const v0, 1
1861 // return v0
1862 // .end method
1863 //
1864 static const char kDexBase64[] =
1865 "ZGV4CjAzNwCdMdeh1KoHWamF2Prq32LF39YZ78fV7q+wAQAAcAAAAHhWNBIAAAAAAAAAADQBAAAF"
1866 "AAAAcAAAAAQAAACEAAAAAgAAAJQAAAAAAAAAAAAAAAIAAACsAAAAAQAAALwAAADUAAAA3AAAANwA"
1867 "AADkAAAA5wAAAPUAAAAJAQAAAQAAAAIAAAADAAAABAAAAAEAAAAAAAAAAAAAAAQAAAADAAAAAAAA"
1868 "AAEAAAAAAAAAAgABAAAAAAABAAAAAQAAAAIAAAAAAAAA/////wAAAAAqAQAAAAAAAAY8aW5pdD4A"
1869 "AUkADExCYWRJbml0U2lnOwASTGphdmEvbGFuZy9PYmplY3Q7AAFWAAEAAQABAAAAAAAAAAcAAABw"
1870 "EAEAAAAUAAEAAAAPAAAAAQAAgYAEjAIKAAAAAAAAAAEAAAAAAAAAAQAAAAUAAABwAAAAAgAAAAQA"
1871 "AACEAAAAAwAAAAIAAACUAAAABQAAAAIAAACsAAAABgAAAAEAAAC8AAAAAiAAAAUAAADcAAAAASAA"
1872 "AAEAAAAMAQAAACAAAAEAAAAqAQAAABAAAAEAAAA0AQAA";
1873
1874 size_t length;
1875 std::unique_ptr<uint8_t[]> dex_bytes(DecodeBase64(kDexBase64, &length));
1876 CHECK(dex_bytes != nullptr);
1877 // Note: `dex_file` will be destroyed before `dex_bytes`.
1878 std::unique_ptr<DexFile> dex_file(GetDexFile(dex_bytes.get(), length));
1879 std::string error_msg;
1880 EXPECT_FALSE(DexFileVerifier::Verify(dex_file.get(),
1881 dex_file->Begin(),
1882 dex_file->Size(),
1883 "bad init signature",
1884 /*verify_checksum*/ true,
1885 &error_msg));
1886 }
1887
1888 static const char* kInvokeCustomDexFiles[] = {
1889 // TODO(oth): Revisit this test when we have smali / dx support.
1890 // https://cs.corp.google.com/android/toolchain/jack/jack-tests/tests/com/android/jack/java7/invokecustom/test001/Tests.java
1891 "ZGV4CjAzOAAEj12s/acmmdGuDL92SWSBh6iLBjxgomWkCAAAcAAAAHhWNBIAAAAAAAAAALwHAAAx"
1892 "AAAAcAAAABYAAAA0AQAACQAAAIwBAAADAAAA+AEAAAsAAAAQAgAAAQAAAHACAAAMBgAAmAIAAMID"
1893 "AADKAwAAzQMAANIDAADhAwAA5AMAAOoDAAAfBAAAUgQAAIMEAAC4BAAA1AQAAOsEAAD+BAAAEgUA"
1894 "ACYFAAA6BQAAUQUAAG4FAACTBQAAtAUAAN0FAAD/BQAAHgYAADgGAABKBgAAVgYAAFkGAABdBgAA"
1895 "YgYAAGYGAAB7BgAAgAYAAI8GAACdBgAAtAYAAMMGAADSBgAA3gYAAPIGAAD4BgAABgcAAA4HAAAU"
1896 "BwAAGgcAAB8HAAAoBwAANAcAADoHAAABAAAABgAAAAcAAAAIAAAACQAAAAoAAAALAAAADAAAAA0A"
1897 "AAAOAAAADwAAABAAAAARAAAAEgAAABMAAAAUAAAAFQAAABYAAAAXAAAAGAAAABoAAAAeAAAAAgAA"
1898 "AAAAAACMAwAABQAAAAwAAACUAwAABQAAAA4AAACgAwAABAAAAA8AAAAAAAAAGgAAABQAAAAAAAAA"
1899 "GwAAABQAAACsAwAAHAAAABQAAACMAwAAHQAAABQAAAC0AwAAHQAAABQAAAC8AwAAAwADAAMAAAAE"
1900 "AAwAJAAAAAoABgAsAAAABAAEAAAAAAAEAAAAHwAAAAQAAQAoAAAABAAIACoAAAAEAAQALwAAAAYA"
1901 "BQAtAAAACAAEAAAAAAANAAcAAAAAAA8AAgAlAAAAEAADACkAAAASAAYAIQAAAJYHAACWBwAABAAA"
1902 "AAEAAAAIAAAAAAAAABkAAABkAwAAnQcAAAAAAAAEAAAAAgAAAAEAAABjBwAAAQAAAIsHAAACAAAA"
1903 "iwcAAJMHAAABAAEAAQAAAEEHAAAEAAAAcBAGAAAADgADAAIAAAAAAEYHAAADAAAAkAABAg8AAAAF"
1904 "AAMABAAAAE0HAAAQAAAAcQAJAAAADAAcAQQAbkAIABBDDAAiAQ0AcCAHAAEAEQEEAAEAAgAAAFYH"
1905 "AAAMAAAAYgACABIhEjL8IAAAIQAKAW4gBQAQAA4AAwABAAIAAABdBwAACwAAABIgEjH8IAEAEAAK"
1906 "ABJRcSAKAAEADgAAAAAAAAAAAAAAAwAAAAAAAAABAAAAmAIAAAIAAACgAgAABAAAAKgCAAACAAAA"
1907 "AAAAAAMAAAAPAAkAEQAAAAMAAAAHAAkAEQAAAAEAAAAAAAAAAQAAAA4AAAABAAAAFQAGPGluaXQ+"
1908 "AAFJAANJSUkADUlOVk9LRV9TVEFUSUMAAUwABExMTEwAM0xjb20vYW5kcm9pZC9qYWNrL2Fubm90"
1909 "YXRpb25zL0NhbGxlZEJ5SW52b2tlQ3VzdG9tOwAxTGNvbS9hbmRyb2lkL2phY2svYW5ub3RhdGlv"
1910 "bnMvTGlua2VyTWV0aG9kSGFuZGxlOwAvTGNvbS9hbmRyb2lkL2phY2svYW5ub3RhdGlvbnMvTWV0"
1911 "aG9kSGFuZGxlS2luZDsAM0xjb20vYW5kcm9pZC9qYWNrL2phdmE3L2ludm9rZWN1c3RvbS90ZXN0"
1912 "MDAxL1Rlc3RzOwAaTGRhbHZpay9hbm5vdGF0aW9uL1Rocm93czsAFUxqYXZhL2lvL1ByaW50U3Ry"
1913 "ZWFtOwARTGphdmEvbGFuZy9DbGFzczsAEkxqYXZhL2xhbmcvT2JqZWN0OwASTGphdmEvbGFuZy9T"
1914 "dHJpbmc7ABJMamF2YS9sYW5nL1N5c3RlbTsAFUxqYXZhL2xhbmcvVGhyb3dhYmxlOwAbTGphdmEv"
1915 "bGFuZy9pbnZva2UvQ2FsbFNpdGU7ACNMamF2YS9sYW5nL2ludm9rZS9Db25zdGFudENhbGxTaXRl"
1916 "OwAfTGphdmEvbGFuZy9pbnZva2UvTWV0aG9kSGFuZGxlOwAnTGphdmEvbGFuZy9pbnZva2UvTWV0"
1917 "aG9kSGFuZGxlcyRMb29rdXA7ACBMamF2YS9sYW5nL2ludm9rZS9NZXRob2RIYW5kbGVzOwAdTGph"
1918 "dmEvbGFuZy9pbnZva2UvTWV0aG9kVHlwZTsAGExqdW5pdC9mcmFtZXdvcmsvQXNzZXJ0OwAQTG9y"
1919 "Zy9qdW5pdC9UZXN0OwAKVGVzdHMuamF2YQABVgACVkkAA1ZJSQACVkwAE1tMamF2YS9sYW5nL1N0"
1920 "cmluZzsAA2FkZAANYXJndW1lbnRUeXBlcwAMYXNzZXJ0RXF1YWxzABVlbWl0dGVyOiBqYWNrLTQu"
1921 "MC1lbmcADWVuY2xvc2luZ1R5cGUADWZpZWxkQ2FsbFNpdGUACmZpbmRTdGF0aWMAEmludm9rZU1l"
1922 "dGhvZEhhbmRsZQAEa2luZAAMbGlua2VyTWV0aG9kAAZsb29rdXAABG1haW4ABG5hbWUAA291dAAH"
1923 "cHJpbnRsbgAKcmV0dXJuVHlwZQAEdGVzdAAFdmFsdWUAIgAHDgAvAgAABw4ANQMAAAAHDqUAPwEA"
1924 "Bw60ADsABw6lAAABBCAcAhgAGAAmHAEdAgQgHAMYDxgJGBEjGAQnGwArFygrFx8uGAACBQEwHAEY"
1925 "CwETAAMWABcfFQABAAQBAQkAgYAEtAUBCswFAQrkBQEJlAYEAbwGAAAAEwAAAAAAAAABAAAAAAAA"
1926 "AAEAAAAxAAAAcAAAAAIAAAAWAAAANAEAAAMAAAAJAAAAjAEAAAQAAAADAAAA+AEAAAUAAAALAAAA"
1927 "EAIAAAcAAAACAAAAaAIAAAYAAAABAAAAcAIAAAgAAAABAAAAkAIAAAMQAAADAAAAmAIAAAEgAAAF"
1928 "AAAAtAIAAAYgAAABAAAAZAMAAAEQAAAGAAAAjAMAAAIgAAAxAAAAwgMAAAMgAAAFAAAAQQcAAAQg"
1929 "AAADAAAAYwcAAAUgAAABAAAAlgcAAAAgAAABAAAAnQcAAAAQAAABAAAAvAcAAA==",
1930 // https://cs.corp.google.com/android/toolchain/jack/jack-tests/tests/com/android/jack/java7/invokecustom/test002/Tests.java
1931 "ZGV4CjAzOAAzq3aGAwKhT4QQj4lqNfZJAO8Tm24uTyNICQAAcAAAAHhWNBIAAAAAAAAAAGAIAAA2"
1932 "AAAAcAAAABgAAABIAQAACQAAAKgBAAAEAAAAFAIAAA0AAAA0AgAAAQAAAKQCAAB8BgAAzAIAACYE"
1933 "AAAwBAAAOAQAAEQEAABHBAAATAQAAE8EAABVBAAAigQAALwEAADtBAAAIgUAAD4FAABVBQAAaAUA"
1934 "AH0FAACRBQAApQUAALkFAADQBQAA7QUAABIGAAAzBgAAXAYAAH4GAACdBgAAtwYAAMkGAADPBgAA"
1935 "2wYAAN4GAADiBgAA5wYAAOsGAAD/BgAAFAcAABkHAAAoBwAANgcAAE0HAABcBwAAawcAAH4HAACK"
1936 "BwAAkAcAAJgHAACeBwAAqgcAALAHAAC1BwAAxgcAAM8HAADbBwAA4QcAAAMAAAAHAAAACAAAAAkA"
1937 "AAAKAAAACwAAAAwAAAANAAAADgAAAA8AAAAQAAAAEQAAABIAAAATAAAAFAAAABUAAAAWAAAAFwAA"
1938 "ABgAAAAZAAAAGgAAAB0AAAAhAAAAIgAAAAQAAAAAAAAA8AMAAAYAAAAPAAAA+AMAAAUAAAAQAAAA"
1939 "AAAAAAYAAAASAAAABAQAAB0AAAAVAAAAAAAAAB4AAAAVAAAAEAQAAB8AAAAVAAAA8AMAACAAAAAV"
1940 "AAAAGAQAACAAAAAVAAAAIAQAAAMAAwACAAAABAANACgAAAAIAAcAGwAAAAsABgAwAAAABAAEAAAA"
1941 "AAAEAAQAAQAAAAQAAAAjAAAABAAIAC0AAAAEAAQANAAAAAYABQAyAAAACQAEAAEAAAAMAAQAMQAA"
1942 "AA4ABwABAAAAEAABACoAAAARAAIALAAAABIAAwAuAAAAEwAGACUAAAA4CAAAOAgAAAQAAAABAAAA"
1943 "CQAAAAAAAAAcAAAA0AMAAD8IAAAAAAAAAQAAAAEAAAABAAAADggAAAIAAAAtCAAANQgAAAgAAAAE"
1944 "AAEA6AcAACoAAABxAAoAAAAMABwBBAAbAiMAAABiAwIAYgQCABIVI1UWAGIGAgASB00GBQdxMAsA"
1945 "QwUMA25ACQAQMgwAIgEOAHAgCAABAGkBAQAOAA0AbhAHAAAAKPsAAAAAJAABAAEBDCUBAAEAAQAA"
1946 "APUHAAAEAAAAcBAGAAAADgADAAIAAAAAAPoHAAADAAAAkAABAg8AAAAEAAEAAgAAAAEIAAAMAAAA"
1947 "YgADABIhEjL8IAAAIQAKAW4gBQAQAA4AAwABAAIAAAAICAAACwAAABIgEjH8IAEAEAAKABJRcSAM"
1948 "AAEADgAAAAAAAAAAAAAAAgAAAAAAAAACAAAAzAIAAAQAAADUAgAAAgAAAAAAAAADAAAABwAKABIA"
1949 "AAADAAAABwAHABYAAAABAAAAAAAAAAEAAAAPAAAAAQAAABcACDxjbGluaXQ+AAY8aW5pdD4ACkdF"
1950 "VF9TVEFUSUMAAUkAA0lJSQABTAAETExMTAAzTGNvbS9hbmRyb2lkL2phY2svYW5ub3RhdGlvbnMv"
1951 "Q2FsbGVkQnlJbnZva2VDdXN0b207ADBMY29tL2FuZHJvaWQvamFjay9hbm5vdGF0aW9ucy9MaW5r"
1952 "ZXJGaWVsZEhhbmRsZTsAL0xjb20vYW5kcm9pZC9qYWNrL2Fubm90YXRpb25zL01ldGhvZEhhbmRs"
1953 "ZUtpbmQ7ADNMY29tL2FuZHJvaWQvamFjay9qYXZhNy9pbnZva2VjdXN0b20vdGVzdDAwMi9UZXN0"
1954 "czsAGkxkYWx2aWsvYW5ub3RhdGlvbi9UaHJvd3M7ABVMamF2YS9pby9QcmludFN0cmVhbTsAEUxq"
1955 "YXZhL2xhbmcvQ2xhc3M7ABNMamF2YS9sYW5nL0ludGVnZXI7ABJMamF2YS9sYW5nL09iamVjdDsA"
1956 "EkxqYXZhL2xhbmcvU3RyaW5nOwASTGphdmEvbGFuZy9TeXN0ZW07ABVMamF2YS9sYW5nL1Rocm93"
1957 "YWJsZTsAG0xqYXZhL2xhbmcvaW52b2tlL0NhbGxTaXRlOwAjTGphdmEvbGFuZy9pbnZva2UvQ29u"
1958 "c3RhbnRDYWxsU2l0ZTsAH0xqYXZhL2xhbmcvaW52b2tlL01ldGhvZEhhbmRsZTsAJ0xqYXZhL2xh"
1959 "bmcvaW52b2tlL01ldGhvZEhhbmRsZXMkTG9va3VwOwAgTGphdmEvbGFuZy9pbnZva2UvTWV0aG9k"
1960 "SGFuZGxlczsAHUxqYXZhL2xhbmcvaW52b2tlL01ldGhvZFR5cGU7ABhManVuaXQvZnJhbWV3b3Jr"
1961 "L0Fzc2VydDsAEExvcmcvanVuaXQvVGVzdDsABFRZUEUAClRlc3RzLmphdmEAAVYAAlZJAANWSUkA"
1962 "AlZMABJbTGphdmEvbGFuZy9DbGFzczsAE1tMamF2YS9sYW5nL1N0cmluZzsAA2FkZAANYXJndW1l"
1963 "bnRUeXBlcwAMYXNzZXJ0RXF1YWxzABVlbWl0dGVyOiBqYWNrLTQuMC1lbmcADWVuY2xvc2luZ1R5"
1964 "cGUADWZpZWxkQ2FsbFNpdGUAEWZpZWxkTWV0aG9kSGFuZGxlAApmaW5kU3RhdGljAARraW5kAAZs"
1965 "b29rdXAABG1haW4ACm1ldGhvZFR5cGUABG5hbWUAA291dAAPcHJpbnRTdGFja1RyYWNlAAdwcmlu"
1966 "dGxuAApyZXR1cm5UeXBlAAR0ZXN0AAV2YWx1ZQAoAAcOAR0PAnh3Jh4AIQAHDgA2AgAABw4APwEA"
1967 "Bw60ADsABw6lAAABBCQcAhgAGAApHAEdAgMnGAQrGwAvFygvFyMzGAACBQE1HAEYDAEUAAMWABcj"
1968 "FQABAAQBAQkAiIAE4AUBgYAE0AYBCugGAQmABwQBqAcAAAATAAAAAAAAAAEAAAAAAAAAAQAAADYA"
1969 "AABwAAAAAgAAABgAAABIAQAAAwAAAAkAAACoAQAABAAAAAQAAAAUAgAABQAAAA0AAAA0AgAABwAA"
1970 "AAIAAACcAgAABgAAAAEAAACkAgAACAAAAAEAAADEAgAAAxAAAAIAAADMAgAAASAAAAUAAADgAgAA"
1971 "BiAAAAEAAADQAwAAARAAAAYAAADwAwAAAiAAADYAAAAmBAAAAyAAAAUAAADoBwAABCAAAAMAAAAO"
1972 "CAAABSAAAAEAAAA4CAAAACAAAAEAAAA/CAAAABAAAAEAAABgCAAA",
1973 // https://cs.corp.google.com/android/toolchain/jack/jack-tests/tests/com/android/jack/java7/invokecustom/test003/Tests.java
1974 "ZGV4CjAzOABjnhkFatj30/7cHTCJsfr7vAjz9/p+Y+TcCAAAcAAAAHhWNBIAAAAAAAAAAPQHAAAx"
1975 "AAAAcAAAABYAAAA0AQAACQAAAIwBAAADAAAA+AEAAAsAAAAQAgAAAQAAAHACAABEBgAAmAIAAOoD"
1976 "AADyAwAA9QMAAP4DAAANBAAAEAQAABYEAABLBAAAfgQAAK8EAADkBAAAAAUAABcFAAAqBQAAPgUA"
1977 "AFIFAABmBQAAfQUAAJoFAAC/BQAA4AUAAAkGAAArBgAASgYAAGQGAAB2BgAAggYAAIUGAACJBgAA"
1978 "jgYAAJIGAACnBgAArAYAALsGAADJBgAA4AYAAO8GAAD+BgAACgcAAB4HAAAkBwAAMgcAADoHAABA"
1979 "BwAARgcAAEsHAABUBwAAYAcAAGYHAAABAAAABgAAAAcAAAAIAAAACQAAAAoAAAALAAAADAAAAA0A"
1980 "AAAOAAAADwAAABAAAAARAAAAEgAAABMAAAAUAAAAFQAAABYAAAAXAAAAGAAAABoAAAAeAAAAAgAA"
1981 "AAAAAACkAwAABQAAAAwAAAC0AwAABQAAAA4AAADAAwAABAAAAA8AAAAAAAAAGgAAABQAAAAAAAAA"
1982 "GwAAABQAAADMAwAAHAAAABQAAADUAwAAHQAAABQAAADcAwAAHQAAABQAAADkAwAAAwADAAMAAAAE"
1983 "AAwAJAAAAAoABgAsAAAABAAEAAAAAAAEAAAAHwAAAAQAAQAoAAAABAAIACoAAAAEAAQALwAAAAYA"
1984 "BQAtAAAACAAEAAAAAAANAAcAAAAAAA8AAgAlAAAAEAADACkAAAASAAYAIQAAAM4HAADOBwAABAAA"
1985 "AAEAAAAIAAAAAAAAABkAAAB8AwAA1QcAAAAAAAAEAAAAAgAAAAEAAACTBwAAAQAAAMMHAAACAAAA"
1986 "wwcAAMsHAAABAAEAAQAAAG0HAAAEAAAAcBAGAAAADgAHAAYAAAAAAHIHAAAHAAAAkAABArAwsECw"
1987 "ULBgDwAAAAUAAwAEAAAAfQcAABAAAABxAAkAAAAMABwBBABuQAgAEEMMACIBDQBwIAcAAQARAQgA"
1988 "AQACAAAAhgcAABAAAABiBgIAEhASIRIyEkMSVBJl/QYAAAAACgBuIAUABgAOAAcAAQACAAAAjQcA"
1989 "ABAAAAASEBIhEjISQxJUEmX9BgEAAAAKABMBFQBxIAoAAQAOAAAAAAAAAAAAAwAAAAAAAAABAAAA"
1990 "mAIAAAIAAACgAgAABAAAAKgCAAAGAAAAAAAAAAAAAAAAAAAAAwAAAA8ACQARAAAAAwAAAAcACQAR"
1991 "AAAAAQAAAAAAAAACAAAAAAAAAAEAAAAOAAAAAQAAABUABjxpbml0PgABSQAHSUlJSUlJSQANSU5W"
1992 "T0tFX1NUQVRJQwABTAAETExMTAAzTGNvbS9hbmRyb2lkL2phY2svYW5ub3RhdGlvbnMvQ2FsbGVk"
1993 "QnlJbnZva2VDdXN0b207ADFMY29tL2FuZHJvaWQvamFjay9hbm5vdGF0aW9ucy9MaW5rZXJNZXRo"
1994 "b2RIYW5kbGU7AC9MY29tL2FuZHJvaWQvamFjay9hbm5vdGF0aW9ucy9NZXRob2RIYW5kbGVLaW5k"
1995 "OwAzTGNvbS9hbmRyb2lkL2phY2svamF2YTcvaW52b2tlY3VzdG9tL3Rlc3QwMDMvVGVzdHM7ABpM"
1996 "ZGFsdmlrL2Fubm90YXRpb24vVGhyb3dzOwAVTGphdmEvaW8vUHJpbnRTdHJlYW07ABFMamF2YS9s"
1997 "YW5nL0NsYXNzOwASTGphdmEvbGFuZy9PYmplY3Q7ABJMamF2YS9sYW5nL1N0cmluZzsAEkxqYXZh"
1998 "L2xhbmcvU3lzdGVtOwAVTGphdmEvbGFuZy9UaHJvd2FibGU7ABtMamF2YS9sYW5nL2ludm9rZS9D"
1999 "YWxsU2l0ZTsAI0xqYXZhL2xhbmcvaW52b2tlL0NvbnN0YW50Q2FsbFNpdGU7AB9MamF2YS9sYW5n"
2000 "L2ludm9rZS9NZXRob2RIYW5kbGU7ACdMamF2YS9sYW5nL2ludm9rZS9NZXRob2RIYW5kbGVzJExv"
2001 "b2t1cDsAIExqYXZhL2xhbmcvaW52b2tlL01ldGhvZEhhbmRsZXM7AB1MamF2YS9sYW5nL2ludm9r"
2002 "ZS9NZXRob2RUeXBlOwAYTGp1bml0L2ZyYW1ld29yay9Bc3NlcnQ7ABBMb3JnL2p1bml0L1Rlc3Q7"
2003 "AApUZXN0cy5qYXZhAAFWAAJWSQADVklJAAJWTAATW0xqYXZhL2xhbmcvU3RyaW5nOwADYWRkAA1h"
2004 "cmd1bWVudFR5cGVzAAxhc3NlcnRFcXVhbHMAFWVtaXR0ZXI6IGphY2stNC4wLWVuZwANZW5jbG9z"
2005 "aW5nVHlwZQANZmllbGRDYWxsU2l0ZQAKZmluZFN0YXRpYwASaW52b2tlTWV0aG9kSGFuZGxlAARr"
2006 "aW5kAAxsaW5rZXJNZXRob2QABmxvb2t1cAAEbWFpbgAEbmFtZQADb3V0AAdwcmludGxuAApyZXR1"
2007 "cm5UeXBlAAR0ZXN0AAV2YWx1ZQAiAAcOAC8GAAAAAAAABw4ANQMAAAAHDqUAPwEABw7wADsABw7w"
2008 "AAABBCAcBhgAGAAYABgAGAAYACYcAR0CBCAcAxgPGAkYESMYBCcbACsXKCsXHy4YAAIFATAcARgL"
2009 "ARMAAxYAFx8VAAEABAEBCQCBgAS0BQEKzAUBCuwFAQmcBgQBzAYAAAATAAAAAAAAAAEAAAAAAAAA"
2010 "AQAAADEAAABwAAAAAgAAABYAAAA0AQAAAwAAAAkAAACMAQAABAAAAAMAAAD4AQAABQAAAAsAAAAQ"
2011 "AgAABwAAAAIAAABoAgAABgAAAAEAAABwAgAACAAAAAEAAACQAgAAAxAAAAMAAACYAgAAASAAAAUA"
2012 "AAC0AgAABiAAAAEAAAB8AwAAARAAAAcAAACkAwAAAiAAADEAAADqAwAAAyAAAAUAAABtBwAABCAA"
2013 "AAMAAACTBwAABSAAAAEAAADOBwAAACAAAAEAAADVBwAAABAAAAEAAAD0BwAA",
2014 // https://cs.corp.google.com/android/toolchain/jack/jack-tests/tests/com/android/jack/java7/invokecustom/test004/Tests.java
2015 "ZGV4CjAzOABvUVfbV74qWbSOEsgKP+EzahlNQLW2/8TMDAAAcAAAAHhWNBIAAAAAAAAAAOQLAABS"
2016 "AAAAcAAAAB8AAAC4AQAAEAAAADQCAAADAAAA9AIAABIAAAAMAwAAAQAAAKQDAAAACQAAzAMAANYF"
2017 "AADZBQAA4QUAAOkFAADsBQAA7wUAAPIFAAD1BQAA/AUAAP8FAAAEBgAAEwYAABYGAAAZBgAAHwYA"
2018 "AC8GAABkBgAAjQYAAMAGAADxBgAAJgcAAEUHAABhBwAAeAcAAIoHAACdBwAAsQcAAMUHAADZBwAA"
2019 "8AcAAA0IAAAyCAAAUwgAAHwIAACeCAAAvQgAANcIAADpCAAA7AgAAPgIAAD7CAAAAAkAAAYJAAAM"
2020 "CQAAEAkAABUJAAAaCQAAHgkAACMJAAAnCQAAKgkAADMJAABICQAATQkAAFwJAABqCQAAdgkAAIQJ"
2021 "AACPCQAAmgkAAKYJAACzCQAAygkAANkJAADoCQAA9AkAAAAKAAAKCgAAHgoAACQKAAAyCgAAPQoA"
2022 "AEUKAABLCgAAYgoAAGgKAABtCgAAdgoAAIIKAACOCgAAmwoAAKEKAAADAAAABAAAAAUAAAAGAAAA"
2023 "CAAAAAsAAAAPAAAAEAAAABEAAAASAAAAEwAAABQAAAAVAAAAFgAAABgAAAAZAAAAGgAAABsAAAAc"
2024 "AAAAHQAAAB4AAAAfAAAAIAAAACEAAAAiAAAAIwAAACQAAAAlAAAAJwAAADEAAAAzAAAACQAAAAQA"
2025 "AABMBQAADgAAABMAAABUBQAADQAAABUAAAB0BQAADAAAABYAAAAAAAAAJwAAABwAAAAAAAAAKAAA"
2026 "ABwAAACABQAAKQAAABwAAACIBQAAKgAAABwAAACUBQAAKwAAABwAAACgBQAALAAAABwAAABMBQAA"
2027 "LQAAABwAAACoBQAALwAAABwAAACwBQAALwAAABwAAAC4BQAALgAAABwAAADABQAAMAAAABwAAADI"
2028 "BQAALgAAABwAAADQBQAACQAJAAoAAAAKABMAPwAAABEADQBLAAAACgAEAAIAAAAKAAAANAAAAAoA"
2029 "AQBFAAAACgAPAEgAAAAKAAQAUAAAAA0ACABMAAAADwAEAAIAAAAUAA0AAgAAABYAAgBAAAAAFwAD"
2030 "AEcAAAAZAAUANgAAABkABgA2AAAAGQAHADYAAAAZAAkANgAAABkACgA2AAAAGQALADYAAAAZAAwA"
2031 "NgAAABkADgA3AAAAnQsAAJ0LAAAKAAAAAQAAAA8AAAAAAAAAJgAAACQFAADGCwAAAAAAAAQAAAAC"
2032 "AAAAAQAAAN4KAAACAAAAegsAAJILAAACAAAAkgsAAJoLAAABAAEAAQAAAKgKAAAEAAAAcBAGAAAA"
2033 "DgADAAIAAAAAAK0KAAADAAAAkAABAg8AAAAYAA8ABgAAALQKAABTAAAAcRARAAwAEhJxIA0A0gAT"
2034 "AmEAcSAKAOIAEwIABHEgDQDyABISAgAQAHEgDQACABICFAOamTFBAgARAHEwDAADAhYGAAAYApqZ"
2035 "mZmZmQFABQQSAHcGCwACABsCBwAAAAgAFABxIBAAAgAcAgoACAAVAHEgDwACABcCFc1bBwUAFgBx"
2036 "QA4AMhBxAAkAAAAMAhwDCgBuQAgAMroMAiIDFABwIAcAIwARAwAABAABAAIAAADRCgAADAAAAGIA"
2037 "AgASIRIy/CAAACEACgFuIAUAEAAOAAMAAQACAAAA2AoAAAsAAAASIBIx/CABABAACgASUXEgDQAB"
2038 "AA4AAAAAAAAAAAAAAAMAAAAAAAAAAQAAAMwDAAACAAAA1AMAAAQAAADgAwAAAgAAAAQABAANAAAA"
2039 "FgAQABgAHQAAAAEAGwAEAAMAAgAQAA4ABQAAAAMAAAAOABAAGAAAAAIAAAABAAEAAwAAAAIAAgAC"
2040 "AAAAAwAAAAMAAwADAAAAAQAAAAQAAAACAAAABQAFAAIAAAAPAA8AAgAAABAAEAABAAAAFQAAAAEA"
2041 "AAAdAAAAAQAAAB4AASgABjwqPjtKKQAGPGluaXQ+AAFCAAFDAAFEAAFGAAVIZWxsbwABSQADSUlJ"
2042 "AA1JTlZPS0VfU1RBVElDAAFKAAFMAARMTExMAA5MTExMWkJDU0lGRExMSgAzTGNvbS9hbmRyb2lk"
2043 "L2phY2svYW5ub3RhdGlvbnMvQ2FsbGVkQnlJbnZva2VDdXN0b207ACdMY29tL2FuZHJvaWQvamFj"
2044 "ay9hbm5vdGF0aW9ucy9Db25zdGFudDsAMUxjb20vYW5kcm9pZC9qYWNrL2Fubm90YXRpb25zL0xp"
2045 "bmtlck1ldGhvZEhhbmRsZTsAL0xjb20vYW5kcm9pZC9qYWNrL2Fubm90YXRpb25zL01ldGhvZEhh"
2046 "bmRsZUtpbmQ7ADNMY29tL2FuZHJvaWQvamFjay9qYXZhNy9pbnZva2VjdXN0b20vdGVzdDAwNC9U"
2047 "ZXN0czsAHUxkYWx2aWsvYW5ub3RhdGlvbi9TaWduYXR1cmU7ABpMZGFsdmlrL2Fubm90YXRpb24v"
2048 "VGhyb3dzOwAVTGphdmEvaW8vUHJpbnRTdHJlYW07ABBMamF2YS9sYW5nL0NsYXNzABFMamF2YS9s"
2049 "YW5nL0NsYXNzOwASTGphdmEvbGFuZy9PYmplY3Q7ABJMamF2YS9sYW5nL1N0cmluZzsAEkxqYXZh"
2050 "L2xhbmcvU3lzdGVtOwAVTGphdmEvbGFuZy9UaHJvd2FibGU7ABtMamF2YS9sYW5nL2ludm9rZS9D"
2051 "YWxsU2l0ZTsAI0xqYXZhL2xhbmcvaW52b2tlL0NvbnN0YW50Q2FsbFNpdGU7AB9MamF2YS9sYW5n"
2052 "L2ludm9rZS9NZXRob2RIYW5kbGU7ACdMamF2YS9sYW5nL2ludm9rZS9NZXRob2RIYW5kbGVzJExv"
2053 "b2t1cDsAIExqYXZhL2xhbmcvaW52b2tlL01ldGhvZEhhbmRsZXM7AB1MamF2YS9sYW5nL2ludm9r"
2054 "ZS9NZXRob2RUeXBlOwAYTGp1bml0L2ZyYW1ld29yay9Bc3NlcnQ7ABBMb3JnL2p1bml0L1Rlc3Q7"
2055 "AAFTAApUZXN0cy5qYXZhAAFWAANWQ0MABFZEREQABFZGRkYAAlZJAANWSUkAA1ZKSgACVkwAA1ZM"
2056 "TAACVloAAVoAB1pCQ1NJRkQAE1tMamF2YS9sYW5nL1N0cmluZzsAA2FkZAANYXJndW1lbnRUeXBl"
2057 "cwAMYXNzZXJ0RXF1YWxzAAphc3NlcnRUcnVlAAxib29sZWFuVmFsdWUACWJ5dGVWYWx1ZQAJY2hh"
2058 "clZhbHVlAApjbGFzc1ZhbHVlAAtkb3VibGVWYWx1ZQAVZW1pdHRlcjogamFjay00LjAtZW5nAA1l"
2059 "bmNsb3NpbmdUeXBlAA1maWVsZENhbGxTaXRlAApmaW5kU3RhdGljAApmbG9hdFZhbHVlAAhpbnRW"
2060 "YWx1ZQASaW52b2tlTWV0aG9kSGFuZGxlAARraW5kAAxsaW5rZXJNZXRob2QACWxvbmdWYWx1ZQAG"
2061 "bG9va3VwAARtYWluABVtZXRob2RIYW5kbGVFeHRyYUFyZ3MABG5hbWUAA291dAAHcHJpbnRsbgAK"
2062 "cmV0dXJuVHlwZQAKc2hvcnRWYWx1ZQALc3RyaW5nVmFsdWUABHRlc3QABXZhbHVlACMABw4ANwIA"
2063 "AAcOAD4NAAAAAAAAAAAAAAAAAAcOPEtaWmmWw4d4h6UAUgEABw60AE4ABw6lAAAGBTUcAhgEGARD"
2064 "HAEdCAQ1HA0YFhgQGBgYHRgAGAEYGxgEGAMYAhgQGA4YBT4YCkQbAEoXRUkcCh0HATgcAT8dBwE5"
2065 "HAEAAR0HATocAQNhHQcBThwBIgAEHQcBQhwBBAEdBwFBHAFwmpkxQR0HATwcAfGamZmZmZkBQB0H"
2066 "AU8cARcHHQcBOxwBGAodBwFGHAFmFc1bB0oXNE0YBAILAVEcCRcAFyAXGhciFzIXGhcXFwEXHQIM"
2067 "AVEcARgSARoADRYAFzQVAAQBBAEEYSQABAQBcJqZMUHxmpmZmZmZAUAXBxgKZhXNWwcBAAQBAQkA"
2068 "gYAE7AcBCoQIAQqcCAEJ1AkEAfwJAAATAAAAAAAAAAEAAAAAAAAAAQAAAFIAAABwAAAAAgAAAB8A"
2069 "AAC4AQAAAwAAABAAAAA0AgAABAAAAAMAAAD0AgAABQAAABIAAAAMAwAABwAAAAIAAACcAwAABgAA"
2070 "AAEAAACkAwAACAAAAAEAAADEAwAAAxAAAAMAAADMAwAAASAAAAUAAADsAwAABiAAAAEAAAAkBQAA"
2071 "ARAAAA0AAABMBQAAAiAAAFIAAADWBQAAAyAAAAUAAACoCgAABCAAAAQAAADeCgAABSAAAAEAAACd"
2072 "CwAAACAAAAEAAADGCwAAABAAAAEAAADkCwAA"
2073 };
2074
TEST_F(DexFileVerifierTest,InvokeCustomDexSamples)2075 TEST_F(DexFileVerifierTest, InvokeCustomDexSamples) {
2076 for (size_t i = 0; i < arraysize(kInvokeCustomDexFiles); ++i) {
2077 size_t length;
2078 std::unique_ptr<uint8_t[]> dex_bytes(DecodeBase64(kInvokeCustomDexFiles[i], &length));
2079 CHECK(dex_bytes != nullptr);
2080 // Note: `dex_file` will be destroyed before `dex_bytes`.
2081 std::unique_ptr<DexFile> dex_file(GetDexFile(dex_bytes.get(), length));
2082 std::string error_msg;
2083 EXPECT_TRUE(DexFileVerifier::Verify(dex_file.get(),
2084 dex_file->Begin(),
2085 dex_file->Size(),
2086 "good checksum, verify",
2087 /*verify_checksum*/ true,
2088 &error_msg));
2089 // TODO(oth): Test corruptions (b/35308502)
2090 }
2091 }
2092
TEST_F(DexFileVerifierTest,BadStaticFieldInitialValuesArray)2093 TEST_F(DexFileVerifierTest, BadStaticFieldInitialValuesArray) {
2094 // Generated DEX file version (037) from:
2095 //
2096 // .class public LBadStaticFieldInitialValuesArray;
2097 // .super Ljava/lang/Object;
2098 //
2099 // # static fields
2100 // .field static final c:C = 'c'
2101 // .field static final i:I = 0x1
2102 // .field static final s:Ljava/lang/String; = "s"
2103 //
2104 // # direct methods
2105 // .method public constructor <init>()V
2106 // .registers 1
2107 // invoke-direct {p0}, Ljava/lang/Object;-><init>()V
2108 // return-void
2109 // .end method
2110 //
2111 // Output file was hex edited so that static field "i" has string typing in initial values array.
2112 static const char kDexBase64[] =
2113 "ZGV4CjAzNQBrMi4cCPcMvvXNRw0uI6RRubwMPwgEYXIsAgAAcAAAAHhWNBIAAAAAAAAAAIwBAAAL"
2114 "AAAAcAAAAAYAAACcAAAAAQAAALQAAAADAAAAwAAAAAIAAADYAAAAAQAAAOgAAAAkAQAACAEAACAB"
2115 "AAAoAQAAMAEAADMBAAA2AQAAOwEAAE8BAABjAQAAZgEAAGkBAABsAQAAAgAAAAMAAAAEAAAABQAA"
2116 "AAYAAAAHAAAABwAAAAUAAAAAAAAAAgAAAAgAAAACAAEACQAAAAIABAAKAAAAAgAAAAAAAAADAAAA"
2117 "AAAAAAIAAAABAAAAAwAAAAAAAAABAAAAAAAAAHsBAAB0AQAAAQABAAEAAABvAQAABAAAAHAQAQAA"
2118 "AA4ABjxpbml0PgAGQS5qYXZhAAFDAAFJAANMQTsAEkxqYXZhL2xhbmcvT2JqZWN0OwASTGphdmEv"
2119 "bGFuZy9TdHJpbmc7AAFWAAFjAAFpAAFzAAEABw4AAwNjFwoXCgMAAQAAGAEYARgAgYAEiAIADQAA"
2120 "AAAAAAABAAAAAAAAAAEAAAALAAAAcAAAAAIAAAAGAAAAnAAAAAMAAAABAAAAtAAAAAQAAAADAAAA"
2121 "wAAAAAUAAAACAAAA2AAAAAYAAAABAAAA6AAAAAEgAAABAAAACAEAAAIgAAALAAAAIAEAAAMgAAAB"
2122 "AAAAbwEAAAUgAAABAAAAdAEAAAAgAAABAAAAewEAAAAQAAABAAAAjAEAAA==";
2123
2124 size_t length;
2125 std::unique_ptr<uint8_t[]> dex_bytes(DecodeBase64(kDexBase64, &length));
2126 CHECK(dex_bytes != nullptr);
2127 // Note: `dex_file` will be destroyed before `dex_bytes`.
2128 std::unique_ptr<DexFile> dex_file(GetDexFile(dex_bytes.get(), length));
2129 std::string error_msg;
2130 EXPECT_FALSE(DexFileVerifier::Verify(dex_file.get(),
2131 dex_file->Begin(),
2132 dex_file->Size(),
2133 "bad static field initial values array",
2134 /*verify_checksum*/ true,
2135 &error_msg));
2136 }
2137
TEST_F(DexFileVerifierTest,GoodStaticFieldInitialValuesArray)2138 TEST_F(DexFileVerifierTest, GoodStaticFieldInitialValuesArray) {
2139 // Generated DEX file version (037) from:
2140 //
2141 // .class public LGoodStaticFieldInitialValuesArray;
2142 // .super Ljava/lang/Object;
2143 //
2144 // # static fields
2145 // .field static final b:B = 0x1t
2146 // .field static final c:C = 'c'
2147 // .field static final d:D = 0.6
2148 // .field static final f:F = 0.5f
2149 // .field static final i:I = 0x3
2150 // .field static final j:J = 0x4L
2151 // .field static final l1:Ljava/lang/String;
2152 // .field static final l2:Ljava/lang/String; = "s"
2153 // .field static final l3:Ljava/lang/Class; = Ljava/lang/String;
2154 // .field static final s:S = 0x2s
2155 // .field static final z:Z = true
2156 //
2157 // # direct methods
2158 // .method public constructor <init>()V
2159 // .registers 1
2160 // invoke-direct {p0}, Ljava/lang/Object;-><init>()V
2161 // return-void
2162 // .end method
2163 static const char kDexBase64[] =
2164 "ZGV4CjAzNQAwWxLbdhFa1NGiFWjsy5fhUCHxe5QHtPY8AwAAcAAAAHhWNBIAAAAAAAAAAJwCAAAZ"
2165 "AAAAcAAAAA0AAADUAAAAAQAAAAgBAAALAAAAFAEAAAIAAABsAQAAAQAAAHwBAACgAQAAnAEAAJwB"
2166 "AACkAQAApwEAAKoBAACtAQAAsAEAALMBAAC2AQAA2wEAAO4BAAACAgAAFgIAABkCAAAcAgAAHwIA"
2167 "ACICAAAlAgAAKAIAACsCAAAuAgAAMQIAADUCAAA5AgAAPQIAAEACAAABAAAAAgAAAAMAAAAEAAAA"
2168 "BQAAAAYAAAAHAAAACAAAAAkAAAAKAAAACwAAAAwAAAANAAAADAAAAAsAAAAAAAAABgAAAA4AAAAG"
2169 "AAEADwAAAAYAAgAQAAAABgADABEAAAAGAAQAEgAAAAYABQATAAAABgAJABQAAAAGAAkAFQAAAAYA"
2170 "BwAWAAAABgAKABcAAAAGAAwAGAAAAAYAAAAAAAAACAAAAAAAAAAGAAAAAQAAAAgAAAAAAAAA////"
2171 "/wAAAAB8AgAARAIAAAY8aW5pdD4AAUIAAUMAAUQAAUYAAUkAAUoAI0xHb29kU3RhdGljRmllbGRJ"
2172 "bml0aWFsVmFsdWVzQXJyYXk7ABFMamF2YS9sYW5nL0NsYXNzOwASTGphdmEvbGFuZy9PYmplY3Q7"
2173 "ABJMamF2YS9sYW5nL1N0cmluZzsAAVMAAVYAAVoAAWIAAWMAAWQAAWYAAWkAAWoAAmwxAAJsMgAC"
2174 "bDMAAXMAAXoAAAsAAQNj8TMzMzMzM+M/ED8EAwYEHhcXGAkCAj8AAAAAAQABAAEAAAAAAAAABAAA"
2175 "AHAQAQAAAA4ACwABAAAYARgBGAEYARgBGAEYARgBGAEYARgAgYAE5AQNAAAAAAAAAAEAAAAAAAAA"
2176 "AQAAABkAAABwAAAAAgAAAA0AAADUAAAAAwAAAAEAAAAIAQAABAAAAAsAAAAUAQAABQAAAAIAAABs"
2177 "AQAABgAAAAEAAAB8AQAAAiAAABkAAACcAQAABSAAAAEAAABEAgAAAxAAAAEAAABgAgAAASAAAAEA"
2178 "AABkAgAAACAAAAEAAAB8AgAAABAAAAEAAACcAgAA";
2179
2180 size_t length;
2181 std::unique_ptr<uint8_t[]> dex_bytes(DecodeBase64(kDexBase64, &length));
2182 CHECK(dex_bytes != nullptr);
2183 // Note: `dex_file` will be destroyed before `dex_bytes`.
2184 std::unique_ptr<DexFile> dex_file(GetDexFile(dex_bytes.get(), length));
2185 std::string error_msg;
2186 EXPECT_TRUE(DexFileVerifier::Verify(dex_file.get(),
2187 dex_file->Begin(),
2188 dex_file->Size(),
2189 "good static field initial values array",
2190 /*verify_checksum*/ true,
2191 &error_msg));
2192 }
2193
2194 } // namespace art
2195