1 /* 2 * Copyright (C) 2018 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 import java.lang.reflect.InvocationTargetException; 18 19 public class Linking { 20 public static boolean canAccess(String className, boolean takesParameter) throws Exception { 21 try { 22 Class<?> c = Class.forName(className); 23 if (takesParameter) { 24 c.getDeclaredMethod("access", Integer.TYPE).invoke(null, 42); 25 } else { 26 c.getDeclaredMethod("access").invoke(null); 27 } 28 return true; 29 } catch (InvocationTargetException ex) { 30 if (ex.getCause() instanceof NoSuchFieldError || ex.getCause() instanceof NoSuchMethodError) { 31 return false; 32 } else { 33 throw ex; 34 } 35 } 36 } 37 } 38 39 // INSTANCE FIELD GET 40 41 class LinkFieldGetWhitelist { 42 public static int access() { 43 return new ParentClass().fieldPublicWhitelist; 44 } 45 } 46 47 class LinkFieldGetLightGreylist { 48 public static int access() { 49 return new ParentClass().fieldPublicLightGreylist; 50 } 51 } 52 53 class LinkFieldGetDarkGreylist { 54 public static int access() { 55 return new ParentClass().fieldPublicDarkGreylist; 56 } 57 } 58 59 class LinkFieldGetBlacklist { 60 public static int access() { 61 return new ParentClass().fieldPublicBlacklist; 62 } 63 } 64 65 // INSTANCE FIELD SET 66 67 class LinkFieldSetWhitelist { 68 public static void access(int x) { 69 // Need to use a different field from the getter to bypass DexCache. 70 new ParentClass().fieldPublicWhitelistB = x; 71 } 72 } 73 74 class LinkFieldSetLightGreylist { 75 public static void access(int x) { 76 // Need to use a different field from the getter to bypass DexCache. 77 new ParentClass().fieldPublicLightGreylistB = x; 78 } 79 } 80 81 class LinkFieldSetDarkGreylist { 82 public static void access(int x) { 83 // Need to use a different field from the getter to bypass DexCache. 84 new ParentClass().fieldPublicDarkGreylistB = x; 85 } 86 } 87 88 class LinkFieldSetBlacklist { 89 public static void access(int x) { 90 // Need to use a different field from the getter to bypass DexCache. 91 new ParentClass().fieldPublicBlacklistB = x; 92 } 93 } 94 95 // STATIC FIELD GET 96 97 class LinkFieldGetStaticWhitelist { 98 public static int access() { 99 return ParentClass.fieldPublicStaticWhitelist; 100 } 101 } 102 103 class LinkFieldGetStaticLightGreylist { 104 public static int access() { 105 return ParentClass.fieldPublicStaticLightGreylist; 106 } 107 } 108 109 class LinkFieldGetStaticDarkGreylist { 110 public static int access() { 111 return ParentClass.fieldPublicStaticDarkGreylist; 112 } 113 } 114 115 class LinkFieldGetStaticBlacklist { 116 public static int access() { 117 return ParentClass.fieldPublicStaticBlacklist; 118 } 119 } 120 121 // STATIC FIELD SET 122 123 class LinkFieldSetStaticWhitelist { 124 public static void access(int x) { 125 // Need to use a different field from the getter to bypass DexCache. 126 ParentClass.fieldPublicStaticWhitelistB = x; 127 } 128 } 129 130 class LinkFieldSetStaticLightGreylist { 131 public static void access(int x) { 132 // Need to use a different field from the getter to bypass DexCache. 133 ParentClass.fieldPublicStaticLightGreylistB = x; 134 } 135 } 136 137 class LinkFieldSetStaticDarkGreylist { 138 public static void access(int x) { 139 // Need to use a different field from the getter to bypass DexCache. 140 ParentClass.fieldPublicStaticDarkGreylistB = x; 141 } 142 } 143 144 class LinkFieldSetStaticBlacklist { 145 public static void access(int x) { 146 // Need to use a different field from the getter to bypass DexCache. 147 ParentClass.fieldPublicStaticBlacklistB = x; 148 } 149 } 150 151 // INVOKE INSTANCE METHOD 152 153 class LinkMethodWhitelist { 154 public static int access() { 155 return new ParentClass().methodPublicWhitelist(); 156 } 157 } 158 159 class LinkMethodLightGreylist { 160 public static int access() { 161 return new ParentClass().methodPublicLightGreylist(); 162 } 163 } 164 165 class LinkMethodDarkGreylist { 166 public static int access() { 167 return new ParentClass().methodPublicDarkGreylist(); 168 } 169 } 170 171 class LinkMethodBlacklist { 172 public static int access() { 173 return new ParentClass().methodPublicBlacklist(); 174 } 175 } 176 177 // INVOKE INSTANCE INTERFACE METHOD 178 179 class LinkMethodInterfaceWhitelist { 180 public static int access() { 181 return DummyClass.getInterfaceInstance().methodPublicWhitelist(); 182 } 183 } 184 185 class LinkMethodInterfaceLightGreylist { 186 public static int access() { 187 return DummyClass.getInterfaceInstance().methodPublicLightGreylist(); 188 } 189 } 190 191 class LinkMethodInterfaceDarkGreylist { 192 public static int access() { 193 return DummyClass.getInterfaceInstance().methodPublicDarkGreylist(); 194 } 195 } 196 197 class LinkMethodInterfaceBlacklist { 198 public static int access() { 199 return DummyClass.getInterfaceInstance().methodPublicBlacklist(); 200 } 201 } 202 203 // INVOKE STATIC METHOD 204 205 class LinkMethodStaticWhitelist { 206 public static int access() { 207 return ParentClass.methodPublicStaticWhitelist(); 208 } 209 } 210 211 class LinkMethodStaticLightGreylist { 212 public static int access() { 213 return ParentClass.methodPublicStaticLightGreylist(); 214 } 215 } 216 217 class LinkMethodStaticDarkGreylist { 218 public static int access() { 219 return ParentClass.methodPublicStaticDarkGreylist(); 220 } 221 } 222 223 class LinkMethodStaticBlacklist { 224 public static int access() { 225 return ParentClass.methodPublicStaticBlacklist(); 226 } 227 } 228 229 // INVOKE INTERFACE STATIC METHOD 230 231 class LinkMethodInterfaceStaticWhitelist { 232 public static int access() { 233 return ParentInterface.methodPublicStaticWhitelist(); 234 } 235 } 236 237 class LinkMethodInterfaceStaticLightGreylist { 238 public static int access() { 239 return ParentInterface.methodPublicStaticLightGreylist(); 240 } 241 } 242 243 class LinkMethodInterfaceStaticDarkGreylist { 244 public static int access() { 245 return ParentInterface.methodPublicStaticDarkGreylist(); 246 } 247 } 248 249 class LinkMethodInterfaceStaticBlacklist { 250 public static int access() { 251 return ParentInterface.methodPublicStaticBlacklist(); 252 } 253 } 254