1 /*
2  * Copyright (C) 2016 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.lang.reflect.Field;
20 import java.util.Base64;
21 
22 import sun.misc.Unsafe;
23 
24 public class Test1977 {
25 
26   // The class we will be transforming.
27   static class Transform {
28     static {
29     }
30 
31     public static String sayHiName = " Alex";
32     // Called whenever we do something.
somethingHappened()33     public static void somethingHappened() {}
34 
sayHi(Runnable r)35     public static void sayHi(Runnable r) {
36       System.out.println("hello" + sayHiName);
37       r.run();
38       somethingHappened();
39       System.out.println("goodbye" + sayHiName);
40     }
41   }
42 
43   // static class Transform {
44   //   static {}
45   //   // NB Due to the ordering of fields offset of sayHiName will change.
46   //   public static String sayHiName;
47   //   public static String sayByeName;
48   //   public static void somethingHappened() {
49   //     sayByeName = " and good luck";
50   //   }
51   //   public static void doSayBye() {
52   //     System.out.println("Goodbye" + sayByeName + " - Transformed");
53   //   }
54   //   public static void doSayHi() {
55   //     System.out.println("Hello" + sayHiName + " - Transformed");
56   //   }
57   //   public static void sayHi(Runnable r) {
58   //     doSayHi();
59   //     r.run();
60   //     somethingHappened();
61   //     doSayBye();
62   //   }
63   // }
64   private static final byte[] DEX_BYTES =
65       Base64.getDecoder()
66           .decode(
67               "ZGV4CjAzNQBNCReVL85UCydGe4wKq3olUYP6Lb8WIlewBgAAcAAAAHhWNBIAAAAAAAAAAOwFAAAl"
68                   + "AAAAcAAAAAsAAAAEAQAABQAAADABAAADAAAAbAEAAAwAAACEAQAAAQAAAOQBAACsBAAABAIAAEID"
69                   + "AABSAwAAYgMAAGwDAAB0AwAAfQMAAIQDAACHAwAAiwMAAKUDAAC1AwAA2QMAAPkDAAAQBAAAJAQA"
70                   + "ADoEAABOBAAAaQQAAH0EAACMBAAAlwQAAJoEAACeBAAAqwQAALMEAAC9BAAAxgQAAMwEAADRBAAA"
71                   + "2gQAAN8EAADrBAAA8gQAAP0EAAAQBQAAGgUAACEFAAAIAAAACQAAAAoAAAALAAAADAAAAA0AAAAO"
72                   + "AAAADwAAABAAAAARAAAAFAAAAAYAAAAHAAAAAAAAAAcAAAAIAAAANAMAABQAAAAKAAAAAAAAABUA"
73                   + "AAAKAAAAPAMAABUAAAAKAAAANAMAAAAABwAeAAAAAAAHACAAAAAJAAQAGwAAAAAAAgACAAAAAAAC"
74                   + "AAMAAAAAAAIAGAAAAAAAAgAZAAAAAAADAB8AAAAAAAIAIQAAAAQABAAcAAAABQACAAMAAAAGAAIA"
75                   + "HQAAAAgAAgADAAAACAABABcAAAAIAAAAIgAAAAAAAAAAAAAABQAAAAAAAAASAAAA3AUAAKgFAAAA"
76                   + "AAAAAAAAAAAAAAAOAwAAAQAAAA4AAAABAAEAAQAAABIDAAAEAAAAcBAHAAAADgAEAAAAAgAAABYD"
77                   + "AAAeAAAAYgACAGIBAAAiAggAcBAJAAIAGgMEAG4gCgAyAG4gCgASABoBAABuIAoAEgBuEAsAAgAM"
78                   + "AW4gBgAQAA4ABAAAAAIAAAAdAwAAHgAAAGIAAgBiAQEAIgIIAHAQCQACABoDBQBuIAoAMgBuIAoA"
79                   + "EgAaAQAAbiAKABIAbhALAAIADAFuIAYAEAAOAAEAAQABAAAAJAMAAA0AAABxAAMAAAByEAgAAABx"
80                   + "AAUAAABxAAIAAAAOAAAAAQAAAAAAAAAtAwAABQAAABoAAQBpAAAADgAHAA4ABgAOAA8ADgEdDwAS"
81                   + "AA4BHQ8AFQEADjw8PDwADAAOSwAAAAEAAAAHAAAAAQAAAAYADiAtIFRyYW5zZm9ybWVkAA4gYW5k"
82                   + "IGdvb2QgbHVjawAIPGNsaW5pdD4ABjxpbml0PgAHR29vZGJ5ZQAFSGVsbG8AAUwAAkxMABhMYXJ0"
83                   + "L1Rlc3QxOTc3JFRyYW5zZm9ybTsADkxhcnQvVGVzdDE5Nzc7ACJMZGFsdmlrL2Fubm90YXRpb24v"
84                   + "RW5jbG9zaW5nQ2xhc3M7AB5MZGFsdmlrL2Fubm90YXRpb24vSW5uZXJDbGFzczsAFUxqYXZhL2lv"
85                   + "L1ByaW50U3RyZWFtOwASTGphdmEvbGFuZy9PYmplY3Q7ABRMamF2YS9sYW5nL1J1bm5hYmxlOwAS"
86                   + "TGphdmEvbGFuZy9TdHJpbmc7ABlMamF2YS9sYW5nL1N0cmluZ0J1aWxkZXI7ABJMamF2YS9sYW5n"
87                   + "L1N5c3RlbTsADVRlc3QxOTc3LmphdmEACVRyYW5zZm9ybQABVgACVkwAC2FjY2Vzc0ZsYWdzAAZh"
88                   + "cHBlbmQACGRvU2F5QnllAAdkb1NheUhpAARuYW1lAANvdXQAB3ByaW50bG4AA3J1bgAKc2F5Qnll"
89                   + "TmFtZQAFc2F5SGkACXNheUhpTmFtZQARc29tZXRoaW5nSGFwcGVuZWQACHRvU3RyaW5nAAV2YWx1"
90                   + "ZQB2fn5EOHsiY29tcGlsYXRpb24tbW9kZSI6ImRlYnVnIiwibWluLWFwaSI6MSwic2hhLTEiOiJh"
91                   + "ODM1MmYyNTQ4ODUzNjJjY2Q4ZDkwOWQzNTI5YzYwMDk0ZGQ4OTZlIiwidmVyc2lvbiI6IjEuNi4y"
92                   + "MC1kZXYifQACAgEjGAECAwIWBAgaFxMCAAYAAAkBCQCIgASEBAGAgASYBAEJsAQBCfwEAQnIBQEJ"
93                   + "9AUAAAAAAgAAAJkFAACfBQAA0AUAAAAAAAAAAAAAAAAAABAAAAAAAAAAAQAAAAAAAAABAAAAJQAA"
94                   + "AHAAAAACAAAACwAAAAQBAAADAAAABQAAADABAAAEAAAAAwAAAGwBAAAFAAAADAAAAIQBAAAGAAAA"
95                   + "AQAAAOQBAAABIAAABgAAAAQCAAADIAAABgAAAA4DAAABEAAAAgAAADQDAAACIAAAJQAAAEIDAAAE"
96                   + "IAAAAgAAAJkFAAAAIAAAAQAAAKgFAAADEAAAAgAAAMwFAAAGIAAAAQAAANwFAAAAEAAAAQAAAOwF"
97                   + "AAA=");
98 
run()99   public static void run() throws Exception {
100     Redefinition.setTestConfiguration(Redefinition.Config.COMMON_REDEFINE);
101     doTest();
102   }
103 
doTest()104   public static void doTest() throws Exception {
105     Transform.sayHi(
106         () -> {
107           System.out.println("Not doing anything here");
108         });
109     Transform.sayHi(
110         () -> {
111           System.out.println("transforming calling function");
112           Redefinition.doCommonStructuralClassRedefinition(Transform.class, DEX_BYTES);
113         });
114     Transform.sayHi(
115         () -> {
116           System.out.println("Not doing anything here");
117         });
118   }
119 }
120