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