blob: 71c0ad92958f681d838507451a3411ebfd5f5f3c [file] [log] [blame]
Andreas Gampedf10b322014-06-11 21:46:05 -07001/*
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
Ian Rogerse63db272014-07-15 15:36:11 -070019#include "sys/mman.h"
Andreas Gampedf10b322014-06-11 21:46:05 -070020#include "zlib.h"
Andreas Gampee6215c02015-08-31 18:54:38 -070021#include <functional>
Ian Rogerse63db272014-07-15 15:36:11 -070022#include <memory>
Andreas Gampedf10b322014-06-11 21:46:05 -070023
Ian Rogerse63db272014-07-15 15:36:11 -070024#include "base/unix_file/fd_file.h"
Andreas Gampee6215c02015-08-31 18:54:38 -070025#include "base/bit_utils.h"
Andreas Gampedf10b322014-06-11 21:46:05 -070026#include "base/macros.h"
Ian Rogerse63db272014-07-15 15:36:11 -070027#include "common_runtime_test.h"
Andreas Gampee6215c02015-08-31 18:54:38 -070028#include "dex_file-inl.h"
29#include "leb128.h"
Ian Rogerse63db272014-07-15 15:36:11 -070030#include "scoped_thread_state_change.h"
31#include "thread-inl.h"
Andreas Gampedf10b322014-06-11 21:46:05 -070032
33namespace art {
34
Ian Rogers13735952014-10-08 12:43:28 -070035static const uint8_t kBase64Map[256] = {
Andreas Gampedf10b322014-06-11 21:46:05 -070036 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
37 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
38 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
39 255, 255, 255, 255, 255, 255, 255, 62, 255, 255, 255, 63,
40 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255,
41 255, 254, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6,
42 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, // NOLINT
43 19, 20, 21, 22, 23, 24, 25, 255, 255, 255, 255, 255, // NOLINT
44 255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
45 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, // NOLINT
46 49, 50, 51, 255, 255, 255, 255, 255, 255, 255, 255, 255, // NOLINT
47 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
48 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
49 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
50 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
51 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
52 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
53 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
54 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
55 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
56 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
57 255, 255, 255, 255
58};
59
Alex Light0ed05212016-05-06 17:36:36 -070060// Make the Dex file version 37.
61static void MakeDexVersion37(DexFile* dex_file) {
62 size_t offset = OFFSETOF_MEMBER(DexFile::Header, magic_) + 6;
63 CHECK_EQ(*(dex_file->Begin() + offset), '5');
64 *(const_cast<uint8_t*>(dex_file->Begin()) + offset) = '7';
65}
66
Vladimir Marko59399ab2016-05-03 16:31:52 +010067static inline std::unique_ptr<uint8_t[]> DecodeBase64(const char* src, size_t* dst_size) {
Ian Rogers13735952014-10-08 12:43:28 -070068 std::vector<uint8_t> tmp;
Andreas Gampedf10b322014-06-11 21:46:05 -070069 uint32_t t = 0, y = 0;
70 int g = 3;
71 for (size_t i = 0; src[i] != '\0'; ++i) {
Ian Rogers13735952014-10-08 12:43:28 -070072 uint8_t c = kBase64Map[src[i] & 0xFF];
Andreas Gampedf10b322014-06-11 21:46:05 -070073 if (c == 255) continue;
74 // the final = symbols are read and used to trim the remaining bytes
75 if (c == 254) {
76 c = 0;
77 // prevent g < 0 which would potentially allow an overflow later
78 if (--g < 0) {
79 *dst_size = 0;
80 return nullptr;
81 }
82 } else if (g != 3) {
83 // we only allow = to be at the end
84 *dst_size = 0;
85 return nullptr;
86 }
87 t = (t << 6) | c;
88 if (++y == 4) {
89 tmp.push_back((t >> 16) & 255);
90 if (g > 1) {
91 tmp.push_back((t >> 8) & 255);
92 }
93 if (g > 2) {
94 tmp.push_back(t & 255);
95 }
96 y = t = 0;
97 }
98 }
99 if (y != 0) {
100 *dst_size = 0;
101 return nullptr;
102 }
Ian Rogers13735952014-10-08 12:43:28 -0700103 std::unique_ptr<uint8_t[]> dst(new uint8_t[tmp.size()]);
Andreas Gampedf10b322014-06-11 21:46:05 -0700104 if (dst_size != nullptr) {
105 *dst_size = tmp.size();
106 } else {
107 *dst_size = 0;
108 }
109 std::copy(tmp.begin(), tmp.end(), dst.get());
Vladimir Marko59399ab2016-05-03 16:31:52 +0100110 return dst;
Andreas Gampedf10b322014-06-11 21:46:05 -0700111}
112
Andreas Gampee6215c02015-08-31 18:54:38 -0700113static void FixUpChecksum(uint8_t* dex_file) {
114 DexFile::Header* header = reinterpret_cast<DexFile::Header*>(dex_file);
115 uint32_t expected_size = header->file_size_;
116 uint32_t adler_checksum = adler32(0L, Z_NULL, 0);
117 const uint32_t non_sum = sizeof(DexFile::Header::magic_) + sizeof(DexFile::Header::checksum_);
118 const uint8_t* non_sum_ptr = dex_file + non_sum;
119 adler_checksum = adler32(adler_checksum, non_sum_ptr, expected_size - non_sum);
120 header->checksum_ = adler_checksum;
121}
122
Andreas Gampee6215c02015-08-31 18:54:38 -0700123class DexFileVerifierTest : public CommonRuntimeTest {
124 protected:
Aart Bik37d6a3b2016-06-21 18:30:10 -0700125 DexFile* GetDexFile(const uint8_t* dex_bytes, size_t length) {
126 return new DexFile(dex_bytes, length, "tmp", 0, nullptr, nullptr);
127 }
128
Andreas Gampee6215c02015-08-31 18:54:38 -0700129 void VerifyModification(const char* dex_file_base64_content,
130 const char* location,
131 std::function<void(DexFile*)> f,
132 const char* expected_error) {
Vladimir Marko59399ab2016-05-03 16:31:52 +0100133 size_t length;
134 std::unique_ptr<uint8_t[]> dex_bytes = DecodeBase64(dex_file_base64_content, &length);
135 CHECK(dex_bytes != nullptr);
136 // Note: `dex_file` will be destroyed before `dex_bytes`.
Aart Bik37d6a3b2016-06-21 18:30:10 -0700137 std::unique_ptr<DexFile> dex_file(GetDexFile(dex_bytes.get(), length));
Andreas Gampee6215c02015-08-31 18:54:38 -0700138 f(dex_file.get());
139 FixUpChecksum(const_cast<uint8_t*>(dex_file->Begin()));
140
Aart Bik37d6a3b2016-06-21 18:30:10 -0700141 static constexpr bool kVerifyChecksum = true;
Andreas Gampee6215c02015-08-31 18:54:38 -0700142 std::string error_msg;
143 bool success = DexFileVerifier::Verify(dex_file.get(),
144 dex_file->Begin(),
145 dex_file->Size(),
146 location,
Aart Bik37d6a3b2016-06-21 18:30:10 -0700147 kVerifyChecksum,
Andreas Gampee6215c02015-08-31 18:54:38 -0700148 &error_msg);
149 if (expected_error == nullptr) {
150 EXPECT_TRUE(success) << error_msg;
151 } else {
152 EXPECT_FALSE(success) << "Expected " << expected_error;
153 if (!success) {
154 EXPECT_NE(error_msg.find(expected_error), std::string::npos) << error_msg;
155 }
156 }
157 }
Andreas Gampee6215c02015-08-31 18:54:38 -0700158};
159
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800160static std::unique_ptr<const DexFile> OpenDexFileBase64(const char* base64,
161 const char* location,
162 std::string* error_msg) {
Andreas Gampedf10b322014-06-11 21:46:05 -0700163 // decode base64
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700164 CHECK(base64 != nullptr);
Andreas Gampedf10b322014-06-11 21:46:05 -0700165 size_t length;
Ian Rogers13735952014-10-08 12:43:28 -0700166 std::unique_ptr<uint8_t[]> dex_bytes(DecodeBase64(base64, &length));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700167 CHECK(dex_bytes.get() != nullptr);
Andreas Gampedf10b322014-06-11 21:46:05 -0700168
169 // write to provided file
170 std::unique_ptr<File> file(OS::CreateEmptyFile(location));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700171 CHECK(file.get() != nullptr);
Andreas Gampedf10b322014-06-11 21:46:05 -0700172 if (!file->WriteFully(dex_bytes.get(), length)) {
173 PLOG(FATAL) << "Failed to write base64 as dex file";
174 }
Andreas Gampe4303ba92014-11-06 01:00:46 -0800175 if (file->FlushCloseOrErase() != 0) {
176 PLOG(FATAL) << "Could not flush and close test file.";
177 }
Andreas Gampedf10b322014-06-11 21:46:05 -0700178 file.reset();
179
180 // read dex file
181 ScopedObjectAccess soa(Thread::Current());
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800182 std::vector<std::unique_ptr<const DexFile>> tmp;
Aart Bik37d6a3b2016-06-21 18:30:10 -0700183 bool success = DexFile::Open(location, location, true, error_msg, &tmp);
Andreas Gampe833a4852014-05-21 18:46:59 -0700184 CHECK(success) << error_msg;
185 EXPECT_EQ(1U, tmp.size());
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800186 std::unique_ptr<const DexFile> dex_file = std::move(tmp[0]);
Andreas Gampe833a4852014-05-21 18:46:59 -0700187 EXPECT_EQ(PROT_READ, dex_file->GetPermissions());
188 EXPECT_TRUE(dex_file->IsReadOnly());
189 return dex_file;
Andreas Gampedf10b322014-06-11 21:46:05 -0700190}
191
Roland Levillain621b5ea2016-05-18 11:41:33 +0100192// To generate a base64 encoded Dex file (such as kGoodTestDex, below)
193// from Smali files, use:
194//
195// smali -o classes.dex class1.smali [class2.smali ...]
196// base64 classes.dex >classes.dex.base64
197
Andreas Gampedf10b322014-06-11 21:46:05 -0700198// For reference.
199static const char kGoodTestDex[] =
200 "ZGV4CjAzNQDrVbyVkxX1HljTznNf95AglkUAhQuFtmKkAgAAcAAAAHhWNBIAAAAAAAAAAAQCAAAN"
201 "AAAAcAAAAAYAAACkAAAAAgAAALwAAAABAAAA1AAAAAQAAADcAAAAAQAAAPwAAACIAQAAHAEAAFoB"
202 "AABiAQAAagEAAIEBAACVAQAAqQEAAL0BAADDAQAAzgEAANEBAADVAQAA2gEAAN8BAAABAAAAAgAA"
203 "AAMAAAAEAAAABQAAAAgAAAAIAAAABQAAAAAAAAAJAAAABQAAAFQBAAAEAAEACwAAAAAAAAAAAAAA"
204 "AAAAAAoAAAABAAEADAAAAAIAAAAAAAAAAAAAAAEAAAACAAAAAAAAAAcAAAAAAAAA8wEAAAAAAAAB"
205 "AAEAAQAAAOgBAAAEAAAAcBADAAAADgACAAAAAgAAAO0BAAAIAAAAYgAAABoBBgBuIAIAEAAOAAEA"
206 "AAADAAY8aW5pdD4ABkxUZXN0OwAVTGphdmEvaW8vUHJpbnRTdHJlYW07ABJMamF2YS9sYW5nL09i"
207 "amVjdDsAEkxqYXZhL2xhbmcvU3RyaW5nOwASTGphdmEvbGFuZy9TeXN0ZW07AARUZXN0AAlUZXN0"
208 "LmphdmEAAVYAAlZMAANmb28AA291dAAHcHJpbnRsbgABAAcOAAMABw54AAAAAgAAgYAEnAIBCbQC"
209 "AAAADQAAAAAAAAABAAAAAAAAAAEAAAANAAAAcAAAAAIAAAAGAAAApAAAAAMAAAACAAAAvAAAAAQA"
210 "AAABAAAA1AAAAAUAAAAEAAAA3AAAAAYAAAABAAAA/AAAAAEgAAACAAAAHAEAAAEQAAABAAAAVAEA"
211 "AAIgAAANAAAAWgEAAAMgAAACAAAA6AEAAAAgAAABAAAA8wEAAAAQAAABAAAABAIAAA==";
212
213TEST_F(DexFileVerifierTest, GoodDex) {
214 ScratchFile tmp;
215 std::string error_msg;
216 std::unique_ptr<const DexFile> raw(OpenDexFileBase64(kGoodTestDex, tmp.GetFilename().c_str(),
217 &error_msg));
218 ASSERT_TRUE(raw.get() != nullptr) << error_msg;
219}
220
Andreas Gampedf10b322014-06-11 21:46:05 -0700221TEST_F(DexFileVerifierTest, MethodId) {
Andreas Gampee6215c02015-08-31 18:54:38 -0700222 // Class idx error.
223 VerifyModification(
224 kGoodTestDex,
225 "method_id_class_idx",
226 [](DexFile* dex_file) {
227 DexFile::MethodId* method_id = const_cast<DexFile::MethodId*>(&dex_file->GetMethodId(0));
228 method_id->class_idx_ = 0xFF;
229 },
230 "could not find declaring class for direct method index 0");
231
232 // Proto idx error.
233 VerifyModification(
234 kGoodTestDex,
235 "method_id_proto_idx",
236 [](DexFile* dex_file) {
237 DexFile::MethodId* method_id = const_cast<DexFile::MethodId*>(&dex_file->GetMethodId(0));
238 method_id->proto_idx_ = 0xFF;
239 },
240 "inter_method_id_item proto_idx");
241
242 // Name idx error.
243 VerifyModification(
244 kGoodTestDex,
245 "method_id_name_idx",
246 [](DexFile* dex_file) {
247 DexFile::MethodId* method_id = const_cast<DexFile::MethodId*>(&dex_file->GetMethodId(0));
248 method_id->name_idx_ = 0xFF;
249 },
250 "String index not available for method flags verification");
251}
252
253// Method flags test class generated from the following smali code. The declared-synchronized
254// flags are there to enforce a 3-byte uLEB128 encoding so we don't have to relayout
255// the code, but we need to remove them before doing tests.
256//
257// .class public LMethodFlags;
258// .super Ljava/lang/Object;
259//
260// .method public static constructor <clinit>()V
261// .registers 1
262// return-void
263// .end method
264//
265// .method public constructor <init>()V
266// .registers 1
267// return-void
268// .end method
269//
270// .method private declared-synchronized foo()V
271// .registers 1
272// return-void
273// .end method
274//
275// .method public declared-synchronized bar()V
276// .registers 1
277// return-void
278// .end method
279
280static const char kMethodFlagsTestDex[] =
281 "ZGV4CjAzNQCyOQrJaDBwiIWv5MIuYKXhxlLLsQcx5SwgAgAAcAAAAHhWNBIAAAAAAAAAAJgBAAAH"
282 "AAAAcAAAAAMAAACMAAAAAQAAAJgAAAAAAAAAAAAAAAQAAACkAAAAAQAAAMQAAAA8AQAA5AAAAOQA"
283 "AADuAAAA9gAAAAUBAAAZAQAAHAEAACEBAAACAAAAAwAAAAQAAAAEAAAAAgAAAAAAAAAAAAAAAAAA"
284 "AAAAAAABAAAAAAAAAAUAAAAAAAAABgAAAAAAAAABAAAAAQAAAAAAAAD/////AAAAAHoBAAAAAAAA"
285 "CDxjbGluaXQ+AAY8aW5pdD4ADUxNZXRob2RGbGFnczsAEkxqYXZhL2xhbmcvT2JqZWN0OwABVgAD"
286 "YmFyAANmb28AAAAAAAAAAQAAAAAAAAAAAAAAAQAAAA4AAAABAAEAAAAAAAAAAAABAAAADgAAAAEA"
287 "AQAAAAAAAAAAAAEAAAAOAAAAAQABAAAAAAAAAAAAAQAAAA4AAAADAQCJgASsAgGBgATAAgKCgAjU"
288 "AgKBgAjoAgAACwAAAAAAAAABAAAAAAAAAAEAAAAHAAAAcAAAAAIAAAADAAAAjAAAAAMAAAABAAAA"
289 "mAAAAAUAAAAEAAAApAAAAAYAAAABAAAAxAAAAAIgAAAHAAAA5AAAAAMQAAABAAAAKAEAAAEgAAAE"
290 "AAAALAEAAAAgAAABAAAAegEAAAAQAAABAAAAmAEAAA==";
291
292// Find the method data for the first method with the given name (from class 0). Note: the pointer
293// is to the access flags, so that the caller doesn't have to handle the leb128-encoded method-index
294// delta.
Vladimir Marko59399ab2016-05-03 16:31:52 +0100295static const uint8_t* FindMethodData(const DexFile* dex_file,
296 const char* name,
297 /*out*/ uint32_t* method_idx = nullptr) {
Andreas Gampee6215c02015-08-31 18:54:38 -0700298 const DexFile::ClassDef& class_def = dex_file->GetClassDef(0);
299 const uint8_t* class_data = dex_file->GetClassData(class_def);
300
301 ClassDataItemIterator it(*dex_file, class_data);
302
303 const uint8_t* trailing = class_data;
304 // Need to manually decode the four entries. DataPointer() doesn't work for this, as the first
305 // element has already been loaded into the iterator.
306 DecodeUnsignedLeb128(&trailing);
307 DecodeUnsignedLeb128(&trailing);
308 DecodeUnsignedLeb128(&trailing);
309 DecodeUnsignedLeb128(&trailing);
310
311 // Skip all fields.
312 while (it.HasNextStaticField() || it.HasNextInstanceField()) {
313 trailing = it.DataPointer();
314 it.Next();
Andreas Gampedf10b322014-06-11 21:46:05 -0700315 }
316
Andreas Gampee6215c02015-08-31 18:54:38 -0700317 while (it.HasNextDirectMethod() || it.HasNextVirtualMethod()) {
318 uint32_t method_index = it.GetMemberIndex();
319 uint32_t name_index = dex_file->GetMethodId(method_index).name_idx_;
320 const DexFile::StringId& string_id = dex_file->GetStringId(name_index);
321 const char* str = dex_file->GetStringData(string_id);
322 if (strcmp(name, str) == 0) {
Vladimir Marko59399ab2016-05-03 16:31:52 +0100323 if (method_idx != nullptr) {
324 *method_idx = method_index;
325 }
Andreas Gampee6215c02015-08-31 18:54:38 -0700326 DecodeUnsignedLeb128(&trailing);
327 return trailing;
328 }
329
330 trailing = it.DataPointer();
331 it.Next();
Andreas Gampedf10b322014-06-11 21:46:05 -0700332 }
333
Andreas Gampee6215c02015-08-31 18:54:38 -0700334 return nullptr;
335}
336
337// Set the method flags to the given value.
338static void SetMethodFlags(DexFile* dex_file, const char* method, uint32_t mask) {
339 uint8_t* method_flags_ptr = const_cast<uint8_t*>(FindMethodData(dex_file, method));
340 CHECK(method_flags_ptr != nullptr) << method;
341
342 // Unroll this, as we only have three bytes, anyways.
343 uint8_t base1 = static_cast<uint8_t>(mask & 0x7F);
344 *(method_flags_ptr++) = (base1 | 0x80);
345 mask >>= 7;
346
347 uint8_t base2 = static_cast<uint8_t>(mask & 0x7F);
348 *(method_flags_ptr++) = (base2 | 0x80);
349 mask >>= 7;
350
351 uint8_t base3 = static_cast<uint8_t>(mask & 0x7F);
352 *method_flags_ptr = base3;
353}
354
355static uint32_t GetMethodFlags(DexFile* dex_file, const char* method) {
356 const uint8_t* method_flags_ptr = const_cast<uint8_t*>(FindMethodData(dex_file, method));
357 CHECK(method_flags_ptr != nullptr) << method;
358 return DecodeUnsignedLeb128(&method_flags_ptr);
359}
360
361// Apply the given mask to method flags.
362static void ApplyMaskToMethodFlags(DexFile* dex_file, const char* method, uint32_t mask) {
363 uint32_t value = GetMethodFlags(dex_file, method);
364 value &= mask;
365 SetMethodFlags(dex_file, method, value);
366}
367
368// Apply the given mask to method flags.
369static void OrMaskToMethodFlags(DexFile* dex_file, const char* method, uint32_t mask) {
370 uint32_t value = GetMethodFlags(dex_file, method);
371 value |= mask;
372 SetMethodFlags(dex_file, method, value);
373}
374
375// Set code_off to 0 for the method.
376static void RemoveCode(DexFile* dex_file, const char* method) {
377 const uint8_t* ptr = FindMethodData(dex_file, method);
378 // Next is flags, pass.
379 DecodeUnsignedLeb128(&ptr);
380
381 // Figure out how many bytes the code_off is.
382 const uint8_t* tmp = ptr;
383 DecodeUnsignedLeb128(&tmp);
384 size_t bytes = tmp - ptr;
385
386 uint8_t* mod = const_cast<uint8_t*>(ptr);
387 for (size_t i = 1; i < bytes; ++i) {
388 *(mod++) = 0x80;
Andreas Gampedf10b322014-06-11 21:46:05 -0700389 }
Andreas Gampee6215c02015-08-31 18:54:38 -0700390 *mod = 0x00;
391}
392
393TEST_F(DexFileVerifierTest, MethodAccessFlagsBase) {
394 // Check that it's OK when the wrong declared-synchronized flag is removed from "foo."
395 VerifyModification(
396 kMethodFlagsTestDex,
397 "method_flags_ok",
398 [](DexFile* dex_file) {
399 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
400 ApplyMaskToMethodFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
401 },
402 nullptr);
403}
404
405TEST_F(DexFileVerifierTest, MethodAccessFlagsConstructors) {
406 // Make sure we still accept constructors without their flags.
407 VerifyModification(
408 kMethodFlagsTestDex,
409 "method_flags_missing_constructor_tag_ok",
410 [](DexFile* dex_file) {
411 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
412 ApplyMaskToMethodFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
413
414 ApplyMaskToMethodFlags(dex_file, "<init>", ~kAccConstructor);
415 ApplyMaskToMethodFlags(dex_file, "<clinit>", ~kAccConstructor);
416 },
417 nullptr);
418
419 constexpr const char* kConstructors[] = { "<clinit>", "<init>"};
420 for (size_t i = 0; i < 2; ++i) {
421 // Constructor with code marked native.
422 VerifyModification(
423 kMethodFlagsTestDex,
424 "method_flags_constructor_native",
425 [&](DexFile* dex_file) {
426 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
427 ApplyMaskToMethodFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
428
429 OrMaskToMethodFlags(dex_file, kConstructors[i], kAccNative);
430 },
431 "has code, but is marked native or abstract");
432 // Constructor with code marked abstract.
433 VerifyModification(
434 kMethodFlagsTestDex,
435 "method_flags_constructor_abstract",
436 [&](DexFile* dex_file) {
437 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
438 ApplyMaskToMethodFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
439
440 OrMaskToMethodFlags(dex_file, kConstructors[i], kAccAbstract);
441 },
442 "has code, but is marked native or abstract");
443 // Constructor as-is without code.
444 VerifyModification(
445 kMethodFlagsTestDex,
446 "method_flags_constructor_nocode",
447 [&](DexFile* dex_file) {
448 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
449 ApplyMaskToMethodFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
450
451 RemoveCode(dex_file, kConstructors[i]);
452 },
453 "has no code, but is not marked native or abstract");
454 // Constructor without code marked native.
455 VerifyModification(
456 kMethodFlagsTestDex,
457 "method_flags_constructor_native_nocode",
458 [&](DexFile* dex_file) {
Alex Light0ed05212016-05-06 17:36:36 -0700459 MakeDexVersion37(dex_file);
Andreas Gampee6215c02015-08-31 18:54:38 -0700460 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
461 ApplyMaskToMethodFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
462
463 OrMaskToMethodFlags(dex_file, kConstructors[i], kAccNative);
464 RemoveCode(dex_file, kConstructors[i]);
465 },
466 "must not be abstract or native");
467 // Constructor without code marked abstract.
468 VerifyModification(
469 kMethodFlagsTestDex,
470 "method_flags_constructor_abstract_nocode",
471 [&](DexFile* dex_file) {
Alex Light0ed05212016-05-06 17:36:36 -0700472 MakeDexVersion37(dex_file);
Andreas Gampee6215c02015-08-31 18:54:38 -0700473 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
474 ApplyMaskToMethodFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
475
476 OrMaskToMethodFlags(dex_file, kConstructors[i], kAccAbstract);
477 RemoveCode(dex_file, kConstructors[i]);
478 },
479 "must not be abstract or native");
480 }
481 // <init> may only have (modulo ignored):
482 // kAccPrivate | kAccProtected | kAccPublic | kAccStrict | kAccVarargs | kAccSynthetic
483 static constexpr uint32_t kInitAllowed[] = {
484 0,
485 kAccPrivate,
486 kAccProtected,
487 kAccPublic,
488 kAccStrict,
489 kAccVarargs,
490 kAccSynthetic
491 };
492 for (size_t i = 0; i < arraysize(kInitAllowed); ++i) {
493 VerifyModification(
494 kMethodFlagsTestDex,
495 "init_allowed_flags",
496 [&](DexFile* dex_file) {
497 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
498 ApplyMaskToMethodFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
499
500 ApplyMaskToMethodFlags(dex_file, "<init>", ~kAccPublic);
501 OrMaskToMethodFlags(dex_file, "<init>", kInitAllowed[i]);
502 },
503 nullptr);
504 }
505 // Only one of public-private-protected.
506 for (size_t i = 1; i < 8; ++i) {
507 if (POPCOUNT(i) < 2) {
508 continue;
509 }
510 // Technically the flags match, but just be defensive here.
511 uint32_t mask = ((i & 1) != 0 ? kAccPrivate : 0) |
512 ((i & 2) != 0 ? kAccProtected : 0) |
513 ((i & 4) != 0 ? kAccPublic : 0);
514 VerifyModification(
515 kMethodFlagsTestDex,
516 "init_one_of_ppp",
517 [&](DexFile* dex_file) {
518 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
519 ApplyMaskToMethodFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
520
521 ApplyMaskToMethodFlags(dex_file, "<init>", ~kAccPublic);
522 OrMaskToMethodFlags(dex_file, "<init>", mask);
523 },
524 "Method may have only one of public/protected/private");
525 }
526 // <init> doesn't allow
527 // kAccStatic | kAccFinal | kAccSynchronized | kAccBridge
528 // Need to handle static separately as it has its own error message.
529 VerifyModification(
530 kMethodFlagsTestDex,
531 "init_not_allowed_flags",
532 [&](DexFile* dex_file) {
Alex Light0ed05212016-05-06 17:36:36 -0700533 MakeDexVersion37(dex_file);
Andreas Gampee6215c02015-08-31 18:54:38 -0700534 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
535 ApplyMaskToMethodFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
536
537 ApplyMaskToMethodFlags(dex_file, "<init>", ~kAccPublic);
538 OrMaskToMethodFlags(dex_file, "<init>", kAccStatic);
539 },
Andreas Gampec9f0ba12016-02-09 09:21:04 -0800540 "Constructor 1(LMethodFlags;.<init>) is not flagged correctly wrt/ static");
Andreas Gampee6215c02015-08-31 18:54:38 -0700541 static constexpr uint32_t kInitNotAllowed[] = {
542 kAccFinal,
543 kAccSynchronized,
544 kAccBridge
545 };
546 for (size_t i = 0; i < arraysize(kInitNotAllowed); ++i) {
547 VerifyModification(
548 kMethodFlagsTestDex,
549 "init_not_allowed_flags",
550 [&](DexFile* dex_file) {
551 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
552 ApplyMaskToMethodFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
553
554 ApplyMaskToMethodFlags(dex_file, "<init>", ~kAccPublic);
555 OrMaskToMethodFlags(dex_file, "<init>", kInitNotAllowed[i]);
556 },
Andreas Gampec9f0ba12016-02-09 09:21:04 -0800557 "Constructor 1(LMethodFlags;.<init>) flagged inappropriately");
Andreas Gampee6215c02015-08-31 18:54:38 -0700558 }
559}
560
561TEST_F(DexFileVerifierTest, MethodAccessFlagsMethods) {
562 constexpr const char* kMethods[] = { "foo", "bar"};
563 for (size_t i = 0; i < arraysize(kMethods); ++i) {
564 // Make sure we reject non-constructors marked as constructors.
565 VerifyModification(
566 kMethodFlagsTestDex,
567 "method_flags_non_constructor",
568 [&](DexFile* dex_file) {
569 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
570 ApplyMaskToMethodFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
571
572 OrMaskToMethodFlags(dex_file, kMethods[i], kAccConstructor);
573 },
574 "is marked constructor, but doesn't match name");
575
576 VerifyModification(
577 kMethodFlagsTestDex,
578 "method_flags_native_with_code",
579 [&](DexFile* dex_file) {
580 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
581 ApplyMaskToMethodFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
582
583 OrMaskToMethodFlags(dex_file, kMethods[i], kAccNative);
584 },
585 "has code, but is marked native or abstract");
586
587 VerifyModification(
588 kMethodFlagsTestDex,
589 "method_flags_abstract_with_code",
590 [&](DexFile* dex_file) {
591 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
592 ApplyMaskToMethodFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
593
594 OrMaskToMethodFlags(dex_file, kMethods[i], kAccAbstract);
595 },
596 "has code, but is marked native or abstract");
597
598 VerifyModification(
599 kMethodFlagsTestDex,
600 "method_flags_non_abstract_native_no_code",
601 [&](DexFile* dex_file) {
602 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
603 ApplyMaskToMethodFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
604
605 RemoveCode(dex_file, kMethods[i]);
606 },
607 "has no code, but is not marked native or abstract");
608
609 // Abstract methods may not have the following flags.
610 constexpr uint32_t kAbstractDisallowed[] = {
611 kAccPrivate,
612 kAccStatic,
613 kAccFinal,
614 kAccNative,
615 kAccStrict,
616 kAccSynchronized,
617 };
618 for (size_t j = 0; j < arraysize(kAbstractDisallowed); ++j) {
619 VerifyModification(
620 kMethodFlagsTestDex,
621 "method_flags_abstract_and_disallowed_no_code",
622 [&](DexFile* dex_file) {
623 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
624 ApplyMaskToMethodFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
625
626 RemoveCode(dex_file, kMethods[i]);
627
628 // Can't check private and static with foo, as it's in the virtual list and gives a
629 // different error.
630 if (((GetMethodFlags(dex_file, kMethods[i]) & kAccPublic) != 0) &&
631 ((kAbstractDisallowed[j] & (kAccPrivate | kAccStatic)) != 0)) {
632 // Use another breaking flag.
633 OrMaskToMethodFlags(dex_file, kMethods[i], kAccAbstract | kAccFinal);
634 } else {
635 OrMaskToMethodFlags(dex_file, kMethods[i], kAccAbstract | kAbstractDisallowed[j]);
636 }
637 },
638 "has disallowed access flags");
639 }
640
641 // Only one of public-private-protected.
642 for (size_t j = 1; j < 8; ++j) {
643 if (POPCOUNT(j) < 2) {
644 continue;
645 }
646 // Technically the flags match, but just be defensive here.
647 uint32_t mask = ((j & 1) != 0 ? kAccPrivate : 0) |
648 ((j & 2) != 0 ? kAccProtected : 0) |
649 ((j & 4) != 0 ? kAccPublic : 0);
650 VerifyModification(
651 kMethodFlagsTestDex,
652 "method_flags_one_of_ppp",
653 [&](DexFile* dex_file) {
654 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
655 ApplyMaskToMethodFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
656
657 ApplyMaskToMethodFlags(dex_file, kMethods[i], ~kAccPublic);
658 OrMaskToMethodFlags(dex_file, kMethods[i], mask);
659 },
660 "Method may have only one of public/protected/private");
661 }
662 }
663}
664
665TEST_F(DexFileVerifierTest, MethodAccessFlagsIgnoredOK) {
666 constexpr const char* kMethods[] = { "<clinit>", "<init>", "foo", "bar"};
667 for (size_t i = 0; i < arraysize(kMethods); ++i) {
668 // All interesting method flags, other flags are to be ignored.
669 constexpr uint32_t kAllMethodFlags =
670 kAccPublic |
671 kAccPrivate |
672 kAccProtected |
673 kAccStatic |
674 kAccFinal |
675 kAccSynchronized |
676 kAccBridge |
677 kAccVarargs |
678 kAccNative |
679 kAccAbstract |
680 kAccStrict |
681 kAccSynthetic;
682 constexpr uint32_t kIgnoredMask = ~kAllMethodFlags & 0xFFFF;
683 VerifyModification(
684 kMethodFlagsTestDex,
685 "method_flags_ignored",
686 [&](DexFile* dex_file) {
687 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
688 ApplyMaskToMethodFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
689
690 OrMaskToMethodFlags(dex_file, kMethods[i], kIgnoredMask);
691 },
692 nullptr);
693 }
694}
695
Vladimir Marko59399ab2016-05-03 16:31:52 +0100696TEST_F(DexFileVerifierTest, B28552165) {
697 // Regression test for bad error string retrieval in different situations.
698 // Using invalid access flags to trigger the error.
699 VerifyModification(
700 kMethodFlagsTestDex,
701 "b28552165",
702 [](DexFile* dex_file) {
703 OrMaskToMethodFlags(dex_file, "foo", kAccPublic | kAccProtected);
704 uint32_t method_idx;
705 FindMethodData(dex_file, "foo", &method_idx);
706 auto* method_id = const_cast<DexFile::MethodId*>(&dex_file->GetMethodId(method_idx));
707 method_id->name_idx_ = dex_file->NumStringIds();
708 },
709 "Method may have only one of public/protected/private, LMethodFlags;.(error)");
710}
711
Andreas Gampee6215c02015-08-31 18:54:38 -0700712// Set of dex files for interface method tests. As it's not as easy to mutate method names, it's
713// just easier to break up bad cases.
714
Andreas Gampee6215c02015-08-31 18:54:38 -0700715// Standard interface. Use declared-synchronized again for 3B encoding.
716//
717// .class public interface LInterfaceMethodFlags;
718// .super Ljava/lang/Object;
719//
720// .method public static constructor <clinit>()V
721// .registers 1
722// return-void
723// .end method
724//
725// .method public abstract declared-synchronized foo()V
726// .end method
727static const char kMethodFlagsInterface[] =
728 "ZGV4CjAzNQCOM0odZ5bws1d9GSmumXaK5iE/7XxFpOm8AQAAcAAAAHhWNBIAAAAAAAAAADQBAAAF"
729 "AAAAcAAAAAMAAACEAAAAAQAAAJAAAAAAAAAAAAAAAAIAAACcAAAAAQAAAKwAAADwAAAAzAAAAMwA"
730 "AADWAAAA7gAAAAIBAAAFAQAAAQAAAAIAAAADAAAAAwAAAAIAAAAAAAAAAAAAAAAAAAAAAAAABAAA"
731 "AAAAAAABAgAAAQAAAAAAAAD/////AAAAACIBAAAAAAAACDxjbGluaXQ+ABZMSW50ZXJmYWNlTWV0"
732 "aG9kRmxhZ3M7ABJMamF2YS9sYW5nL09iamVjdDsAAVYAA2ZvbwAAAAAAAAABAAAAAAAAAAAAAAAB"
733 "AAAADgAAAAEBAImABJACAYGICAAAAAALAAAAAAAAAAEAAAAAAAAAAQAAAAUAAABwAAAAAgAAAAMA"
734 "AACEAAAAAwAAAAEAAACQAAAABQAAAAIAAACcAAAABgAAAAEAAACsAAAAAiAAAAUAAADMAAAAAxAA"
735 "AAEAAAAMAQAAASAAAAEAAAAQAQAAACAAAAEAAAAiAQAAABAAAAEAAAA0AQAA";
736
737// To simplify generation of interesting "sub-states" of src_value, allow a "simple" mask to apply
738// to a src_value, such that mask bit 0 applies to the lowest set bit in src_value, and so on.
739static uint32_t ApplyMaskShifted(uint32_t src_value, uint32_t mask) {
740 uint32_t result = 0;
741 uint32_t mask_index = 0;
742 while (src_value != 0) {
743 uint32_t index = CTZ(src_value);
744 if (((src_value & (1 << index)) != 0) &&
745 ((mask & (1 << mask_index)) != 0)) {
746 result |= (1 << index);
747 }
748 src_value &= ~(1 << index);
749 mask_index++;
750 }
751 return result;
752}
753
754TEST_F(DexFileVerifierTest, MethodAccessFlagsInterfaces) {
Andreas Gampee6215c02015-08-31 18:54:38 -0700755 VerifyModification(
756 kMethodFlagsInterface,
757 "method_flags_interface_ok",
758 [](DexFile* dex_file) {
759 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
760 },
761 nullptr);
Andreas Gampe76ed99d2016-03-28 18:31:29 -0700762 VerifyModification(
763 kMethodFlagsInterface,
764 "method_flags_interface_ok37",
765 [](DexFile* dex_file) {
766 MakeDexVersion37(dex_file);
767 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
768 },
769 nullptr);
Andreas Gampee6215c02015-08-31 18:54:38 -0700770
771 VerifyModification(
772 kMethodFlagsInterface,
773 "method_flags_interface_non_public",
774 [](DexFile* dex_file) {
775 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
776
777 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccPublic);
778 },
Andreas Gampe76ed99d2016-03-28 18:31:29 -0700779 nullptr); // Should be allowed in older dex versions for backwards compatibility.
780 VerifyModification(
781 kMethodFlagsInterface,
782 "method_flags_interface_non_public",
783 [](DexFile* dex_file) {
784 MakeDexVersion37(dex_file);
785 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
786
787 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccPublic);
788 },
Alex Lightd7c10c22016-03-31 10:03:07 -0700789 "Interface virtual method 1(LInterfaceMethodFlags;.foo) is not public");
Andreas Gampe76ed99d2016-03-28 18:31:29 -0700790
Andreas Gampee6215c02015-08-31 18:54:38 -0700791 VerifyModification(
792 kMethodFlagsInterface,
793 "method_flags_interface_non_abstract",
794 [](DexFile* dex_file) {
795 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
796
797 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccAbstract);
798 },
Andreas Gampec9f0ba12016-02-09 09:21:04 -0800799 "Method 1(LInterfaceMethodFlags;.foo) has no code, but is not marked native or abstract");
Andreas Gampee6215c02015-08-31 18:54:38 -0700800
801 VerifyModification(
802 kMethodFlagsInterface,
803 "method_flags_interface_static",
804 [](DexFile* dex_file) {
805 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
806
807 OrMaskToMethodFlags(dex_file, "foo", kAccStatic);
808 },
Andreas Gampec9f0ba12016-02-09 09:21:04 -0800809 "Direct/virtual method 1(LInterfaceMethodFlags;.foo) not in expected list 0");
Andreas Gampee6215c02015-08-31 18:54:38 -0700810 VerifyModification(
811 kMethodFlagsInterface,
812 "method_flags_interface_private",
813 [](DexFile* dex_file) {
814 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
815
816 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccPublic);
817 OrMaskToMethodFlags(dex_file, "foo", kAccPrivate);
818 },
Andreas Gampec9f0ba12016-02-09 09:21:04 -0800819 "Direct/virtual method 1(LInterfaceMethodFlags;.foo) not in expected list 0");
Andreas Gampee6215c02015-08-31 18:54:38 -0700820
821 VerifyModification(
822 kMethodFlagsInterface,
823 "method_flags_interface_non_public",
824 [](DexFile* dex_file) {
825 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
826
827 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccPublic);
828 },
Andreas Gampe76ed99d2016-03-28 18:31:29 -0700829 nullptr); // Should be allowed in older dex versions for backwards compatibility.
830 VerifyModification(
831 kMethodFlagsInterface,
832 "method_flags_interface_non_public",
833 [](DexFile* dex_file) {
834 MakeDexVersion37(dex_file);
835 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
836
837 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccPublic);
838 },
Alex Lightd7c10c22016-03-31 10:03:07 -0700839 "Interface virtual method 1(LInterfaceMethodFlags;.foo) is not public");
Andreas Gampe76ed99d2016-03-28 18:31:29 -0700840
Andreas Gampee6215c02015-08-31 18:54:38 -0700841 VerifyModification(
842 kMethodFlagsInterface,
843 "method_flags_interface_protected",
844 [](DexFile* dex_file) {
845 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
846
847 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccPublic);
848 OrMaskToMethodFlags(dex_file, "foo", kAccProtected);
849 },
Andreas Gampe76ed99d2016-03-28 18:31:29 -0700850 nullptr); // Should be allowed in older dex versions for backwards compatibility.
851 VerifyModification(
852 kMethodFlagsInterface,
853 "method_flags_interface_protected",
854 [](DexFile* dex_file) {
855 MakeDexVersion37(dex_file);
856 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
857
858 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccPublic);
859 OrMaskToMethodFlags(dex_file, "foo", kAccProtected);
860 },
Alex Lightd7c10c22016-03-31 10:03:07 -0700861 "Interface virtual method 1(LInterfaceMethodFlags;.foo) is not public");
Andreas Gampee6215c02015-08-31 18:54:38 -0700862
863 constexpr uint32_t kAllMethodFlags =
864 kAccPublic |
865 kAccPrivate |
866 kAccProtected |
867 kAccStatic |
868 kAccFinal |
869 kAccSynchronized |
870 kAccBridge |
871 kAccVarargs |
872 kAccNative |
873 kAccAbstract |
874 kAccStrict |
875 kAccSynthetic;
876 constexpr uint32_t kInterfaceMethodFlags =
877 kAccPublic | kAccAbstract | kAccVarargs | kAccBridge | kAccSynthetic;
878 constexpr uint32_t kInterfaceDisallowed = kAllMethodFlags &
879 ~kInterfaceMethodFlags &
880 // Already tested, needed to be separate.
881 ~kAccStatic &
882 ~kAccPrivate &
883 ~kAccProtected;
884 static_assert(kInterfaceDisallowed != 0, "There should be disallowed flags.");
885
886 uint32_t bits = POPCOUNT(kInterfaceDisallowed);
887 for (uint32_t i = 1; i < (1u << bits); ++i) {
888 VerifyModification(
889 kMethodFlagsInterface,
890 "method_flags_interface_non_abstract",
891 [&](DexFile* dex_file) {
892 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
893
894 uint32_t mask = ApplyMaskShifted(kInterfaceDisallowed, i);
895 if ((mask & kAccProtected) != 0) {
896 mask &= ~kAccProtected;
897 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccPublic);
898 }
899 OrMaskToMethodFlags(dex_file, "foo", mask);
900 },
Andreas Gampec9f0ba12016-02-09 09:21:04 -0800901 "Abstract method 1(LInterfaceMethodFlags;.foo) has disallowed access flags");
Andreas Gampee6215c02015-08-31 18:54:38 -0700902 }
903}
904
905///////////////////////////////////////////////////////////////////
906
907// Field flags.
908
909// Find the method data for the first method with the given name (from class 0). Note: the pointer
910// is to the access flags, so that the caller doesn't have to handle the leb128-encoded method-index
911// delta.
912static const uint8_t* FindFieldData(const DexFile* dex_file, const char* name) {
913 const DexFile::ClassDef& class_def = dex_file->GetClassDef(0);
914 const uint8_t* class_data = dex_file->GetClassData(class_def);
915
916 ClassDataItemIterator it(*dex_file, class_data);
917
918 const uint8_t* trailing = class_data;
919 // Need to manually decode the four entries. DataPointer() doesn't work for this, as the first
920 // element has already been loaded into the iterator.
921 DecodeUnsignedLeb128(&trailing);
922 DecodeUnsignedLeb128(&trailing);
923 DecodeUnsignedLeb128(&trailing);
924 DecodeUnsignedLeb128(&trailing);
925
926 while (it.HasNextStaticField() || it.HasNextInstanceField()) {
927 uint32_t field_index = it.GetMemberIndex();
928 uint32_t name_index = dex_file->GetFieldId(field_index).name_idx_;
929 const DexFile::StringId& string_id = dex_file->GetStringId(name_index);
930 const char* str = dex_file->GetStringData(string_id);
931 if (strcmp(name, str) == 0) {
932 DecodeUnsignedLeb128(&trailing);
933 return trailing;
934 }
935
936 trailing = it.DataPointer();
937 it.Next();
938 }
939
940 return nullptr;
941}
942
943// Set the method flags to the given value.
944static void SetFieldFlags(DexFile* dex_file, const char* field, uint32_t mask) {
945 uint8_t* field_flags_ptr = const_cast<uint8_t*>(FindFieldData(dex_file, field));
946 CHECK(field_flags_ptr != nullptr) << field;
947
948 // Unroll this, as we only have three bytes, anyways.
949 uint8_t base1 = static_cast<uint8_t>(mask & 0x7F);
950 *(field_flags_ptr++) = (base1 | 0x80);
951 mask >>= 7;
952
953 uint8_t base2 = static_cast<uint8_t>(mask & 0x7F);
954 *(field_flags_ptr++) = (base2 | 0x80);
955 mask >>= 7;
956
957 uint8_t base3 = static_cast<uint8_t>(mask & 0x7F);
958 *field_flags_ptr = base3;
959}
960
961static uint32_t GetFieldFlags(DexFile* dex_file, const char* field) {
962 const uint8_t* field_flags_ptr = const_cast<uint8_t*>(FindFieldData(dex_file, field));
963 CHECK(field_flags_ptr != nullptr) << field;
964 return DecodeUnsignedLeb128(&field_flags_ptr);
965}
966
967// Apply the given mask to method flags.
968static void ApplyMaskToFieldFlags(DexFile* dex_file, const char* field, uint32_t mask) {
969 uint32_t value = GetFieldFlags(dex_file, field);
970 value &= mask;
971 SetFieldFlags(dex_file, field, value);
972}
973
974// Apply the given mask to method flags.
975static void OrMaskToFieldFlags(DexFile* dex_file, const char* field, uint32_t mask) {
976 uint32_t value = GetFieldFlags(dex_file, field);
977 value |= mask;
978 SetFieldFlags(dex_file, field, value);
979}
980
981// Standard class. Use declared-synchronized again for 3B encoding.
982//
983// .class public LFieldFlags;
984// .super Ljava/lang/Object;
985//
986// .field declared-synchronized public foo:I
987//
988// .field declared-synchronized public static bar:I
989
990static const char kFieldFlagsTestDex[] =
991 "ZGV4CjAzNQBtLw7hydbfv4TdXidZyzAB70W7w3vnYJRwAQAAcAAAAHhWNBIAAAAAAAAAAAABAAAF"
992 "AAAAcAAAAAMAAACEAAAAAAAAAAAAAAACAAAAkAAAAAAAAAAAAAAAAQAAAKAAAACwAAAAwAAAAMAA"
993 "AADDAAAA0QAAAOUAAADqAAAAAAAAAAEAAAACAAAAAQAAAAMAAAABAAAABAAAAAEAAAABAAAAAgAA"
994 "AAAAAAD/////AAAAAPQAAAAAAAAAAUkADExGaWVsZEZsYWdzOwASTGphdmEvbGFuZy9PYmplY3Q7"
995 "AANiYXIAA2ZvbwAAAAAAAAEBAAAAiYAIAYGACAkAAAAAAAAAAQAAAAAAAAABAAAABQAAAHAAAAAC"
996 "AAAAAwAAAIQAAAAEAAAAAgAAAJAAAAAGAAAAAQAAAKAAAAACIAAABQAAAMAAAAADEAAAAQAAAPAA"
997 "AAAAIAAAAQAAAPQAAAAAEAAAAQAAAAABAAA=";
998
999TEST_F(DexFileVerifierTest, FieldAccessFlagsBase) {
1000 // Check that it's OK when the wrong declared-synchronized flag is removed from "foo."
1001 VerifyModification(
1002 kFieldFlagsTestDex,
1003 "field_flags_ok",
1004 [](DexFile* dex_file) {
1005 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
1006 ApplyMaskToFieldFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
1007 },
1008 nullptr);
1009}
1010
1011TEST_F(DexFileVerifierTest, FieldAccessFlagsWrongList) {
1012 // Mark the field so that it should appear in the opposite list (instance vs static).
1013 VerifyModification(
1014 kFieldFlagsTestDex,
1015 "field_flags_wrong_list",
1016 [](DexFile* dex_file) {
1017 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
1018 ApplyMaskToFieldFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
1019
1020 OrMaskToFieldFlags(dex_file, "foo", kAccStatic);
1021 },
1022 "Static/instance field not in expected list");
1023 VerifyModification(
1024 kFieldFlagsTestDex,
1025 "field_flags_wrong_list",
1026 [](DexFile* dex_file) {
1027 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
1028 ApplyMaskToFieldFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
1029
1030 ApplyMaskToFieldFlags(dex_file, "bar", ~kAccStatic);
1031 },
1032 "Static/instance field not in expected list");
1033}
1034
1035TEST_F(DexFileVerifierTest, FieldAccessFlagsPPP) {
1036 static const char* kFields[] = { "foo", "bar" };
1037 for (size_t i = 0; i < arraysize(kFields); ++i) {
1038 // Should be OK to remove public.
1039 VerifyModification(
1040 kFieldFlagsTestDex,
1041 "field_flags_non_public",
1042 [&](DexFile* dex_file) {
1043 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
1044 ApplyMaskToFieldFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
1045
1046 ApplyMaskToFieldFlags(dex_file, kFields[i], ~kAccPublic);
1047 },
1048 nullptr);
1049 constexpr uint32_t kAccFlags = kAccPublic | kAccPrivate | kAccProtected;
1050 uint32_t bits = POPCOUNT(kAccFlags);
1051 for (uint32_t j = 1; j < (1u << bits); ++j) {
1052 if (POPCOUNT(j) < 2) {
1053 continue;
1054 }
1055 VerifyModification(
1056 kFieldFlagsTestDex,
1057 "field_flags_ppp",
1058 [&](DexFile* dex_file) {
1059 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
1060 ApplyMaskToFieldFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
1061
1062 ApplyMaskToFieldFlags(dex_file, kFields[i], ~kAccPublic);
1063 uint32_t mask = ApplyMaskShifted(kAccFlags, j);
1064 OrMaskToFieldFlags(dex_file, kFields[i], mask);
1065 },
1066 "Field may have only one of public/protected/private");
1067 }
1068 }
1069}
1070
1071TEST_F(DexFileVerifierTest, FieldAccessFlagsIgnoredOK) {
1072 constexpr const char* kFields[] = { "foo", "bar"};
1073 for (size_t i = 0; i < arraysize(kFields); ++i) {
1074 // All interesting method flags, other flags are to be ignored.
1075 constexpr uint32_t kAllFieldFlags =
1076 kAccPublic |
1077 kAccPrivate |
1078 kAccProtected |
1079 kAccStatic |
1080 kAccFinal |
1081 kAccVolatile |
1082 kAccTransient |
1083 kAccSynthetic |
1084 kAccEnum;
1085 constexpr uint32_t kIgnoredMask = ~kAllFieldFlags & 0xFFFF;
1086 VerifyModification(
1087 kFieldFlagsTestDex,
1088 "field_flags_ignored",
1089 [&](DexFile* dex_file) {
1090 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
1091 ApplyMaskToFieldFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
1092
1093 OrMaskToFieldFlags(dex_file, kFields[i], kIgnoredMask);
1094 },
1095 nullptr);
1096 }
1097}
1098
1099TEST_F(DexFileVerifierTest, FieldAccessFlagsVolatileFinal) {
1100 constexpr const char* kFields[] = { "foo", "bar"};
1101 for (size_t i = 0; i < arraysize(kFields); ++i) {
1102 VerifyModification(
1103 kFieldFlagsTestDex,
1104 "field_flags_final_and_volatile",
1105 [&](DexFile* dex_file) {
1106 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
1107 ApplyMaskToFieldFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
1108
1109 OrMaskToFieldFlags(dex_file, kFields[i], kAccVolatile | kAccFinal);
1110 },
1111 "Fields may not be volatile and final");
1112 }
1113}
1114
1115// Standard interface. Needs to be separate from class as interfaces do not allow instance fields.
1116// Use declared-synchronized again for 3B encoding.
1117//
1118// .class public interface LInterfaceFieldFlags;
1119// .super Ljava/lang/Object;
1120//
1121// .field declared-synchronized public static final foo:I
1122
1123static const char kFieldFlagsInterfaceTestDex[] =
1124 "ZGV4CjAzNQCVMHfEimR1zZPk6hl6O9GPAYqkl3u0umFkAQAAcAAAAHhWNBIAAAAAAAAAAPQAAAAE"
1125 "AAAAcAAAAAMAAACAAAAAAAAAAAAAAAABAAAAjAAAAAAAAAAAAAAAAQAAAJQAAACwAAAAtAAAALQA"
1126 "AAC3AAAAzgAAAOIAAAAAAAAAAQAAAAIAAAABAAAAAwAAAAEAAAABAgAAAgAAAAAAAAD/////AAAA"
1127 "AOwAAAAAAAAAAUkAFUxJbnRlcmZhY2VGaWVsZEZsYWdzOwASTGphdmEvbGFuZy9PYmplY3Q7AANm"
1128 "b28AAAAAAAABAAAAAJmACAkAAAAAAAAAAQAAAAAAAAABAAAABAAAAHAAAAACAAAAAwAAAIAAAAAE"
1129 "AAAAAQAAAIwAAAAGAAAAAQAAAJQAAAACIAAABAAAALQAAAADEAAAAQAAAOgAAAAAIAAAAQAAAOwA"
1130 "AAAAEAAAAQAAAPQAAAA=";
1131
1132TEST_F(DexFileVerifierTest, FieldAccessFlagsInterface) {
1133 VerifyModification(
1134 kFieldFlagsInterfaceTestDex,
1135 "field_flags_interface",
1136 [](DexFile* dex_file) {
1137 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
1138 },
1139 nullptr);
Andreas Gampe76ed99d2016-03-28 18:31:29 -07001140 VerifyModification(
1141 kFieldFlagsInterfaceTestDex,
1142 "field_flags_interface",
1143 [](DexFile* dex_file) {
1144 MakeDexVersion37(dex_file);
1145 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
1146 },
1147 nullptr);
Andreas Gampee6215c02015-08-31 18:54:38 -07001148
1149 VerifyModification(
1150 kFieldFlagsInterfaceTestDex,
1151 "field_flags_interface_non_public",
1152 [](DexFile* dex_file) {
1153 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
1154
1155 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccPublic);
1156 },
Andreas Gampe76ed99d2016-03-28 18:31:29 -07001157 nullptr); // Should be allowed in older dex versions for backwards compatibility.
1158 VerifyModification(
1159 kFieldFlagsInterfaceTestDex,
1160 "field_flags_interface_non_public",
1161 [](DexFile* dex_file) {
1162 MakeDexVersion37(dex_file);
1163 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
1164
1165 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccPublic);
1166 },
Andreas Gampee6215c02015-08-31 18:54:38 -07001167 "Interface field is not public final static");
Andreas Gampe76ed99d2016-03-28 18:31:29 -07001168
Andreas Gampee6215c02015-08-31 18:54:38 -07001169 VerifyModification(
1170 kFieldFlagsInterfaceTestDex,
1171 "field_flags_interface_non_final",
1172 [](DexFile* dex_file) {
1173 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
1174
1175 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccFinal);
1176 },
Andreas Gampe76ed99d2016-03-28 18:31:29 -07001177 nullptr); // Should be allowed in older dex versions for backwards compatibility.
1178 VerifyModification(
1179 kFieldFlagsInterfaceTestDex,
1180 "field_flags_interface_non_final",
1181 [](DexFile* dex_file) {
1182 MakeDexVersion37(dex_file);
1183 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
1184
1185 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccFinal);
1186 },
Andreas Gampee6215c02015-08-31 18:54:38 -07001187 "Interface field is not public final static");
Andreas Gampe76ed99d2016-03-28 18:31:29 -07001188
Andreas Gampee6215c02015-08-31 18:54:38 -07001189 VerifyModification(
1190 kFieldFlagsInterfaceTestDex,
1191 "field_flags_interface_protected",
1192 [](DexFile* dex_file) {
1193 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
1194
1195 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccPublic);
1196 OrMaskToFieldFlags(dex_file, "foo", kAccProtected);
1197 },
Andreas Gampe76ed99d2016-03-28 18:31:29 -07001198 nullptr); // Should be allowed in older dex versions for backwards compatibility.
1199 VerifyModification(
1200 kFieldFlagsInterfaceTestDex,
1201 "field_flags_interface_protected",
1202 [](DexFile* dex_file) {
1203 MakeDexVersion37(dex_file);
1204 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
1205
1206 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccPublic);
1207 OrMaskToFieldFlags(dex_file, "foo", kAccProtected);
1208 },
Andreas Gampee6215c02015-08-31 18:54:38 -07001209 "Interface field is not public final static");
Andreas Gampe76ed99d2016-03-28 18:31:29 -07001210
Andreas Gampee6215c02015-08-31 18:54:38 -07001211 VerifyModification(
1212 kFieldFlagsInterfaceTestDex,
1213 "field_flags_interface_private",
1214 [](DexFile* dex_file) {
1215 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
1216
1217 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccPublic);
1218 OrMaskToFieldFlags(dex_file, "foo", kAccPrivate);
1219 },
Andreas Gampe76ed99d2016-03-28 18:31:29 -07001220 nullptr); // Should be allowed in older dex versions for backwards compatibility.
1221 VerifyModification(
1222 kFieldFlagsInterfaceTestDex,
1223 "field_flags_interface_private",
1224 [](DexFile* dex_file) {
1225 MakeDexVersion37(dex_file);
1226 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
1227
1228 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccPublic);
1229 OrMaskToFieldFlags(dex_file, "foo", kAccPrivate);
1230 },
Andreas Gampee6215c02015-08-31 18:54:38 -07001231 "Interface field is not public final static");
1232
1233 VerifyModification(
1234 kFieldFlagsInterfaceTestDex,
1235 "field_flags_interface_synthetic",
1236 [](DexFile* dex_file) {
1237 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
1238
1239 OrMaskToFieldFlags(dex_file, "foo", kAccSynthetic);
1240 },
1241 nullptr);
1242
1243 constexpr uint32_t kAllFieldFlags =
1244 kAccPublic |
1245 kAccPrivate |
1246 kAccProtected |
1247 kAccStatic |
1248 kAccFinal |
1249 kAccVolatile |
1250 kAccTransient |
1251 kAccSynthetic |
1252 kAccEnum;
1253 constexpr uint32_t kInterfaceFieldFlags = kAccPublic | kAccStatic | kAccFinal | kAccSynthetic;
1254 constexpr uint32_t kInterfaceDisallowed = kAllFieldFlags &
1255 ~kInterfaceFieldFlags &
1256 ~kAccProtected &
1257 ~kAccPrivate;
1258 static_assert(kInterfaceDisallowed != 0, "There should be disallowed flags.");
1259
1260 uint32_t bits = POPCOUNT(kInterfaceDisallowed);
1261 for (uint32_t i = 1; i < (1u << bits); ++i) {
1262 VerifyModification(
1263 kFieldFlagsInterfaceTestDex,
1264 "field_flags_interface_disallowed",
1265 [&](DexFile* dex_file) {
1266 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
1267
1268 uint32_t mask = ApplyMaskShifted(kInterfaceDisallowed, i);
1269 if ((mask & kAccProtected) != 0) {
1270 mask &= ~kAccProtected;
1271 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccPublic);
1272 }
1273 OrMaskToFieldFlags(dex_file, "foo", mask);
1274 },
Andreas Gampe76ed99d2016-03-28 18:31:29 -07001275 nullptr); // Should be allowed in older dex versions for backwards compatibility.
1276 VerifyModification(
1277 kFieldFlagsInterfaceTestDex,
1278 "field_flags_interface_disallowed",
1279 [&](DexFile* dex_file) {
1280 MakeDexVersion37(dex_file);
1281 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
1282
1283 uint32_t mask = ApplyMaskShifted(kInterfaceDisallowed, i);
1284 if ((mask & kAccProtected) != 0) {
1285 mask &= ~kAccProtected;
1286 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccPublic);
1287 }
1288 OrMaskToFieldFlags(dex_file, "foo", mask);
1289 },
Andreas Gampee6215c02015-08-31 18:54:38 -07001290 "Interface field has disallowed flag");
1291 }
1292}
1293
1294// Standard bad interface. Needs to be separate from class as interfaces do not allow instance
1295// fields. Use declared-synchronized again for 3B encoding.
1296//
1297// .class public interface LInterfaceFieldFlags;
1298// .super Ljava/lang/Object;
1299//
1300// .field declared-synchronized public final foo:I
1301
1302static const char kFieldFlagsInterfaceBadTestDex[] =
1303 "ZGV4CjAzNQByMUnqYKHBkUpvvNp+9CnZ2VyDkKnRN6VkAQAAcAAAAHhWNBIAAAAAAAAAAPQAAAAE"
1304 "AAAAcAAAAAMAAACAAAAAAAAAAAAAAAABAAAAjAAAAAAAAAAAAAAAAQAAAJQAAACwAAAAtAAAALQA"
1305 "AAC3AAAAzgAAAOIAAAAAAAAAAQAAAAIAAAABAAAAAwAAAAEAAAABAgAAAgAAAAAAAAD/////AAAA"
1306 "AOwAAAAAAAAAAUkAFUxJbnRlcmZhY2VGaWVsZEZsYWdzOwASTGphdmEvbGFuZy9PYmplY3Q7AANm"
1307 "b28AAAAAAAAAAQAAAJGACAkAAAAAAAAAAQAAAAAAAAABAAAABAAAAHAAAAACAAAAAwAAAIAAAAAE"
1308 "AAAAAQAAAIwAAAAGAAAAAQAAAJQAAAACIAAABAAAALQAAAADEAAAAQAAAOgAAAAAIAAAAQAAAOwA"
1309 "AAAAEAAAAQAAAPQAAAA=";
1310
1311TEST_F(DexFileVerifierTest, FieldAccessFlagsInterfaceNonStatic) {
1312 VerifyModification(
1313 kFieldFlagsInterfaceBadTestDex,
1314 "field_flags_interface_non_static",
1315 [](DexFile* dex_file) {
1316 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
1317 },
Andreas Gampe76ed99d2016-03-28 18:31:29 -07001318 nullptr); // Should be allowed in older dex versions for backwards compatibility.
1319 VerifyModification(
1320 kFieldFlagsInterfaceBadTestDex,
1321 "field_flags_interface_non_static",
1322 [](DexFile* dex_file) {
1323 MakeDexVersion37(dex_file);
1324 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
1325 },
Andreas Gampee6215c02015-08-31 18:54:38 -07001326 "Interface field is not public final static");
Andreas Gampedf10b322014-06-11 21:46:05 -07001327}
1328
Logan Chiendd3208d2015-04-19 23:27:52 +08001329// Generated from:
1330//
1331// .class public LTest;
1332// .super Ljava/lang/Object;
1333// .source "Test.java"
1334//
1335// .method public constructor <init>()V
1336// .registers 1
1337//
1338// .prologue
1339// .line 1
1340// invoke-direct {p0}, Ljava/lang/Object;-><init>()V
1341//
1342// return-void
1343// .end method
1344//
1345// .method public static main()V
1346// .registers 2
1347//
1348// const-string v0, "a"
1349// const-string v0, "b"
1350// const-string v0, "c"
1351// const-string v0, "d"
1352// const-string v0, "e"
1353// const-string v0, "f"
1354// const-string v0, "g"
1355// const-string v0, "h"
1356// const-string v0, "i"
1357// const-string v0, "j"
1358// const-string v0, "k"
1359//
1360// .local v1, "local_var":Ljava/lang/String;
1361// const-string v1, "test"
1362// .end method
1363
1364static const char kDebugInfoTestDex[] =
1365 "ZGV4CjAzNQCHRkHix2eIMQgvLD/0VGrlllZLo0Rb6VyUAgAAcAAAAHhWNBIAAAAAAAAAAAwCAAAU"
1366 "AAAAcAAAAAQAAADAAAAAAQAAANAAAAAAAAAAAAAAAAMAAADcAAAAAQAAAPQAAACAAQAAFAEAABQB"
1367 "AAAcAQAAJAEAADgBAABMAQAAVwEAAFoBAABdAQAAYAEAAGMBAABmAQAAaQEAAGwBAABvAQAAcgEA"
1368 "AHUBAAB4AQAAewEAAIYBAACMAQAAAQAAAAIAAAADAAAABQAAAAUAAAADAAAAAAAAAAAAAAAAAAAA"
1369 "AAAAABIAAAABAAAAAAAAAAAAAAABAAAAAQAAAAAAAAAEAAAAAAAAAPwBAAAAAAAABjxpbml0PgAG"
1370 "TFRlc3Q7ABJMamF2YS9sYW5nL09iamVjdDsAEkxqYXZhL2xhbmcvU3RyaW5nOwAJVGVzdC5qYXZh"
1371 "AAFWAAFhAAFiAAFjAAFkAAFlAAFmAAFnAAFoAAFpAAFqAAFrAAlsb2NhbF92YXIABG1haW4ABHRl"
1372 "c3QAAAABAAcOAAAAARYDARIDAAAAAQABAAEAAACUAQAABAAAAHAQAgAAAA4AAgAAAAAAAACZAQAA"
1373 "GAAAABoABgAaAAcAGgAIABoACQAaAAoAGgALABoADAAaAA0AGgAOABoADwAaABAAGgETAAAAAgAA"
1374 "gYAEpAMBCbwDAAALAAAAAAAAAAEAAAAAAAAAAQAAABQAAABwAAAAAgAAAAQAAADAAAAAAwAAAAEA"
1375 "AADQAAAABQAAAAMAAADcAAAABgAAAAEAAAD0AAAAAiAAABQAAAAUAQAAAyAAAAIAAACUAQAAASAA"
1376 "AAIAAACkAQAAACAAAAEAAAD8AQAAABAAAAEAAAAMAgAA";
1377
1378TEST_F(DexFileVerifierTest, DebugInfoTypeIdxTest) {
1379 {
1380 // The input dex file should be good before modification.
1381 ScratchFile tmp;
1382 std::string error_msg;
1383 std::unique_ptr<const DexFile> raw(OpenDexFileBase64(kDebugInfoTestDex,
1384 tmp.GetFilename().c_str(),
1385 &error_msg));
1386 ASSERT_TRUE(raw.get() != nullptr) << error_msg;
1387 }
1388
Andreas Gampee6215c02015-08-31 18:54:38 -07001389 // Modify the debug information entry.
1390 VerifyModification(
1391 kDebugInfoTestDex,
1392 "debug_start_type_idx",
1393 [](DexFile* dex_file) {
1394 *(const_cast<uint8_t*>(dex_file->Begin()) + 416) = 0x14U;
1395 },
1396 "DBG_START_LOCAL type_idx");
Logan Chiendd3208d2015-04-19 23:27:52 +08001397}
1398
Andreas Gampeb512c0e2016-02-19 19:45:34 -08001399TEST_F(DexFileVerifierTest, SectionAlignment) {
1400 {
1401 // The input dex file should be good before modification. Any file is fine, as long as it
1402 // uses all sections.
1403 ScratchFile tmp;
1404 std::string error_msg;
1405 std::unique_ptr<const DexFile> raw(OpenDexFileBase64(kGoodTestDex,
1406 tmp.GetFilename().c_str(),
1407 &error_msg));
1408 ASSERT_TRUE(raw.get() != nullptr) << error_msg;
1409 }
1410
1411 // Modify all section offsets to be unaligned.
1412 constexpr size_t kSections = 7;
1413 for (size_t i = 0; i < kSections; ++i) {
1414 VerifyModification(
1415 kGoodTestDex,
1416 "section_align",
1417 [&](DexFile* dex_file) {
1418 DexFile::Header* header = const_cast<DexFile::Header*>(
1419 reinterpret_cast<const DexFile::Header*>(dex_file->Begin()));
1420 uint32_t* off_ptr;
1421 switch (i) {
1422 case 0:
1423 off_ptr = &header->map_off_;
1424 break;
1425 case 1:
1426 off_ptr = &header->string_ids_off_;
1427 break;
1428 case 2:
1429 off_ptr = &header->type_ids_off_;
1430 break;
1431 case 3:
1432 off_ptr = &header->proto_ids_off_;
1433 break;
1434 case 4:
1435 off_ptr = &header->field_ids_off_;
1436 break;
1437 case 5:
1438 off_ptr = &header->method_ids_off_;
1439 break;
1440 case 6:
1441 off_ptr = &header->class_defs_off_;
1442 break;
1443
1444 static_assert(kSections == 7, "kSections is wrong");
1445 default:
1446 LOG(FATAL) << "Unexpected section";
1447 UNREACHABLE();
1448 }
1449 ASSERT_TRUE(off_ptr != nullptr);
1450 ASSERT_NE(*off_ptr, 0U) << i; // Should already contain a value (in use).
1451 (*off_ptr)++; // Add one, which should misalign it (all the sections
1452 // above are aligned by 4).
1453 },
1454 "should be aligned by 4 for");
1455 }
1456}
1457
Vladimir Marko0ca8add2016-05-03 17:17:50 +01001458// Generated from
1459//
1460// .class LOverloading;
1461//
1462// .super Ljava/lang/Object;
1463//
1464// .method public static foo()V
1465// .registers 1
1466// return-void
1467// .end method
1468//
1469// .method public static foo(I)V
1470// .registers 1
1471// return-void
1472// .end method
1473static const char kProtoOrderingTestDex[] =
1474 "ZGV4CjAzNQA1L+ABE6voQ9Lr4Ci//efB53oGnDr5PinsAQAAcAAAAHhWNBIAAAAAAAAAAFgBAAAG"
1475 "AAAAcAAAAAQAAACIAAAAAgAAAJgAAAAAAAAAAAAAAAIAAACwAAAAAQAAAMAAAAAMAQAA4AAAAOAA"
1476 "AADjAAAA8gAAAAYBAAAJAQAADQEAAAAAAAABAAAAAgAAAAMAAAADAAAAAwAAAAAAAAAEAAAAAwAA"
1477 "ABQBAAABAAAABQAAAAEAAQAFAAAAAQAAAAAAAAACAAAAAAAAAP////8AAAAASgEAAAAAAAABSQAN"
1478 "TE92ZXJsb2FkaW5nOwASTGphdmEvbGFuZy9PYmplY3Q7AAFWAAJWSQADZm9vAAAAAQAAAAAAAAAA"
1479 "AAAAAAAAAAEAAAAAAAAAAAAAAAEAAAAOAAAAAQABAAAAAAAAAAAAAQAAAA4AAAACAAAJpAIBCbgC"
1480 "AAAMAAAAAAAAAAEAAAAAAAAAAQAAAAYAAABwAAAAAgAAAAQAAACIAAAAAwAAAAIAAACYAAAABQAA"
1481 "AAIAAACwAAAABgAAAAEAAADAAAAAAiAAAAYAAADgAAAAARAAAAEAAAAUAQAAAxAAAAIAAAAcAQAA"
1482 "ASAAAAIAAAAkAQAAACAAAAEAAABKAQAAABAAAAEAAABYAQAA";
1483
1484TEST_F(DexFileVerifierTest, ProtoOrdering) {
1485 {
1486 // The input dex file should be good before modification.
1487 ScratchFile tmp;
1488 std::string error_msg;
1489 std::unique_ptr<const DexFile> raw(OpenDexFileBase64(kProtoOrderingTestDex,
1490 tmp.GetFilename().c_str(),
1491 &error_msg));
1492 ASSERT_TRUE(raw.get() != nullptr) << error_msg;
1493 }
1494
1495 // Modify the order of the ProtoIds for two overloads of "foo" with the
1496 // same return type and one having longer parameter list than the other.
1497 for (size_t i = 0; i != 2; ++i) {
1498 VerifyModification(
1499 kProtoOrderingTestDex,
1500 "proto_ordering",
1501 [i](DexFile* dex_file) {
1502 uint32_t method_idx;
1503 const uint8_t* data = FindMethodData(dex_file, "foo", &method_idx);
1504 CHECK(data != nullptr);
1505 // There should be 2 methods called "foo".
1506 CHECK_LT(method_idx + 1u, dex_file->NumMethodIds());
1507 CHECK_EQ(dex_file->GetMethodId(method_idx).name_idx_,
1508 dex_file->GetMethodId(method_idx + 1).name_idx_);
1509 CHECK_EQ(dex_file->GetMethodId(method_idx).proto_idx_ + 1u,
1510 dex_file->GetMethodId(method_idx + 1).proto_idx_);
1511 // Their return types should be the same.
1512 uint32_t proto1_idx = dex_file->GetMethodId(method_idx).proto_idx_;
1513 const DexFile::ProtoId& proto1 = dex_file->GetProtoId(proto1_idx);
1514 const DexFile::ProtoId& proto2 = dex_file->GetProtoId(proto1_idx + 1u);
1515 CHECK_EQ(proto1.return_type_idx_, proto2.return_type_idx_);
1516 // And the first should not have any parameters while the second should have some.
1517 CHECK(!DexFileParameterIterator(*dex_file, proto1).HasNext());
1518 CHECK(DexFileParameterIterator(*dex_file, proto2).HasNext());
1519 if (i == 0) {
1520 // Swap the proto parameters and shorties to break the ordering.
1521 std::swap(const_cast<uint32_t&>(proto1.parameters_off_),
1522 const_cast<uint32_t&>(proto2.parameters_off_));
1523 std::swap(const_cast<uint32_t&>(proto1.shorty_idx_),
1524 const_cast<uint32_t&>(proto2.shorty_idx_));
1525 } else {
1526 // Copy the proto parameters and shorty to create duplicate proto id.
1527 const_cast<uint32_t&>(proto1.parameters_off_) = proto2.parameters_off_;
1528 const_cast<uint32_t&>(proto1.shorty_idx_) = proto2.shorty_idx_;
1529 }
1530 },
1531 "Out-of-order proto_id arguments");
1532 }
1533}
1534
Roland Levillain621b5ea2016-05-18 11:41:33 +01001535// To generate a base64 encoded Dex file version 037 from Smali files, use:
1536//
1537// smali --api-level 24 -o classes.dex class1.smali [class2.smali ...]
1538// base64 classes.dex >classes.dex.base64
1539
1540// Dex file version 037 generated from:
1541//
1542// .class public LB28685551;
1543// .super LB28685551;
1544
1545static const char kClassExtendsItselfTestDex[] =
1546 "ZGV4CjAzNwDeGbgRg1kb6swszpcTWrrOAALB++F4OPT0AAAAcAAAAHhWNBIAAAAAAAAAAKgAAAAB"
1547 "AAAAcAAAAAEAAAB0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAHgAAABcAAAAmAAAAJgA"
1548 "AAAAAAAAAAAAAAEAAAAAAAAAAAAAAP////8AAAAAAAAAAAAAAAALTEIyODY4NTU1MTsAAAAABgAA"
1549 "AAAAAAABAAAAAAAAAAEAAAABAAAAcAAAAAIAAAABAAAAdAAAAAYAAAABAAAAeAAAAAIgAAABAAAA"
1550 "mAAAAAAQAAABAAAAqAAAAA==";
1551
1552TEST_F(DexFileVerifierTest, ClassExtendsItself) {
1553 VerifyModification(
1554 kClassExtendsItselfTestDex,
1555 "class_extends_itself",
1556 [](DexFile* dex_file ATTRIBUTE_UNUSED) { /* empty */ },
1557 "Class with same type idx as its superclass: '0'");
1558}
1559
1560// Dex file version 037 generated from:
1561//
1562// .class public LFoo;
1563// .super LBar;
1564//
1565// and:
1566//
1567// .class public LBar;
1568// .super LFoo;
1569
1570static const char kClassesExtendOneAnotherTestDex[] =
1571 "ZGV4CjAzNwBXHSrwpDMwRBkg+L+JeQCuFNRLhQ86duEcAQAAcAAAAHhWNBIAAAAAAAAAANAAAAAC"
1572 "AAAAcAAAAAIAAAB4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAIAAAABcAAAAwAAAAMAA"
1573 "AADHAAAAAAAAAAEAAAABAAAAAQAAAAAAAAAAAAAA/////wAAAAAAAAAAAAAAAAAAAAABAAAAAQAA"
1574 "AAAAAAD/////AAAAAAAAAAAAAAAABUxCYXI7AAVMRm9vOwAAAAYAAAAAAAAAAQAAAAAAAAABAAAA"
1575 "AgAAAHAAAAACAAAAAgAAAHgAAAAGAAAAAgAAAIAAAAACIAAAAgAAAMAAAAAAEAAAAQAAANAAAAA=";
1576
1577TEST_F(DexFileVerifierTest, ClassesExtendOneAnother) {
1578 VerifyModification(
1579 kClassesExtendOneAnotherTestDex,
1580 "classes_extend_one_another",
1581 [](DexFile* dex_file ATTRIBUTE_UNUSED) { /* empty */ },
1582 "Invalid class definition ordering: class with type idx: '1' defined before"
1583 " superclass with type idx: '0'");
1584}
1585
1586// Dex file version 037 generated from:
1587//
1588// .class public LAll;
1589// .super LYour;
1590//
1591// and:
1592//
1593// .class public LYour;
1594// .super LBase;
1595//
1596// and:
1597//
1598// .class public LBase;
1599// .super LAll;
1600
1601static const char kCircularClassInheritanceTestDex[] =
1602 "ZGV4CjAzNwBMJxgP0SJz6oLXnKfl+J7lSEORLRwF5LNMAQAAcAAAAHhWNBIAAAAAAAAAAAABAAAD"
1603 "AAAAcAAAAAMAAAB8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAIgAAABkAAAA6AAAAOgA"
1604 "AADvAAAA9wAAAAAAAAABAAAAAgAAAAEAAAABAAAAAAAAAAAAAAD/////AAAAAAAAAAAAAAAAAgAA"
1605 "AAEAAAABAAAAAAAAAP////8AAAAAAAAAAAAAAAAAAAAAAQAAAAIAAAAAAAAA/////wAAAAAAAAAA"
1606 "AAAAAAVMQWxsOwAGTEJhc2U7AAZMWW91cjsAAAYAAAAAAAAAAQAAAAAAAAABAAAAAwAAAHAAAAAC"
1607 "AAAAAwAAAHwAAAAGAAAAAwAAAIgAAAACIAAAAwAAAOgAAAAAEAAAAQAAAAABAAA=";
1608
1609TEST_F(DexFileVerifierTest, CircularClassInheritance) {
1610 VerifyModification(
1611 kCircularClassInheritanceTestDex,
1612 "circular_class_inheritance",
1613 [](DexFile* dex_file ATTRIBUTE_UNUSED) { /* empty */ },
1614 "Invalid class definition ordering: class with type idx: '1' defined before"
1615 " superclass with type idx: '0'");
1616}
1617
1618// Dex file version 037 generated from:
1619//
1620// .class public abstract interface LInterfaceImplementsItself;
1621// .super Ljava/lang/Object;
1622// .implements LInterfaceImplementsItself;
1623
1624static const char kInterfaceImplementsItselfTestDex[] =
1625 "ZGV4CjAzNwCKKrjatp8XbXl5S/bEVJnqaBhjZkQY4440AQAAcAAAAHhWNBIAAAAAAAAAANwAAAAC"
1626 "AAAAcAAAAAIAAAB4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAIAAAACUAAAAoAAAAKAA"
1627 "AAC9AAAAAAAAAAEAAAAAAAAAAQYAAAEAAADUAAAA/////wAAAAAAAAAAAAAAABtMSW50ZXJmYWNl"
1628 "SW1wbGVtZW50c0l0c2VsZjsAEkxqYXZhL2xhbmcvT2JqZWN0OwAAAAABAAAAAAAAAAcAAAAAAAAA"
1629 "AQAAAAAAAAABAAAAAgAAAHAAAAACAAAAAgAAAHgAAAAGAAAAAQAAAIAAAAACIAAAAgAAAKAAAAAB"
1630 "EAAAAQAAANQAAAAAEAAAAQAAANwAAAA=";
1631
1632TEST_F(DexFileVerifierTest, InterfaceImplementsItself) {
1633 VerifyModification(
1634 kInterfaceImplementsItselfTestDex,
1635 "interface_implements_itself",
1636 [](DexFile* dex_file ATTRIBUTE_UNUSED) { /* empty */ },
1637 "Class with same type idx as implemented interface: '0'");
1638}
1639
1640// Dex file version 037 generated from:
1641//
1642// .class public abstract interface LPing;
1643// .super Ljava/lang/Object;
1644// .implements LPong;
1645//
1646// and:
1647//
1648// .class public abstract interface LPong;
1649// .super Ljava/lang/Object;
1650// .implements LPing;
1651
1652static const char kInterfacesImplementOneAnotherTestDex[] =
1653 "ZGV4CjAzNwD0Kk9sxlYdg3Dy1Cff0gQCuJAQfEP6ohZUAQAAcAAAAHhWNBIAAAAAAAAAAPwAAAAD"
1654 "AAAAcAAAAAMAAAB8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAIgAAACMAAAAyAAAAMgA"
1655 "AADQAAAA2AAAAAAAAAABAAAAAgAAAAEAAAABBgAAAgAAAOwAAAD/////AAAAAAAAAAAAAAAAAAAA"
1656 "AAEGAAACAAAA9AAAAP////8AAAAAAAAAAAAAAAAGTFBpbmc7AAZMUG9uZzsAEkxqYXZhL2xhbmcv"
1657 "T2JqZWN0OwABAAAAAAAAAAEAAAABAAAABwAAAAAAAAABAAAAAAAAAAEAAAADAAAAcAAAAAIAAAAD"
1658 "AAAAfAAAAAYAAAACAAAAiAAAAAIgAAADAAAAyAAAAAEQAAACAAAA7AAAAAAQAAABAAAA/AAAAA==";
1659
1660TEST_F(DexFileVerifierTest, InterfacesImplementOneAnother) {
1661 VerifyModification(
1662 kInterfacesImplementOneAnotherTestDex,
1663 "interfaces_implement_one_another",
1664 [](DexFile* dex_file ATTRIBUTE_UNUSED) { /* empty */ },
1665 "Invalid class definition ordering: class with type idx: '1' defined before"
1666 " implemented interface with type idx: '0'");
1667}
1668
1669// Dex file version 037 generated from:
1670//
1671// .class public abstract interface LA;
1672// .super Ljava/lang/Object;
1673// .implements LB;
1674//
1675// and:
1676//
1677// .class public abstract interface LB;
1678// .super Ljava/lang/Object;
1679// .implements LC;
1680//
1681// and:
1682//
1683// .class public abstract interface LC;
1684// .super Ljava/lang/Object;
1685// .implements LA;
1686
1687static const char kCircularInterfaceImplementationTestDex[] =
1688 "ZGV4CjAzNwCzKmD5Fol6XAU6ichYHcUTIP7Z7MdTcEmEAQAAcAAAAHhWNBIAAAAAAAAAACwBAAAE"
1689 "AAAAcAAAAAQAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAJAAAACUAAAA8AAAAPAA"
1690 "AAD1AAAA+gAAAP8AAAAAAAAAAQAAAAIAAAADAAAAAgAAAAEGAAADAAAAHAEAAP////8AAAAAAAAA"
1691 "AAAAAAABAAAAAQYAAAMAAAAUAQAA/////wAAAAAAAAAAAAAAAAAAAAABBgAAAwAAACQBAAD/////"
1692 "AAAAAAAAAAAAAAAAA0xBOwADTEI7AANMQzsAEkxqYXZhL2xhbmcvT2JqZWN0OwAAAQAAAAIAAAAB"
1693 "AAAAAAAAAAEAAAABAAAABwAAAAAAAAABAAAAAAAAAAEAAAAEAAAAcAAAAAIAAAAEAAAAgAAAAAYA"
1694 "AAADAAAAkAAAAAIgAAAEAAAA8AAAAAEQAAADAAAAFAEAAAAQAAABAAAALAEAAA==";
1695
1696TEST_F(DexFileVerifierTest, CircularInterfaceImplementation) {
1697 VerifyModification(
1698 kCircularInterfaceImplementationTestDex,
1699 "circular_interface_implementation",
1700 [](DexFile* dex_file ATTRIBUTE_UNUSED) { /* empty */ },
1701 "Invalid class definition ordering: class with type idx: '2' defined before"
1702 " implemented interface with type idx: '0'");
1703}
1704
Aart Bik37d6a3b2016-06-21 18:30:10 -07001705TEST_F(DexFileVerifierTest, Checksum) {
1706 size_t length;
1707 std::unique_ptr<uint8_t[]> dex_bytes = DecodeBase64(kGoodTestDex, &length);
1708 CHECK(dex_bytes != nullptr);
1709 // Note: `dex_file` will be destroyed before `dex_bytes`.
1710 std::unique_ptr<DexFile> dex_file(GetDexFile(dex_bytes.get(), length));
1711 std::string error_msg;
1712
1713 // Good checksum: all pass.
1714 EXPECT_TRUE(DexFileVerifier::Verify(dex_file.get(),
1715 dex_file->Begin(),
1716 dex_file->Size(),
1717 "good checksum, no verify",
1718 /*verify_checksum*/ false,
1719 &error_msg));
1720 EXPECT_TRUE(DexFileVerifier::Verify(dex_file.get(),
1721 dex_file->Begin(),
1722 dex_file->Size(),
1723 "good checksum, verify",
1724 /*verify_checksum*/ true,
1725 &error_msg));
1726
1727 // Bad checksum: !verify_checksum passes verify_checksum fails.
1728 DexFile::Header* header = reinterpret_cast<DexFile::Header*>(
1729 const_cast<uint8_t*>(dex_file->Begin()));
1730 header->checksum_ = 0;
1731 EXPECT_TRUE(DexFileVerifier::Verify(dex_file.get(),
1732 dex_file->Begin(),
1733 dex_file->Size(),
1734 "bad checksum, no verify",
1735 /*verify_checksum*/ false,
1736 &error_msg));
1737 EXPECT_FALSE(DexFileVerifier::Verify(dex_file.get(),
1738 dex_file->Begin(),
1739 dex_file->Size(),
1740 "bad checksum, verify",
1741 /*verify_checksum*/ true,
1742 &error_msg));
1743 EXPECT_NE(error_msg.find("Bad checksum"), std::string::npos) << error_msg;
1744}
1745
Andreas Gampedf10b322014-06-11 21:46:05 -07001746} // namespace art