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 package art; 18 19 import java.lang.reflect.Constructor; 20 import java.lang.reflect.Method; 21 import java.nio.ByteBuffer; 22 import java.util.Arrays; 23 import java.util.Base64; 24 25 public class Test1901 { 26 // Class & Dex file containing the following class. 27 // Using this representation to prevent any changes to the compiler or the file formats from 28 // changing the output of this test. 29 // 30 // package art; 31 // public class Target { 32 // public void doNothing() { 33 // return; 34 // } 35 // 36 // public static void staticNothing() { 37 // return; 38 // } 39 // 40 // public void sayHi() { 41 // System.out.println("hello"); 42 // } 43 // } 44 public static byte[] CLASS_BYTES = Base64.getDecoder().decode( 45 "yv66vgAAADQAHgoABgAQCQARABIIABMKABQAFQcAFgcAFwEABjxpbml0PgEAAygpVgEABENvZGUB" + 46 "AA9MaW5lTnVtYmVyVGFibGUBAAlkb05vdGhpbmcBAA1zdGF0aWNOb3RoaW5nAQAFc2F5SGkBAApT" + 47 "b3VyY2VGaWxlAQALVGFyZ2V0LmphdmEMAAcACAcAGAwAGQAaAQAFaGVsbG8HABsMABwAHQEACmFy" + 48 "dC9UYXJnZXQBABBqYXZhL2xhbmcvT2JqZWN0AQAQamF2YS9sYW5nL1N5c3RlbQEAA291dAEAFUxq" + 49 "YXZhL2lvL1ByaW50U3RyZWFtOwEAE2phdmEvaW8vUHJpbnRTdHJlYW0BAAdwcmludGxuAQAVKExq" + 50 "YXZhL2xhbmcvU3RyaW5nOylWACEABQAGAAAAAAAEAAEABwAIAAEACQAAAB0AAQABAAAABSq3AAGx" + 51 "AAAAAQAKAAAABgABAAAAAgABAAsACAABAAkAAAAZAAAAAQAAAAGxAAAAAQAKAAAABgABAAAABAAJ" + 52 "AAwACAABAAkAAAAZAAAAAAAAAAGxAAAAAQAKAAAABgABAAAACAABAA0ACAABAAkAAAAlAAIAAQAA" + 53 "AAmyAAISA7YABLEAAAABAAoAAAAKAAIAAAAMAAgADQABAA4AAAACAA8="); 54 public static byte[] DEX_BYTES = Base64.getDecoder().decode( 55 "ZGV4CjAzNQAbYkxNjiZ8a+fNWF4smR2+uXbrq88/FNoYAwAAcAAAAHhWNBIAAAAAAAAAAHgCAAAP" + 56 "AAAAcAAAAAYAAACsAAAAAgAAAMQAAAABAAAA3AAAAAYAAADkAAAAAQAAABQBAADkAQAANAEAAJoB" + 57 "AACiAQAAsAEAAMcBAADbAQAA7wEAAAMCAAAQAgAAEwIAABcCAAAiAgAAKQIAAC4CAAA3AgAAPgIA" + 58 "AAEAAAACAAAAAwAAAAQAAAAFAAAABwAAAAcAAAAFAAAAAAAAAAgAAAAFAAAAlAEAAAQAAQALAAAA" + 59 "AAAAAAAAAAAAAAAACQAAAAAAAAANAAAAAAAAAA4AAAABAAEADAAAAAIAAAAAAAAAAAAAAAEAAAAC" + 60 "AAAAAAAAAAYAAAAAAAAAYgIAAAAAAAABAAEAAQAAAE0CAAAEAAAAcBAFAAAADgAAAAAAAAAAAFIC" + 61 "AAABAAAADgAAAAEAAQAAAAAAVwIAAAEAAAAOAAAAAwABAAIAAABcAgAACAAAAGIAAAAaAQoAbiAE" + 62 "ABAADgABAAAAAwAGPGluaXQ+AAxMYXJ0L1RhcmdldDsAFUxqYXZhL2lvL1ByaW50U3RyZWFtOwAS" + 63 "TGphdmEvbGFuZy9PYmplY3Q7ABJMamF2YS9sYW5nL1N0cmluZzsAEkxqYXZhL2xhbmcvU3lzdGVt" + 64 "OwALVGFyZ2V0LmphdmEAAVYAAlZMAAlkb05vdGhpbmcABWhlbGxvAANvdXQAB3ByaW50bG4ABXNh" + 65 "eUhpAA1zdGF0aWNOb3RoaW5nAAIABw4ACAAHDgAEAAcOAAwABw54AAAAAgIAgYAEtAIDCcwCAQHg" + 66 "AgEB9AINAAAAAAAAAAEAAAAAAAAAAQAAAA8AAABwAAAAAgAAAAYAAACsAAAAAwAAAAIAAADEAAAA" + 67 "BAAAAAEAAADcAAAABQAAAAYAAADkAAAABgAAAAEAAAAUAQAAASAAAAQAAAA0AQAAARAAAAEAAACU" + 68 "AQAAAiAAAA8AAACaAQAAAyAAAAQAAABNAgAAACAAAAEAAABiAgAAABAAAAEAAAB4AgAA"); 69 70 public static byte[][] DO_NOTHING_BYTECODES = new byte[][] { 71 // Dex Bytecodes for doNothing 72 // 0e00 |0000: return-void 73 new byte[] { 14, 0 }, 74 // Java bytecodes 75 // 0: return 76 new byte[] { -79 }, 77 }; 78 79 public static byte[][] STATIC_NOTHING_BYTECODES = new byte[][] { 80 // Dex Bytecodes for staticNothing 81 // 0e00 |0000: return-void 82 new byte[] { 14, 0 }, 83 // Java bytecodes 84 // 0: return 85 new byte[] { -79 }, 86 }; 87 88 public static byte[][] SAY_HI_NOTHING_BYTECODES = new byte[][] { 89 // Dex Bytecodes for sayHi 90 // 6200 0000 |0000: sget-object v0, Ljava/lang/System;.out:Ljava/io/PrintStream; // field@0000 91 // 1a01 0a00 |0002: const-string v1, "hello" // string@000a 92 // 6e20 0400 1000 |0004: invoke-virtual {v0, v1}, Ljava/io/PrintStream;.println:(Ljava/lang/String;)V // method@0004 93 // 0e00 |0007: return-void 94 new byte[] { 98, 0, 0, 0, 26, 1, 10, 0, 110, 32, 4, 0, 16, 0, 14, 0 }, 95 // Java bytecodes 96 // 0: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream; 97 // 3: ldc #3 // String hello 98 // 5: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 99 // 8: return 100 new byte[] { -78, 0, 2, 18, 3, -74, 0, 4, -79 }, 101 }; 102 getClassLoader()103 public static ClassLoader getClassLoader() throws Exception { 104 try { 105 Class<?> class_loader_class = Class.forName("dalvik.system.InMemoryDexClassLoader"); 106 Constructor<?> ctor = class_loader_class.getConstructor(ByteBuffer.class, ClassLoader.class); 107 // We are on art since we got the InMemoryDexClassLoader. 108 return (ClassLoader)ctor.newInstance( 109 ByteBuffer.wrap(DEX_BYTES), Test1901.class.getClassLoader()); 110 } catch (ClassNotFoundException e) { 111 // Running on RI. 112 return new ClassLoader(Test1901.class.getClassLoader()) { 113 protected Class<?> findClass(String name) throws ClassNotFoundException { 114 if (name.equals("art.Target")) { 115 return defineClass(name, CLASS_BYTES, 0, CLASS_BYTES.length); 116 } else { 117 return super.findClass(name); 118 } 119 } 120 }; 121 } 122 } 123 CheckMethodBytes(Method m, byte[][] possible_bytecodes)124 public static void CheckMethodBytes(Method m, byte[][] possible_bytecodes) { 125 byte[] real_codes = getBytecodes(m); 126 for (byte[] pos : possible_bytecodes) { 127 if (Arrays.equals(pos, real_codes)) { 128 return; 129 } 130 } 131 System.out.println("Unexpected bytecodes for " + m); 132 System.out.println("Received: " + Arrays.toString(real_codes)); 133 System.out.println("Expected one of:"); 134 for (byte[] pos : possible_bytecodes) { 135 System.out.println("\t" + Arrays.toString(pos)); 136 } 137 } 138 run()139 public static void run() throws Exception { 140 Class<?> target = getClassLoader().loadClass("art.Target"); 141 CheckMethodBytes(target.getDeclaredMethod("doNothing"), DO_NOTHING_BYTECODES); 142 CheckMethodBytes(target.getDeclaredMethod("staticNothing"), STATIC_NOTHING_BYTECODES); 143 CheckMethodBytes(target.getDeclaredMethod("sayHi"), SAY_HI_NOTHING_BYTECODES); 144 } 145 getBytecodes(Method m)146 public static native byte[] getBytecodes(Method m); 147 } 148