1*795d594fSAndroid Build Coastguard Worker /* 2*795d594fSAndroid Build Coastguard Worker * Copyright (C) 2018 The Android Open Source Project 3*795d594fSAndroid Build Coastguard Worker * 4*795d594fSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*795d594fSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*795d594fSAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*795d594fSAndroid Build Coastguard Worker * 8*795d594fSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*795d594fSAndroid Build Coastguard Worker * 10*795d594fSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*795d594fSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*795d594fSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*795d594fSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*795d594fSAndroid Build Coastguard Worker * limitations under the License. 15*795d594fSAndroid Build Coastguard Worker */ 16*795d594fSAndroid Build Coastguard Worker 17*795d594fSAndroid Build Coastguard Worker import java.io.File; 18*795d594fSAndroid Build Coastguard Worker import java.lang.reflect.Method; 19*795d594fSAndroid Build Coastguard Worker import java.util.Base64; 20*795d594fSAndroid Build Coastguard Worker 21*795d594fSAndroid Build Coastguard Worker public class Main { main(String[] args)22*795d594fSAndroid Build Coastguard Worker public static void main(String[] args) throws ClassNotFoundException { 23*795d594fSAndroid Build Coastguard Worker System.loadLibrary(args[0]); 24*795d594fSAndroid Build Coastguard Worker 25*795d594fSAndroid Build Coastguard Worker // Run the initialization routine. This will enable hidden API checks in 26*795d594fSAndroid Build Coastguard Worker // the runtime, in case they are not enabled by default. 27*795d594fSAndroid Build Coastguard Worker init(); 28*795d594fSAndroid Build Coastguard Worker 29*795d594fSAndroid Build Coastguard Worker // Load the '-ex' APK and attach it to the boot class path. 30*795d594fSAndroid Build Coastguard Worker appendToBootClassLoader(DEX_EXTRA, /* isCorePlatform */ false); 31*795d594fSAndroid Build Coastguard Worker 32*795d594fSAndroid Build Coastguard Worker // Find the test class in boot class loader and verify that its members are hidden. 33*795d594fSAndroid Build Coastguard Worker Class<?> klass = Class.forName("art.Test999", true, BOOT_CLASS_LOADER); 34*795d594fSAndroid Build Coastguard Worker assertFieldIsHidden(klass, "before redefinition"); 35*795d594fSAndroid Build Coastguard Worker assertMethodIsHidden(klass, "before redefinition"); 36*795d594fSAndroid Build Coastguard Worker 37*795d594fSAndroid Build Coastguard Worker // Redefine the class using JVMTI. Use dex file without hiddenapi flags. 38*795d594fSAndroid Build Coastguard Worker art.Redefinition.setTestConfiguration(art.Redefinition.Config.COMMON_REDEFINE); 39*795d594fSAndroid Build Coastguard Worker art.Redefinition.doCommonClassRedefinition(klass, CLASS_BYTES, DEX_BYTES); 40*795d594fSAndroid Build Coastguard Worker 41*795d594fSAndroid Build Coastguard Worker // Verify that the class members are still hidden. 42*795d594fSAndroid Build Coastguard Worker assertFieldIsHidden(klass, "after first redefinition"); 43*795d594fSAndroid Build Coastguard Worker assertMethodIsHidden(klass, "after first redefinition"); 44*795d594fSAndroid Build Coastguard Worker } 45*795d594fSAndroid Build Coastguard Worker assertMethodIsHidden(Class<?> klass, String msg)46*795d594fSAndroid Build Coastguard Worker private static void assertMethodIsHidden(Class<?> klass, String msg) { 47*795d594fSAndroid Build Coastguard Worker try { 48*795d594fSAndroid Build Coastguard Worker klass.getDeclaredMethod("foo"); 49*795d594fSAndroid Build Coastguard Worker // Unexpected. Should have thrown NoSuchMethodException. 50*795d594fSAndroid Build Coastguard Worker throw new RuntimeException("Method should not be accessible " + msg); 51*795d594fSAndroid Build Coastguard Worker } catch (NoSuchMethodException ex) { 52*795d594fSAndroid Build Coastguard Worker } 53*795d594fSAndroid Build Coastguard Worker } 54*795d594fSAndroid Build Coastguard Worker assertFieldIsHidden(Class<?> klass, String msg)55*795d594fSAndroid Build Coastguard Worker private static void assertFieldIsHidden(Class<?> klass, String msg) { 56*795d594fSAndroid Build Coastguard Worker try { 57*795d594fSAndroid Build Coastguard Worker klass.getDeclaredField("bar"); 58*795d594fSAndroid Build Coastguard Worker // Unexpected. Should have thrown NoSuchFieldException. 59*795d594fSAndroid Build Coastguard Worker throw new RuntimeException("Field should not be accessible " + msg); 60*795d594fSAndroid Build Coastguard Worker } catch (NoSuchFieldException ex) { 61*795d594fSAndroid Build Coastguard Worker } 62*795d594fSAndroid Build Coastguard Worker } 63*795d594fSAndroid Build Coastguard Worker 64*795d594fSAndroid Build Coastguard Worker private static final String DEX_EXTRA = new File( 65*795d594fSAndroid Build Coastguard Worker System.getenv("DEX_LOCATION"), "999-redefine-hiddenapi-ex.jar").getAbsolutePath(); 66*795d594fSAndroid Build Coastguard Worker 67*795d594fSAndroid Build Coastguard Worker private static ClassLoader BOOT_CLASS_LOADER = Object.class.getClassLoader(); 68*795d594fSAndroid Build Coastguard Worker 69*795d594fSAndroid Build Coastguard Worker // Native functions. Note that these are implemented in 674-hiddenapi/hiddenapi.cc. appendToBootClassLoader(String dexPath, boolean isCorePlatform)70*795d594fSAndroid Build Coastguard Worker private static native void appendToBootClassLoader(String dexPath, boolean isCorePlatform); init()71*795d594fSAndroid Build Coastguard Worker private static native void init(); 72*795d594fSAndroid Build Coastguard Worker 73*795d594fSAndroid Build Coastguard Worker /** 74*795d594fSAndroid Build Coastguard Worker * base64 encoded class/dex file for 75*795d594fSAndroid Build Coastguard Worker * 76*795d594fSAndroid Build Coastguard Worker * public class Test999 { 77*795d594fSAndroid Build Coastguard Worker * public void foo() { 78*795d594fSAndroid Build Coastguard Worker * System.out.println("Goodbye"); 79*795d594fSAndroid Build Coastguard Worker * } 80*795d594fSAndroid Build Coastguard Worker * 81*795d594fSAndroid Build Coastguard Worker * public int bar = 64; 82*795d594fSAndroid Build Coastguard Worker * } 83*795d594fSAndroid Build Coastguard Worker */ 84*795d594fSAndroid Build Coastguard Worker private static final byte[] CLASS_BYTES = Base64.getDecoder().decode( 85*795d594fSAndroid Build Coastguard Worker "yv66vgAAADUAIAoABwARCQAGABIJABMAFAgAFQoAFgAXBwAYBwAZAQADYmFyAQABSQEABjxpbml0" + 86*795d594fSAndroid Build Coastguard Worker "PgEAAygpVgEABENvZGUBAA9MaW5lTnVtYmVyVGFibGUBAANmb28BAApTb3VyY2VGaWxlAQAMVGVz" + 87*795d594fSAndroid Build Coastguard Worker "dDk5OS5qYXZhDAAKAAsMAAgACQcAGgwAGwAcAQAHR29vZGJ5ZQcAHQwAHgAfAQALYXJ0L1Rlc3Q5" + 88*795d594fSAndroid Build Coastguard Worker "OTkBABBqYXZhL2xhbmcvT2JqZWN0AQAQamF2YS9sYW5nL1N5c3RlbQEAA291dAEAFUxqYXZhL2lv" + 89*795d594fSAndroid Build Coastguard Worker "L1ByaW50U3RyZWFtOwEAE2phdmEvaW8vUHJpbnRTdHJlYW0BAAdwcmludGxuAQAVKExqYXZhL2xh" + 90*795d594fSAndroid Build Coastguard Worker "bmcvU3RyaW5nOylWACEABgAHAAAAAQABAAgACQAAAAIAAQAKAAsAAQAMAAAAJwACAAEAAAALKrcA" + 91*795d594fSAndroid Build Coastguard Worker "ASoQQLUAArEAAAABAA0AAAAKAAIAAAATAAQAGAABAA4ACwABAAwAAAAlAAIAAQAAAAmyAAMSBLYA" + 92*795d594fSAndroid Build Coastguard Worker "BbEAAAABAA0AAAAKAAIAAAAVAAgAFgABAA8AAAACABA="); 93*795d594fSAndroid Build Coastguard Worker private static final byte[] DEX_BYTES = Base64.getDecoder().decode( 94*795d594fSAndroid Build Coastguard Worker "ZGV4CjAzNQDlfmgFfKulToQpDF+P4dsgeOkgfzzH+5lgAwAAcAAAAHhWNBIAAAAAAAAAALQCAAAQ" + 95*795d594fSAndroid Build Coastguard Worker "AAAAcAAAAAcAAACwAAAAAgAAAMwAAAACAAAA5AAAAAQAAAD0AAAAAQAAABQBAAAsAgAANAEAAIYB" + 96*795d594fSAndroid Build Coastguard Worker "AACOAQAAlwEAAJoBAACpAQAAwAEAANQBAADoAQAA/AEAAAoCAAANAgAAEQIAABYCAAAbAgAAIAIA" + 97*795d594fSAndroid Build Coastguard Worker "ACkCAAACAAAAAwAAAAQAAAAFAAAABgAAAAcAAAAJAAAACQAAAAYAAAAAAAAACgAAAAYAAACAAQAA" + 98*795d594fSAndroid Build Coastguard Worker "AQAAAAsAAAAFAAIADQAAAAEAAAAAAAAAAQAAAAwAAAACAAEADgAAAAMAAAAAAAAAAQAAAAEAAAAD" + 99*795d594fSAndroid Build Coastguard Worker "AAAAAAAAAAgAAAAAAAAAoAIAAAAAAAACAAEAAQAAAHQBAAAIAAAAcBADAAEAEwBAAFkQAAAOAAMA" + 100*795d594fSAndroid Build Coastguard Worker "AQACAAAAeQEAAAgAAABiAAEAGgEBAG4gAgAQAA4AEwAOQAAVAA54AAAAAQAAAAQABjxpbml0PgAH" + 101*795d594fSAndroid Build Coastguard Worker "R29vZGJ5ZQABSQANTGFydC9UZXN0OTk5OwAVTGphdmEvaW8vUHJpbnRTdHJlYW07ABJMamF2YS9s" + 102*795d594fSAndroid Build Coastguard Worker "YW5nL09iamVjdDsAEkxqYXZhL2xhbmcvU3RyaW5nOwASTGphdmEvbGFuZy9TeXN0ZW07AAxUZXN0" + 103*795d594fSAndroid Build Coastguard Worker "OTk5LmphdmEAAVYAAlZMAANiYXIAA2ZvbwADb3V0AAdwcmludGxuAHV+fkQ4eyJjb21waWxhdGlv" + 104*795d594fSAndroid Build Coastguard Worker "bi1tb2RlIjoiZGVidWciLCJtaW4tYXBpIjoxLCJzaGEtMSI6ImQyMmFiNGYxOWI3NTYxNDQ3NTI4" + 105*795d594fSAndroid Build Coastguard Worker "NTdjYTg2YjJjZWU0ZGQ5Y2ExNjYiLCJ2ZXJzaW9uIjoiMS40LjktZGV2In0AAAEBAQABAIGABLQC" + 106*795d594fSAndroid Build Coastguard Worker "AQHUAgAAAAAOAAAAAAAAAAEAAAAAAAAAAQAAABAAAABwAAAAAgAAAAcAAACwAAAAAwAAAAIAAADM" + 107*795d594fSAndroid Build Coastguard Worker "AAAABAAAAAIAAADkAAAABQAAAAQAAAD0AAAABgAAAAEAAAAUAQAAASAAAAIAAAA0AQAAAyAAAAIA" + 108*795d594fSAndroid Build Coastguard Worker "AAB0AQAAARAAAAEAAACAAQAAAiAAABAAAACGAQAAACAAAAEAAACgAgAAAxAAAAEAAACwAgAAABAA" + 109*795d594fSAndroid Build Coastguard Worker "AAEAAAC0AgAA"); 110*795d594fSAndroid Build Coastguard Worker } 111