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