1 /*
2 * Copyright (C) 2017 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 <fstream>
18
19 #include "base/unix_file/fd_file.h"
20 #include "common_runtime_test.h"
21 #include "dex/art_dex_file_loader.h"
22 #include "dex/dex_file-inl.h"
23 #include "exec_utils.h"
24 #include "zip_archive.h"
25
26 namespace art {
27
28 class HiddenApiTest : public CommonRuntimeTest {
29 protected:
GetHiddenApiCmd()30 std::string GetHiddenApiCmd() {
31 std::string file_path = GetTestAndroidRoot();
32 file_path += "/bin/hiddenapi";
33 if (kIsDebugBuild) {
34 file_path += "d";
35 }
36 if (!OS::FileExists(file_path.c_str())) {
37 LOG(FATAL) << "Could not find binary " << file_path;
38 UNREACHABLE();
39 }
40 return file_path;
41 }
42
RunHiddenApi(const ScratchFile & light_greylist,const ScratchFile & dark_greylist,const ScratchFile & blacklist,const std::vector<std::string> & extra_args,ScratchFile * out_dex)43 std::unique_ptr<const DexFile> RunHiddenApi(const ScratchFile& light_greylist,
44 const ScratchFile& dark_greylist,
45 const ScratchFile& blacklist,
46 const std::vector<std::string>& extra_args,
47 ScratchFile* out_dex) {
48 std::string error;
49 std::unique_ptr<ZipArchive> jar(
50 ZipArchive::Open(GetTestDexFileName("HiddenApi").c_str(), &error));
51 if (jar == nullptr) {
52 LOG(FATAL) << "Could not open test file " << GetTestDexFileName("HiddenApi") << ": " << error;
53 UNREACHABLE();
54 }
55 std::unique_ptr<ZipEntry> jar_classes_dex(jar->Find("classes.dex", &error));
56 if (jar_classes_dex == nullptr) {
57 LOG(FATAL) << "Could not find classes.dex in test file " << GetTestDexFileName("HiddenApi")
58 << ": " << error;
59 UNREACHABLE();
60 } else if (!jar_classes_dex->ExtractToFile(*out_dex->GetFile(), &error)) {
61 LOG(FATAL) << "Could not extract classes.dex from test file "
62 << GetTestDexFileName("HiddenApi") << ": " << error;
63 UNREACHABLE();
64 }
65
66 std::vector<std::string> argv_str;
67 argv_str.push_back(GetHiddenApiCmd());
68 argv_str.insert(argv_str.end(), extra_args.begin(), extra_args.end());
69 argv_str.push_back("--dex=" + out_dex->GetFilename());
70 argv_str.push_back("--light-greylist=" + light_greylist.GetFilename());
71 argv_str.push_back("--dark-greylist=" + dark_greylist.GetFilename());
72 argv_str.push_back("--blacklist=" + blacklist.GetFilename());
73 int return_code = ExecAndReturnCode(argv_str, &error);
74 if (return_code != 0) {
75 LOG(FATAL) << "HiddenApi binary exited with unexpected return code " << return_code;
76 }
77 return OpenDex(*out_dex);
78 }
79
OpenDex(const ScratchFile & file)80 std::unique_ptr<const DexFile> OpenDex(const ScratchFile& file) {
81 ArtDexFileLoader dex_loader;
82 std::string error_msg;
83
84 File fd(file.GetFilename(), O_RDONLY, /* check_usage */ false);
85 if (fd.Fd() == -1) {
86 LOG(FATAL) << "Unable to open file '" << file.GetFilename() << "': " << strerror(errno);
87 UNREACHABLE();
88 }
89
90 std::unique_ptr<const DexFile> dex_file(dex_loader.OpenDex(
91 fd.Release(), /* location */ file.GetFilename(), /* verify */ false,
92 /* verify_checksum */ true, /* mmap_shared */ false, &error_msg));
93 if (dex_file.get() == nullptr) {
94 LOG(FATAL) << "Open failed for '" << file.GetFilename() << "' " << error_msg;
95 UNREACHABLE();
96 } else if (!dex_file->IsStandardDexFile()) {
97 LOG(FATAL) << "Expected a standard dex file '" << file.GetFilename() << "'";
98 UNREACHABLE();
99 }
100
101 return dex_file;
102 }
103
OpenStream(const ScratchFile & file)104 std::ofstream OpenStream(const ScratchFile& file) {
105 std::ofstream ofs(file.GetFilename(), std::ofstream::out);
106 if (ofs.fail()) {
107 LOG(FATAL) << "Open failed for '" << file.GetFilename() << "' " << strerror(errno);
108 UNREACHABLE();
109 }
110 return ofs;
111 }
112
FindClass(const char * desc,const DexFile & dex_file)113 const DexFile::ClassDef& FindClass(const char* desc, const DexFile& dex_file) {
114 for (uint32_t i = 0; i < dex_file.NumClassDefs(); ++i) {
115 const DexFile::ClassDef& class_def = dex_file.GetClassDef(i);
116 if (strcmp(desc, dex_file.GetClassDescriptor(class_def)) == 0) {
117 return class_def;
118 }
119 }
120 LOG(FATAL) << "Could not find class " << desc;
121 UNREACHABLE();
122 }
123
GetFieldHiddenFlags(const char * name,uint32_t expected_visibility,const DexFile::ClassDef & class_def,const DexFile & dex_file)124 HiddenApiAccessFlags::ApiList GetFieldHiddenFlags(const char* name,
125 uint32_t expected_visibility,
126 const DexFile::ClassDef& class_def,
127 const DexFile& dex_file) {
128 const uint8_t* class_data = dex_file.GetClassData(class_def);
129 if (class_data == nullptr) {
130 LOG(FATAL) << "Class " << dex_file.GetClassDescriptor(class_def) << " has no data";
131 UNREACHABLE();
132 }
133
134 for (ClassDataItemIterator it(dex_file, class_data); it.HasNext(); it.Next()) {
135 if (it.IsAtMethod()) {
136 break;
137 }
138 const DexFile::FieldId& fid = dex_file.GetFieldId(it.GetMemberIndex());
139 if (strcmp(name, dex_file.GetFieldName(fid)) == 0) {
140 uint32_t actual_visibility = it.GetFieldAccessFlags() & kAccVisibilityFlags;
141 if (actual_visibility != expected_visibility) {
142 LOG(FATAL) << "Field " << name << " in class " << dex_file.GetClassDescriptor(class_def)
143 << " does not have the expected visibility flags (" << expected_visibility
144 << " != " << actual_visibility << ")";
145 UNREACHABLE();
146 }
147 return it.DecodeHiddenAccessFlags();
148 }
149 }
150
151 LOG(FATAL) << "Could not find field " << name << " in class "
152 << dex_file.GetClassDescriptor(class_def);
153 UNREACHABLE();
154 }
155
GetMethodHiddenFlags(const char * name,uint32_t expected_visibility,bool expected_native,const DexFile::ClassDef & class_def,const DexFile & dex_file)156 HiddenApiAccessFlags::ApiList GetMethodHiddenFlags(const char* name,
157 uint32_t expected_visibility,
158 bool expected_native,
159 const DexFile::ClassDef& class_def,
160 const DexFile& dex_file) {
161 const uint8_t* class_data = dex_file.GetClassData(class_def);
162 if (class_data == nullptr) {
163 LOG(FATAL) << "Class " << dex_file.GetClassDescriptor(class_def) << " has no data";
164 UNREACHABLE();
165 }
166
167 for (ClassDataItemIterator it(dex_file, class_data); it.HasNext(); it.Next()) {
168 if (!it.IsAtMethod()) {
169 continue;
170 }
171 const DexFile::MethodId& mid = dex_file.GetMethodId(it.GetMemberIndex());
172 if (strcmp(name, dex_file.GetMethodName(mid)) == 0) {
173 if (expected_native != it.MemberIsNative()) {
174 LOG(FATAL) << "Expected native=" << expected_native << " for method " << name
175 << " in class " << dex_file.GetClassDescriptor(class_def);
176 UNREACHABLE();
177 }
178 uint32_t actual_visibility = it.GetMethodAccessFlags() & kAccVisibilityFlags;
179 if (actual_visibility != expected_visibility) {
180 LOG(FATAL) << "Method " << name << " in class " << dex_file.GetClassDescriptor(class_def)
181 << " does not have the expected visibility flags (" << expected_visibility
182 << " != " << actual_visibility << ")";
183 UNREACHABLE();
184 }
185 return it.DecodeHiddenAccessFlags();
186 }
187 }
188
189 LOG(FATAL) << "Could not find method " << name << " in class "
190 << dex_file.GetClassDescriptor(class_def);
191 UNREACHABLE();
192 }
193
GetIFieldHiddenFlags(const DexFile & dex_file)194 HiddenApiAccessFlags::ApiList GetIFieldHiddenFlags(const DexFile& dex_file) {
195 return GetFieldHiddenFlags("ifield", kAccPublic, FindClass("LMain;", dex_file), dex_file);
196 }
197
GetSFieldHiddenFlags(const DexFile & dex_file)198 HiddenApiAccessFlags::ApiList GetSFieldHiddenFlags(const DexFile& dex_file) {
199 return GetFieldHiddenFlags("sfield", kAccPrivate, FindClass("LMain;", dex_file), dex_file);
200 }
201
GetIMethodHiddenFlags(const DexFile & dex_file)202 HiddenApiAccessFlags::ApiList GetIMethodHiddenFlags(const DexFile& dex_file) {
203 return GetMethodHiddenFlags(
204 "imethod", 0, /* native */ false, FindClass("LMain;", dex_file), dex_file);
205 }
206
GetSMethodHiddenFlags(const DexFile & dex_file)207 HiddenApiAccessFlags::ApiList GetSMethodHiddenFlags(const DexFile& dex_file) {
208 return GetMethodHiddenFlags(
209 "smethod", kAccPublic, /* native */ false, FindClass("LMain;", dex_file), dex_file);
210 }
211
GetINMethodHiddenFlags(const DexFile & dex_file)212 HiddenApiAccessFlags::ApiList GetINMethodHiddenFlags(const DexFile& dex_file) {
213 return GetMethodHiddenFlags(
214 "inmethod", kAccPublic, /* native */ true, FindClass("LMain;", dex_file), dex_file);
215 }
216
GetSNMethodHiddenFlags(const DexFile & dex_file)217 HiddenApiAccessFlags::ApiList GetSNMethodHiddenFlags(const DexFile& dex_file) {
218 return GetMethodHiddenFlags(
219 "snmethod", kAccProtected, /* native */ true, FindClass("LMain;", dex_file), dex_file);
220 }
221 };
222
TEST_F(HiddenApiTest,InstanceFieldNoMatch)223 TEST_F(HiddenApiTest, InstanceFieldNoMatch) {
224 ScratchFile dex, light_greylist, dark_greylist, blacklist;
225 OpenStream(light_greylist) << "LMain;->ifield:LBadType1;" << std::endl;
226 OpenStream(dark_greylist) << "LMain;->ifield:LBadType2;" << std::endl;
227 OpenStream(blacklist) << "LMain;->ifield:LBadType3;" << std::endl;
228 auto dex_file = RunHiddenApi(light_greylist, dark_greylist, blacklist, {}, &dex);
229 ASSERT_EQ(HiddenApiAccessFlags::kWhitelist, GetIFieldHiddenFlags(*dex_file));
230 }
231
TEST_F(HiddenApiTest,InstanceFieldLightGreylistMatch)232 TEST_F(HiddenApiTest, InstanceFieldLightGreylistMatch) {
233 ScratchFile dex, light_greylist, dark_greylist, blacklist;
234 OpenStream(light_greylist) << "LMain;->ifield:I" << std::endl;
235 OpenStream(dark_greylist) << "LMain;->ifield:LBadType2;" << std::endl;
236 OpenStream(blacklist) << "LMain;->ifield:LBadType3;" << std::endl;
237 auto dex_file = RunHiddenApi(light_greylist, dark_greylist, blacklist, {}, &dex);
238 ASSERT_EQ(HiddenApiAccessFlags::kLightGreylist, GetIFieldHiddenFlags(*dex_file));
239 }
240
TEST_F(HiddenApiTest,InstanceFieldDarkGreylistMatch)241 TEST_F(HiddenApiTest, InstanceFieldDarkGreylistMatch) {
242 ScratchFile dex, light_greylist, dark_greylist, blacklist;
243 OpenStream(light_greylist) << "LMain;->ifield:LBadType1;" << std::endl;
244 OpenStream(dark_greylist) << "LMain;->ifield:I" << std::endl;
245 OpenStream(blacklist) << "LMain;->ifield:LBadType3;" << std::endl;
246 auto dex_file = RunHiddenApi(light_greylist, dark_greylist, blacklist, {}, &dex);
247 ASSERT_EQ(HiddenApiAccessFlags::kDarkGreylist, GetIFieldHiddenFlags(*dex_file));
248 }
249
TEST_F(HiddenApiTest,InstanceFieldBlacklistMatch)250 TEST_F(HiddenApiTest, InstanceFieldBlacklistMatch) {
251 ScratchFile dex, light_greylist, dark_greylist, blacklist;
252 OpenStream(light_greylist) << "LMain;->ifield:LBadType1;" << std::endl;
253 OpenStream(dark_greylist) << "LMain;->ifield:LBadType2;" << std::endl;
254 OpenStream(blacklist) << "LMain;->ifield:I" << std::endl;
255 auto dex_file = RunHiddenApi(light_greylist, dark_greylist, blacklist, {}, &dex);
256 ASSERT_EQ(HiddenApiAccessFlags::kBlacklist, GetIFieldHiddenFlags(*dex_file));
257 }
258
TEST_F(HiddenApiTest,InstanceFieldTwoListsMatch1)259 TEST_F(HiddenApiTest, InstanceFieldTwoListsMatch1) {
260 ScratchFile dex, light_greylist, dark_greylist, blacklist;
261 OpenStream(light_greylist) << "LMain;->ifield:LBadType1;" << std::endl;
262 OpenStream(dark_greylist) << "LMain;->ifield:I" << std::endl;
263 OpenStream(blacklist) << "LMain;->ifield:I" << std::endl;
264 auto dex_file = RunHiddenApi(light_greylist, dark_greylist, blacklist, {}, &dex);
265 ASSERT_EQ(HiddenApiAccessFlags::kBlacklist, GetIFieldHiddenFlags(*dex_file));
266 }
267
TEST_F(HiddenApiTest,InstanceFieldTwoListsMatch2)268 TEST_F(HiddenApiTest, InstanceFieldTwoListsMatch2) {
269 ScratchFile dex, light_greylist, dark_greylist, blacklist;
270 OpenStream(light_greylist) << "LMain;->ifield:I" << std::endl;
271 OpenStream(dark_greylist) << "LMain;->ifield:LBadType2;" << std::endl;
272 OpenStream(blacklist) << "LMain;->ifield:I" << std::endl;
273 auto dex_file = RunHiddenApi(light_greylist, dark_greylist, blacklist, {}, &dex);
274 ASSERT_EQ(HiddenApiAccessFlags::kBlacklist, GetIFieldHiddenFlags(*dex_file));
275 }
276
TEST_F(HiddenApiTest,InstanceFieldTwoListsMatch3)277 TEST_F(HiddenApiTest, InstanceFieldTwoListsMatch3) {
278 ScratchFile dex, light_greylist, dark_greylist, blacklist;
279 OpenStream(light_greylist) << "LMain;->ifield:I" << std::endl;
280 OpenStream(dark_greylist) << "LMain;->ifield:I" << std::endl;
281 OpenStream(blacklist) << "LMain;->ifield:LBadType3;" << std::endl;
282 auto dex_file = RunHiddenApi(light_greylist, dark_greylist, blacklist, {}, &dex);
283 ASSERT_EQ(HiddenApiAccessFlags::kDarkGreylist, GetIFieldHiddenFlags(*dex_file));
284 }
285
TEST_F(HiddenApiTest,StaticFieldNoMatch)286 TEST_F(HiddenApiTest, StaticFieldNoMatch) {
287 ScratchFile dex, light_greylist, dark_greylist, blacklist;
288 OpenStream(light_greylist) << "LMain;->sfield:LBadType1;" << std::endl;
289 OpenStream(dark_greylist) << "LMain;->sfield:LBadType2;" << std::endl;
290 OpenStream(blacklist) << "LMain;->sfield:LBadType3;" << std::endl;
291 auto dex_file = RunHiddenApi(light_greylist, dark_greylist, blacklist, {}, &dex);
292 ASSERT_EQ(HiddenApiAccessFlags::kWhitelist, GetSFieldHiddenFlags(*dex_file));
293 }
294
TEST_F(HiddenApiTest,StaticFieldLightGreylistMatch)295 TEST_F(HiddenApiTest, StaticFieldLightGreylistMatch) {
296 ScratchFile dex, light_greylist, dark_greylist, blacklist;
297 OpenStream(light_greylist) << "LMain;->sfield:Ljava/lang/Object;" << std::endl;
298 OpenStream(dark_greylist) << "LMain;->sfield:LBadType2;" << std::endl;
299 OpenStream(blacklist) << "LMain;->sfield:LBadType3;" << std::endl;
300 auto dex_file = RunHiddenApi(light_greylist, dark_greylist, blacklist, {}, &dex);
301 ASSERT_EQ(HiddenApiAccessFlags::kLightGreylist, GetSFieldHiddenFlags(*dex_file));
302 }
303
TEST_F(HiddenApiTest,StaticFieldDarkGreylistMatch)304 TEST_F(HiddenApiTest, StaticFieldDarkGreylistMatch) {
305 ScratchFile dex, light_greylist, dark_greylist, blacklist;
306 OpenStream(light_greylist) << "LMain;->sfield:LBadType1;" << std::endl;
307 OpenStream(dark_greylist) << "LMain;->sfield:Ljava/lang/Object;" << std::endl;
308 OpenStream(blacklist) << "LMain;->sfield:LBadType3;" << std::endl;
309 auto dex_file = RunHiddenApi(light_greylist, dark_greylist, blacklist, {}, &dex);
310 ASSERT_EQ(HiddenApiAccessFlags::kDarkGreylist, GetSFieldHiddenFlags(*dex_file));
311 }
312
TEST_F(HiddenApiTest,StaticFieldBlacklistMatch)313 TEST_F(HiddenApiTest, StaticFieldBlacklistMatch) {
314 ScratchFile dex, light_greylist, dark_greylist, blacklist;
315 OpenStream(light_greylist) << "LMain;->sfield:LBadType1;" << std::endl;
316 OpenStream(dark_greylist) << "LMain;->sfield:LBadType2;" << std::endl;
317 OpenStream(blacklist) << "LMain;->sfield:Ljava/lang/Object;" << std::endl;
318 auto dex_file = RunHiddenApi(light_greylist, dark_greylist, blacklist, {}, &dex);
319 ASSERT_EQ(HiddenApiAccessFlags::kBlacklist, GetSFieldHiddenFlags(*dex_file));
320 }
321
TEST_F(HiddenApiTest,StaticFieldTwoListsMatch1)322 TEST_F(HiddenApiTest, StaticFieldTwoListsMatch1) {
323 ScratchFile dex, light_greylist, dark_greylist, blacklist;
324 OpenStream(light_greylist) << "LMain;->sfield:LBadType1;" << std::endl;
325 OpenStream(dark_greylist) << "LMain;->sfield:Ljava/lang/Object;" << std::endl;
326 OpenStream(blacklist) << "LMain;->sfield:Ljava/lang/Object;" << std::endl;
327 auto dex_file = RunHiddenApi(light_greylist, dark_greylist, blacklist, {}, &dex);
328 ASSERT_EQ(HiddenApiAccessFlags::kBlacklist, GetSFieldHiddenFlags(*dex_file));
329 }
330
TEST_F(HiddenApiTest,StaticFieldTwoListsMatch2)331 TEST_F(HiddenApiTest, StaticFieldTwoListsMatch2) {
332 ScratchFile dex, light_greylist, dark_greylist, blacklist;
333 OpenStream(light_greylist) << "LMain;->sfield:Ljava/lang/Object;" << std::endl;
334 OpenStream(dark_greylist) << "LMain;->sfield:LBadType2;" << std::endl;
335 OpenStream(blacklist) << "LMain;->sfield:Ljava/lang/Object;" << std::endl;
336 auto dex_file = RunHiddenApi(light_greylist, dark_greylist, blacklist, {}, &dex);
337 ASSERT_EQ(HiddenApiAccessFlags::kBlacklist, GetSFieldHiddenFlags(*dex_file));
338 }
339
TEST_F(HiddenApiTest,StaticFieldTwoListsMatch3)340 TEST_F(HiddenApiTest, StaticFieldTwoListsMatch3) {
341 ScratchFile dex, light_greylist, dark_greylist, blacklist;
342 OpenStream(light_greylist) << "LMain;->sfield:Ljava/lang/Object;" << std::endl;
343 OpenStream(dark_greylist) << "LMain;->sfield:Ljava/lang/Object;" << std::endl;
344 OpenStream(blacklist) << "LMain;->sfield:LBadType3;" << std::endl;
345 auto dex_file = RunHiddenApi(light_greylist, dark_greylist, blacklist, {}, &dex);
346 ASSERT_EQ(HiddenApiAccessFlags::kDarkGreylist, GetSFieldHiddenFlags(*dex_file));
347 }
348
TEST_F(HiddenApiTest,InstanceMethodNoMatch)349 TEST_F(HiddenApiTest, InstanceMethodNoMatch) {
350 ScratchFile dex, light_greylist, dark_greylist, blacklist;
351 OpenStream(light_greylist) << "LMain;->imethod(LBadType1;)V" << std::endl;
352 OpenStream(dark_greylist) << "LMain;->imethod(LBadType2;)V" << std::endl;
353 OpenStream(blacklist) << "LMain;->imethod(LBadType3;)V" << std::endl;
354 auto dex_file = RunHiddenApi(light_greylist, dark_greylist, blacklist, {}, &dex);
355 ASSERT_EQ(HiddenApiAccessFlags::kWhitelist, GetIMethodHiddenFlags(*dex_file));
356 }
357
TEST_F(HiddenApiTest,InstanceMethodLightGreylistMatch)358 TEST_F(HiddenApiTest, InstanceMethodLightGreylistMatch) {
359 ScratchFile dex, light_greylist, dark_greylist, blacklist;
360 OpenStream(light_greylist) << "LMain;->imethod(J)V" << std::endl;
361 OpenStream(dark_greylist) << "LMain;->imethod(LBadType2;)V" << std::endl;
362 OpenStream(blacklist) << "LMain;->imethod(LBadType3;)V" << std::endl;
363 auto dex_file = RunHiddenApi(light_greylist, dark_greylist, blacklist, {}, &dex);
364 ASSERT_EQ(HiddenApiAccessFlags::kLightGreylist, GetIMethodHiddenFlags(*dex_file));
365 }
366
TEST_F(HiddenApiTest,InstanceMethodDarkGreylistMatch)367 TEST_F(HiddenApiTest, InstanceMethodDarkGreylistMatch) {
368 ScratchFile dex, light_greylist, dark_greylist, blacklist;
369 OpenStream(light_greylist) << "LMain;->imethod(LBadType1;)V" << std::endl;
370 OpenStream(dark_greylist) << "LMain;->imethod(J)V" << std::endl;
371 OpenStream(blacklist) << "LMain;->imethod(LBadType3;)V" << std::endl;
372 auto dex_file = RunHiddenApi(light_greylist, dark_greylist, blacklist, {}, &dex);
373 ASSERT_EQ(HiddenApiAccessFlags::kDarkGreylist, GetIMethodHiddenFlags(*dex_file));
374 }
375
TEST_F(HiddenApiTest,InstanceMethodBlacklistMatch)376 TEST_F(HiddenApiTest, InstanceMethodBlacklistMatch) {
377 ScratchFile dex, light_greylist, dark_greylist, blacklist;
378 OpenStream(light_greylist) << "LMain;->imethod(LBadType1;)V" << std::endl;
379 OpenStream(dark_greylist) << "LMain;->imethod(LBadType2;)V" << std::endl;
380 OpenStream(blacklist) << "LMain;->imethod(J)V" << std::endl;
381 auto dex_file = RunHiddenApi(light_greylist, dark_greylist, blacklist, {}, &dex);
382 ASSERT_EQ(HiddenApiAccessFlags::kBlacklist, GetIMethodHiddenFlags(*dex_file));
383 }
384
TEST_F(HiddenApiTest,InstanceMethodTwoListsMatch1)385 TEST_F(HiddenApiTest, InstanceMethodTwoListsMatch1) {
386 ScratchFile dex, light_greylist, dark_greylist, blacklist;
387 OpenStream(light_greylist) << "LMain;->imethod(LBadType1;)V" << std::endl;
388 OpenStream(dark_greylist) << "LMain;->imethod(J)V" << std::endl;
389 OpenStream(blacklist) << "LMain;->imethod(J)V" << std::endl;
390 auto dex_file = RunHiddenApi(light_greylist, dark_greylist, blacklist, {}, &dex);
391 ASSERT_EQ(HiddenApiAccessFlags::kBlacklist, GetIMethodHiddenFlags(*dex_file));
392 }
393
TEST_F(HiddenApiTest,InstanceMethodTwoListsMatch2)394 TEST_F(HiddenApiTest, InstanceMethodTwoListsMatch2) {
395 ScratchFile dex, light_greylist, dark_greylist, blacklist;
396 OpenStream(light_greylist) << "LMain;->imethod(J)V" << std::endl;
397 OpenStream(dark_greylist) << "LMain;->imethod(LBadType2;)V" << std::endl;
398 OpenStream(blacklist) << "LMain;->imethod(J)V" << std::endl;
399 auto dex_file = RunHiddenApi(light_greylist, dark_greylist, blacklist, {}, &dex);
400 ASSERT_EQ(HiddenApiAccessFlags::kBlacklist, GetIMethodHiddenFlags(*dex_file));
401 }
402
TEST_F(HiddenApiTest,InstanceMethodTwoListsMatch3)403 TEST_F(HiddenApiTest, InstanceMethodTwoListsMatch3) {
404 ScratchFile dex, light_greylist, dark_greylist, blacklist;
405 OpenStream(light_greylist) << "LMain;->imethod(J)V" << std::endl;
406 OpenStream(dark_greylist) << "LMain;->imethod(J)V" << std::endl;
407 OpenStream(blacklist) << "LMain;->imethod(LBadType3;)V" << std::endl;
408 auto dex_file = RunHiddenApi(light_greylist, dark_greylist, blacklist, {}, &dex);
409 ASSERT_EQ(HiddenApiAccessFlags::kDarkGreylist, GetIMethodHiddenFlags(*dex_file));
410 }
411
TEST_F(HiddenApiTest,StaticMethodNoMatch)412 TEST_F(HiddenApiTest, StaticMethodNoMatch) {
413 ScratchFile dex, light_greylist, dark_greylist, blacklist;
414 OpenStream(light_greylist) << "LMain;->smethod(LBadType1;)V" << std::endl;
415 OpenStream(dark_greylist) << "LMain;->smethod(LBadType2;)V" << std::endl;
416 OpenStream(blacklist) << "LMain;->smethod(LBadType3;)V" << std::endl;
417 auto dex_file = RunHiddenApi(light_greylist, dark_greylist, blacklist, {}, &dex);
418 ASSERT_EQ(HiddenApiAccessFlags::kWhitelist, GetSMethodHiddenFlags(*dex_file));
419 }
420
TEST_F(HiddenApiTest,StaticMethodLightGreylistMatch)421 TEST_F(HiddenApiTest, StaticMethodLightGreylistMatch) {
422 ScratchFile dex, light_greylist, dark_greylist, blacklist;
423 OpenStream(light_greylist) << "LMain;->smethod(Ljava/lang/Object;)V" << std::endl;
424 OpenStream(dark_greylist) << "LMain;->smethod(LBadType2;)V" << std::endl;
425 OpenStream(blacklist) << "LMain;->smethod(LBadType3;)V" << std::endl;
426 auto dex_file = RunHiddenApi(light_greylist, dark_greylist, blacklist, {}, &dex);
427 ASSERT_EQ(HiddenApiAccessFlags::kLightGreylist, GetSMethodHiddenFlags(*dex_file));
428 }
429
TEST_F(HiddenApiTest,StaticMethodDarkGreylistMatch)430 TEST_F(HiddenApiTest, StaticMethodDarkGreylistMatch) {
431 ScratchFile dex, light_greylist, dark_greylist, blacklist;
432 OpenStream(light_greylist) << "LMain;->smethod(LBadType1;)V" << std::endl;
433 OpenStream(dark_greylist) << "LMain;->smethod(Ljava/lang/Object;)V" << std::endl;
434 OpenStream(blacklist) << "LMain;->smethod(LBadType3;)V" << std::endl;
435 auto dex_file = RunHiddenApi(light_greylist, dark_greylist, blacklist, {}, &dex);
436 ASSERT_EQ(HiddenApiAccessFlags::kDarkGreylist, GetSMethodHiddenFlags(*dex_file));
437 }
438
TEST_F(HiddenApiTest,StaticMethodBlacklistMatch)439 TEST_F(HiddenApiTest, StaticMethodBlacklistMatch) {
440 ScratchFile dex, light_greylist, dark_greylist, blacklist;
441 OpenStream(light_greylist) << "LMain;->smethod(LBadType1;)V" << std::endl;
442 OpenStream(dark_greylist) << "LMain;->smethod(LBadType2;)V" << std::endl;
443 OpenStream(blacklist) << "LMain;->smethod(Ljava/lang/Object;)V" << std::endl;
444 auto dex_file = RunHiddenApi(light_greylist, dark_greylist, blacklist, {}, &dex);
445 ASSERT_EQ(HiddenApiAccessFlags::kBlacklist, GetSMethodHiddenFlags(*dex_file));
446 }
447
TEST_F(HiddenApiTest,StaticMethodTwoListsMatch1)448 TEST_F(HiddenApiTest, StaticMethodTwoListsMatch1) {
449 ScratchFile dex, light_greylist, dark_greylist, blacklist;
450 OpenStream(light_greylist) << "LMain;->smethod(LBadType1;)V" << std::endl;
451 OpenStream(dark_greylist) << "LMain;->smethod(Ljava/lang/Object;)V" << std::endl;
452 OpenStream(blacklist) << "LMain;->smethod(Ljava/lang/Object;)V" << std::endl;
453 auto dex_file = RunHiddenApi(light_greylist, dark_greylist, blacklist, {}, &dex);
454 ASSERT_EQ(HiddenApiAccessFlags::kBlacklist, GetSMethodHiddenFlags(*dex_file));
455 }
456
TEST_F(HiddenApiTest,StaticMethodTwoListsMatch2)457 TEST_F(HiddenApiTest, StaticMethodTwoListsMatch2) {
458 ScratchFile dex, light_greylist, dark_greylist, blacklist;
459 OpenStream(light_greylist) << "LMain;->smethod(Ljava/lang/Object;)V" << std::endl;
460 OpenStream(dark_greylist) << "LMain;->smethod(LBadType2;)V" << std::endl;
461 OpenStream(blacklist) << "LMain;->smethod(Ljava/lang/Object;)V" << std::endl;
462 auto dex_file = RunHiddenApi(light_greylist, dark_greylist, blacklist, {}, &dex);
463 ASSERT_EQ(HiddenApiAccessFlags::kBlacklist, GetSMethodHiddenFlags(*dex_file));
464 }
465
TEST_F(HiddenApiTest,StaticMethodTwoListsMatch3)466 TEST_F(HiddenApiTest, StaticMethodTwoListsMatch3) {
467 ScratchFile dex, light_greylist, dark_greylist, blacklist;
468 OpenStream(light_greylist) << "LMain;->smethod(Ljava/lang/Object;)V" << std::endl;
469 OpenStream(dark_greylist) << "LMain;->smethod(Ljava/lang/Object;)V" << std::endl;
470 OpenStream(blacklist) << "LMain;->smethod(LBadType3;)V" << std::endl;
471 auto dex_file = RunHiddenApi(light_greylist, dark_greylist, blacklist, {}, &dex);
472 ASSERT_EQ(HiddenApiAccessFlags::kDarkGreylist, GetSMethodHiddenFlags(*dex_file));
473 }
474
TEST_F(HiddenApiTest,InstanceNativeMethodNoMatch)475 TEST_F(HiddenApiTest, InstanceNativeMethodNoMatch) {
476 ScratchFile dex, light_greylist, dark_greylist, blacklist;
477 OpenStream(light_greylist) << "LMain;->inmethod(LBadType1;)V" << std::endl;
478 OpenStream(dark_greylist) << "LMain;->inmethod(LBadType2;)V" << std::endl;
479 OpenStream(blacklist) << "LMain;->inmethod(LBadType3;)V" << std::endl;
480 auto dex_file = RunHiddenApi(light_greylist, dark_greylist, blacklist, {}, &dex);
481 ASSERT_EQ(HiddenApiAccessFlags::kWhitelist, GetINMethodHiddenFlags(*dex_file));
482 }
483
TEST_F(HiddenApiTest,InstanceNativeMethodLightGreylistMatch)484 TEST_F(HiddenApiTest, InstanceNativeMethodLightGreylistMatch) {
485 ScratchFile dex, light_greylist, dark_greylist, blacklist;
486 OpenStream(light_greylist) << "LMain;->inmethod(C)V" << std::endl;
487 OpenStream(dark_greylist) << "LMain;->inmethod(LBadType2;)V" << std::endl;
488 OpenStream(blacklist) << "LMain;->inmethod(LBadType3;)V" << std::endl;
489 auto dex_file = RunHiddenApi(light_greylist, dark_greylist, blacklist, {}, &dex);
490 ASSERT_EQ(HiddenApiAccessFlags::kLightGreylist, GetINMethodHiddenFlags(*dex_file));
491 }
492
TEST_F(HiddenApiTest,InstanceNativeMethodDarkGreylistMatch)493 TEST_F(HiddenApiTest, InstanceNativeMethodDarkGreylistMatch) {
494 ScratchFile dex, light_greylist, dark_greylist, blacklist;
495 OpenStream(light_greylist) << "LMain;->inmethod(LBadType1;)V" << std::endl;
496 OpenStream(dark_greylist) << "LMain;->inmethod(C)V" << std::endl;
497 OpenStream(blacklist) << "LMain;->inmethod(LBadType3;)V" << std::endl;
498 auto dex_file = RunHiddenApi(light_greylist, dark_greylist, blacklist, {}, &dex);
499 ASSERT_EQ(HiddenApiAccessFlags::kDarkGreylist, GetINMethodHiddenFlags(*dex_file));
500 }
501
TEST_F(HiddenApiTest,InstanceNativeMethodBlacklistMatch)502 TEST_F(HiddenApiTest, InstanceNativeMethodBlacklistMatch) {
503 ScratchFile dex, light_greylist, dark_greylist, blacklist;
504 OpenStream(light_greylist) << "LMain;->inmethod(LBadType1;)V" << std::endl;
505 OpenStream(dark_greylist) << "LMain;->inmethod(LBadType2;)V" << std::endl;
506 OpenStream(blacklist) << "LMain;->inmethod(C)V" << std::endl;
507 auto dex_file = RunHiddenApi(light_greylist, dark_greylist, blacklist, {}, &dex);
508 ASSERT_EQ(HiddenApiAccessFlags::kBlacklist, GetINMethodHiddenFlags(*dex_file));
509 }
510
TEST_F(HiddenApiTest,InstanceNativeMethodTwoListsMatch1)511 TEST_F(HiddenApiTest, InstanceNativeMethodTwoListsMatch1) {
512 ScratchFile dex, light_greylist, dark_greylist, blacklist;
513 OpenStream(light_greylist) << "LMain;->inmethod(LBadType1;)V" << std::endl;
514 OpenStream(dark_greylist) << "LMain;->inmethod(C)V" << std::endl;
515 OpenStream(blacklist) << "LMain;->inmethod(C)V" << std::endl;
516 auto dex_file = RunHiddenApi(light_greylist, dark_greylist, blacklist, {}, &dex);
517 ASSERT_EQ(HiddenApiAccessFlags::kBlacklist, GetINMethodHiddenFlags(*dex_file));
518 }
519
TEST_F(HiddenApiTest,InstanceNativeMethodTwoListsMatch2)520 TEST_F(HiddenApiTest, InstanceNativeMethodTwoListsMatch2) {
521 ScratchFile dex, light_greylist, dark_greylist, blacklist;
522 OpenStream(light_greylist) << "LMain;->inmethod(C)V" << std::endl;
523 OpenStream(dark_greylist) << "LMain;->inmethod(LBadType2;)V" << std::endl;
524 OpenStream(blacklist) << "LMain;->inmethod(C)V" << std::endl;
525 auto dex_file = RunHiddenApi(light_greylist, dark_greylist, blacklist, {}, &dex);
526 ASSERT_EQ(HiddenApiAccessFlags::kBlacklist, GetINMethodHiddenFlags(*dex_file));
527 }
528
TEST_F(HiddenApiTest,InstanceNativeMethodTwoListsMatch3)529 TEST_F(HiddenApiTest, InstanceNativeMethodTwoListsMatch3) {
530 ScratchFile dex, light_greylist, dark_greylist, blacklist;
531 OpenStream(light_greylist) << "LMain;->inmethod(C)V" << std::endl;
532 OpenStream(dark_greylist) << "LMain;->inmethod(C)V" << std::endl;
533 OpenStream(blacklist) << "LMain;->inmethod(LBadType3;)V" << std::endl;
534 auto dex_file = RunHiddenApi(light_greylist, dark_greylist, blacklist, {}, &dex);
535 ASSERT_EQ(HiddenApiAccessFlags::kDarkGreylist, GetINMethodHiddenFlags(*dex_file));
536 }
537
TEST_F(HiddenApiTest,StaticNativeMethodNoMatch)538 TEST_F(HiddenApiTest, StaticNativeMethodNoMatch) {
539 ScratchFile dex, light_greylist, dark_greylist, blacklist;
540 OpenStream(light_greylist) << "LMain;->snmethod(LBadType1;)V" << std::endl;
541 OpenStream(dark_greylist) << "LMain;->snmethod(LBadType2;)V" << std::endl;
542 OpenStream(blacklist) << "LMain;->snmethod(LBadType3;)V" << std::endl;
543 auto dex_file = RunHiddenApi(light_greylist, dark_greylist, blacklist, {}, &dex);
544 ASSERT_EQ(HiddenApiAccessFlags::kWhitelist, GetSNMethodHiddenFlags(*dex_file));
545 }
546
TEST_F(HiddenApiTest,StaticNativeMethodLightGreylistMatch)547 TEST_F(HiddenApiTest, StaticNativeMethodLightGreylistMatch) {
548 ScratchFile dex, light_greylist, dark_greylist, blacklist;
549 OpenStream(light_greylist) << "LMain;->snmethod(Ljava/lang/Integer;)V" << std::endl;
550 OpenStream(dark_greylist) << "LMain;->snmethod(LBadType2;)V" << std::endl;
551 OpenStream(blacklist) << "LMain;->snmethod(LBadType3;)V" << std::endl;
552 auto dex_file = RunHiddenApi(light_greylist, dark_greylist, blacklist, {}, &dex);
553 ASSERT_EQ(HiddenApiAccessFlags::kLightGreylist, GetSNMethodHiddenFlags(*dex_file));
554 }
555
TEST_F(HiddenApiTest,StaticNativeMethodDarkGreylistMatch)556 TEST_F(HiddenApiTest, StaticNativeMethodDarkGreylistMatch) {
557 ScratchFile dex, light_greylist, dark_greylist, blacklist;
558 OpenStream(light_greylist) << "LMain;->snmethod(LBadType1;)V" << std::endl;
559 OpenStream(dark_greylist) << "LMain;->snmethod(Ljava/lang/Integer;)V" << std::endl;
560 OpenStream(blacklist) << "LMain;->snmethod(LBadType3;)V" << std::endl;
561 auto dex_file = RunHiddenApi(light_greylist, dark_greylist, blacklist, {}, &dex);
562 ASSERT_EQ(HiddenApiAccessFlags::kDarkGreylist, GetSNMethodHiddenFlags(*dex_file));
563 }
564
TEST_F(HiddenApiTest,StaticNativeMethodBlacklistMatch)565 TEST_F(HiddenApiTest, StaticNativeMethodBlacklistMatch) {
566 ScratchFile dex, light_greylist, dark_greylist, blacklist;
567 OpenStream(light_greylist) << "LMain;->snmethod(LBadType1;)V" << std::endl;
568 OpenStream(dark_greylist) << "LMain;->snmethod(LBadType2;)V" << std::endl;
569 OpenStream(blacklist) << "LMain;->snmethod(Ljava/lang/Integer;)V" << std::endl;
570 auto dex_file = RunHiddenApi(light_greylist, dark_greylist, blacklist, {}, &dex);
571 ASSERT_EQ(HiddenApiAccessFlags::kBlacklist, GetSNMethodHiddenFlags(*dex_file));
572 }
573
TEST_F(HiddenApiTest,StaticNativeMethodTwoListsMatch1)574 TEST_F(HiddenApiTest, StaticNativeMethodTwoListsMatch1) {
575 ScratchFile dex, light_greylist, dark_greylist, blacklist;
576 OpenStream(light_greylist) << "LMain;->snmethod(LBadType1;)V" << std::endl;
577 OpenStream(dark_greylist) << "LMain;->snmethod(Ljava/lang/Integer;)V" << std::endl;
578 OpenStream(blacklist) << "LMain;->snmethod(Ljava/lang/Integer;)V" << std::endl;
579 auto dex_file = RunHiddenApi(light_greylist, dark_greylist, blacklist, {}, &dex);
580 ASSERT_EQ(HiddenApiAccessFlags::kBlacklist, GetSNMethodHiddenFlags(*dex_file));
581 }
582
TEST_F(HiddenApiTest,StaticNativeMethodTwoListsMatch2)583 TEST_F(HiddenApiTest, StaticNativeMethodTwoListsMatch2) {
584 ScratchFile dex, light_greylist, dark_greylist, blacklist;
585 OpenStream(light_greylist) << "LMain;->snmethod(Ljava/lang/Integer;)V" << std::endl;
586 OpenStream(dark_greylist) << "LMain;->snmethod(LBadType2;)V" << std::endl;
587 OpenStream(blacklist) << "LMain;->snmethod(Ljava/lang/Integer;)V" << std::endl;
588 auto dex_file = RunHiddenApi(light_greylist, dark_greylist, blacklist, {}, &dex);
589 ASSERT_EQ(HiddenApiAccessFlags::kBlacklist, GetSNMethodHiddenFlags(*dex_file));
590 }
591
TEST_F(HiddenApiTest,StaticNativeMethodTwoListsMatch3)592 TEST_F(HiddenApiTest, StaticNativeMethodTwoListsMatch3) {
593 ScratchFile dex, light_greylist, dark_greylist, blacklist;
594 OpenStream(light_greylist) << "LMain;->snmethod(Ljava/lang/Integer;)V" << std::endl;
595 OpenStream(dark_greylist) << "LMain;->snmethod(Ljava/lang/Integer;)V" << std::endl;
596 OpenStream(blacklist) << "LMain;->snmethod(LBadType3;)V" << std::endl;
597 auto dex_file = RunHiddenApi(light_greylist, dark_greylist, blacklist, {}, &dex);
598 ASSERT_EQ(HiddenApiAccessFlags::kDarkGreylist, GetSNMethodHiddenFlags(*dex_file));
599 }
600
601 } // namespace art
602