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