1 /* 2 * Copyright (C) 2020 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 package art; 18 19 import java.util.Base64; 20 21 public class Test2036 { 22 public static class Transform { Transform()23 public Transform() {} 24 } 25 26 public static class SubTransform extends Transform { SubTransform()27 public SubTransform() {} 28 FooBar()29 public static int FooBar() { 30 return 1337; 31 } 32 33 public int foo = 42; 34 public static double STATIC_FOO = 3.14d; 35 } 36 37 public static class SubSubTransform extends SubTransform { SubSubTransform()38 public SubSubTransform() {} 39 } 40 41 public static class SubSubSubTransform extends SubSubTransform { SubSubSubTransform()42 public SubSubSubTransform() {} 43 getFoo()44 public int getFoo() { 45 return this.foo; 46 } 47 } 48 /* 49 * base64 encoded class/dex file for 50 * Base64 generated using: 51 * % javac Test2036.java 52 * % d8 Test2035\$Transform.class 53 * % base64 classes.dex| sed 's:^:":' | sed 's:$:" +:' 54 * 55 * package art; 56 * public static class Transform { 57 * public Transform() {} 58 * public int bar; 59 * } 60 */ 61 private static final byte[] DEX_BYTES = 62 Base64.getDecoder() 63 .decode( 64 "ZGV4CjAzNQAZlSz5hewOnpRnplr0AnEqh8+AKNc2qhp0AwAAcAAAAHhWNBIAAAAAAAAAALwCAAAP" 65 + "AAAAcAAAAAcAAACsAAAAAQAAAMgAAAABAAAA1AAAAAIAAADcAAAAAQAAAOwAAABoAgAADAEAACgB" 66 + "AAAwAQAAMwEAAE0BAABdAQAAgQEAAKEBAAC1AQAAxAEAAM8BAADSAQAA3wEAAOQBAADqAQAA8QEA" 67 + "AAEAAAACAAAAAwAAAAQAAAAFAAAABgAAAAkAAAAJAAAABgAAAAAAAAABAAAACwAAAAEAAAAAAAAA" 68 + "BQAAAAAAAAABAAAAAQAAAAUAAAAAAAAABwAAAKwCAACOAgAAAAAAAAEAAQABAAAAJAEAAAQAAABw" 69 + "EAEAAAAOABgADgAGPGluaXQ+AAFJABhMYXJ0L1Rlc3QyMDM2JFRyYW5zZm9ybTsADkxhcnQvVGVz" 70 + "dDIwMzY7ACJMZGFsdmlrL2Fubm90YXRpb24vRW5jbG9zaW5nQ2xhc3M7AB5MZGFsdmlrL2Fubm90" 71 + "YXRpb24vSW5uZXJDbGFzczsAEkxqYXZhL2xhbmcvT2JqZWN0OwANVGVzdDIwMzYuamF2YQAJVHJh" 72 + "bnNmb3JtAAFWAAthY2Nlc3NGbGFncwADYmFyAARuYW1lAAV2YWx1ZQCLAX5+RDh7ImNvbXBpbGF0" 73 + "aW9uLW1vZGUiOiJkZWJ1ZyIsImhhcy1jaGVja3N1bXMiOmZhbHNlLCJtaW4tYXBpIjoxLCJzaGEt" 74 + "MSI6IjJkMDE0MjEyNjVlMjUxMWM5MGUxZTY2NTU0NWEzMzliM2M5OWMwYWYiLCJ2ZXJzaW9uIjoi" 75 + "Mi4yLjMtZGV2In0AAgMBDRgCAgQCCgQJDBcIAAEBAAABAIGABIwCAAAAAAAAAgAAAH8CAACFAgAA" 76 + "oAIAAAAAAAAAAAAAAAAAAA8AAAAAAAAAAQAAAAAAAAABAAAADwAAAHAAAAACAAAABwAAAKwAAAAD" 77 + "AAAAAQAAAMgAAAAEAAAAAQAAANQAAAAFAAAAAgAAANwAAAAGAAAAAQAAAOwAAAABIAAAAQAAAAwB" 78 + "AAADIAAAAQAAACQBAAACIAAADwAAACgBAAAEIAAAAgAAAH8CAAAAIAAAAQAAAI4CAAADEAAAAgAA" 79 + "AJwCAAAGIAAAAQAAAKwCAAAAEAAAAQAAALwCAAA="); 80 /* 81 * base64 encoded class/dex file for 82 * Base64 generated using: 83 * % javac Test2036.java 84 * % d8 Test2035\$SubSubTransform.class 85 * % base64 classes.dex| sed 's:^:":' | sed 's:$:" +:' 86 * 87 * package art; 88 * public static class SubSubTransform extends SubTransform { 89 * public SubTransform() {} 90 * public static int FooBar() { return 0xDEADBEEF; } 91 * public int foo; 92 * public static double STATIC_FOO; 93 * } 94 */ 95 private static final byte[] DEX_BYTES_SUB_SUB = 96 Base64.getDecoder() 97 .decode( 98 "ZGV4CjAzNQATpeOoP5d8wSzfcaS99KwXbb1DsEne1tDsAwAAcAAAAHhWNBIAAAAAAAAAADQDAAAS" 99 + "AAAAcAAAAAgAAAC4AAAAAgAAANgAAAACAAAA8AAAAAMAAAAAAQAAAQAAABgBAAC0AgAAOAEAAHAB" 100 + "AAB4AQAAewEAAIMBAACGAQAApgEAAMMBAADTAQAA9wEAABcCAAAjAgAANAIAAEMCAABGAgAAUwIA" 101 + "AFgCAABeAgAAZQIAAAEAAAADAAAABAAAAAUAAAAGAAAABwAAAAgAAAAMAAAAAwAAAAEAAAAAAAAA" 102 + "DAAAAAcAAAAAAAAAAgAAAAkAAAACAAEADgAAAAIAAQAAAAAAAgAAAAIAAAADAAEAAAAAAAIAAAAB" 103 + "AAAAAwAAAAAAAAALAAAAJAMAAAIDAAAAAAAAAQAAAAAAAABoAQAABAAAABQA776t3g8AAQABAAEA" 104 + "AABsAQAABAAAAHAQAgAAAA4AIQAOACAADgAGPGluaXQ+AAFEAAZGb29CYXIAAUkAHkxhcnQvVGVz" 105 + "dDIwMzYkU3ViU3ViVHJhbnNmb3JtOwAbTGFydC9UZXN0MjAzNiRTdWJUcmFuc2Zvcm07AA5MYXJ0" 106 + "L1Rlc3QyMDM2OwAiTGRhbHZpay9hbm5vdGF0aW9uL0VuY2xvc2luZ0NsYXNzOwAeTGRhbHZpay9h" 107 + "bm5vdGF0aW9uL0lubmVyQ2xhc3M7AApTVEFUSUNfRk9PAA9TdWJTdWJUcmFuc2Zvcm0ADVRlc3Qy" 108 + "MDM2LmphdmEAAVYAC2FjY2Vzc0ZsYWdzAANmb28ABG5hbWUABXZhbHVlAIsBfn5EOHsiY29tcGls" 109 + "YXRpb24tbW9kZSI6ImRlYnVnIiwiaGFzLWNoZWNrc3VtcyI6ZmFsc2UsIm1pbi1hcGkiOjEsInNo" 110 + "YS0xIjoiMmQwMTQyMTI2NWUyNTExYzkwZTFlNjY1NTQ1YTMzOWIzYzk5YzBhZiIsInZlcnNpb24i" 111 + "OiIyLjIuMy1kZXYifQACBQEQGAQCBgINBAkPFwoBAQIAAAkBAQCBgATQAgEJuAIAAAAAAgAAAPMC" 112 + "AAD5AgAAGAMAAAAAAAAAAAAAAAAAAA8AAAAAAAAAAQAAAAAAAAABAAAAEgAAAHAAAAACAAAACAAA" 113 + "ALgAAAADAAAAAgAAANgAAAAEAAAAAgAAAPAAAAAFAAAAAwAAAAABAAAGAAAAAQAAABgBAAABIAAA" 114 + "AgAAADgBAAADIAAAAgAAAGgBAAACIAAAEgAAAHABAAAEIAAAAgAAAPMCAAAAIAAAAQAAAAIDAAAD" 115 + "EAAAAgAAABQDAAAGIAAAAQAAACQDAAAAEAAAAQAAADQDAAA="); 116 run()117 public static void run() throws Exception { 118 Redefinition.setTestConfiguration(Redefinition.Config.COMMON_REDEFINE); 119 doTest(); 120 } 121 doTest()122 public static void doTest() throws Exception { 123 SubSubSubTransform t = new SubSubSubTransform(); 124 System.out.println("value-getter is " + t.getFoo()); 125 System.out.println("value is " + t.foo); 126 System.out.println("static-call is " + SubSubSubTransform.FooBar()); 127 System.out.println("static-value is " + SubSubSubTransform.STATIC_FOO); 128 Redefinition.doMultiStructuralClassRedefinition( 129 new Redefinition.DexOnlyClassDefinition(Transform.class, DEX_BYTES), 130 new Redefinition.DexOnlyClassDefinition(SubSubTransform.class, DEX_BYTES_SUB_SUB)); 131 System.out.println("value-getter is " + t.getFoo()); 132 System.out.println("value is " + t.foo); 133 System.out.println("static-call is " + SubSubSubTransform.FooBar()); 134 System.out.println("static-value is " + SubSubSubTransform.STATIC_FOO); 135 } 136 } 137