• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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