/*
* Copyright ( C ) 2017 The Android Open Source Project
*
* Licensed under the Apache License , Version 2 . 0 ( the " License " ) ;
* you may not use this file except in compliance with the License .
* You may obtain a copy of the License at
*
* http : //www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing , software
* distributed under the License is distributed on an " AS IS " BASIS ,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND , either express or implied .
* See the License for the specific language governing permissions and
* limitations under the License .
*/
package art;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.Base64;
public class Test1901 {
// Class & Dex file containing the following class.
// Using this representation to prevent any changes to the compiler or the file formats from
// changing the output of this test.
//
// package art;
// public class Target {
// public void doNothing() {
// return;
// }
//
// public static void staticNothing() {
// return;
// }
//
// public void sayHi() {
// System.out.println("hello");
// }
// }
public static byte [] CLASS_BYTES = Base64.getDecoder().decode(
"yv66vgAAADQAHgoABgAQCQARABIIABMKABQAFQcAFgcAFwEABjxpbml0PgEAAygpVgEABENvZGUB" +
"AA9MaW5lTnVtYmVyVGFibGUBAAlkb05vdGhpbmcBAA1zdGF0aWNOb3RoaW5nAQAFc2F5SGkBAApT" +
"b3VyY2VGaWxlAQALVGFyZ2V0LmphdmEMAAcACAcAGAwAGQAaAQAFaGVsbG8HABsMABwAHQEACmFy" +
"dC9UYXJnZXQBABBqYXZhL2xhbmcvT2JqZWN0AQAQamF2YS9sYW5nL1N5c3RlbQEAA291dAEAFUxq" +
"YXZhL2lvL1ByaW50U3RyZWFtOwEAE2phdmEvaW8vUHJpbnRTdHJlYW0BAAdwcmludGxuAQAVKExq" +
"YXZhL2xhbmcvU3RyaW5nOylWACEABQAGAAAAAAAEAAEABwAIAAEACQAAAB0AAQABAAAABSq3AAGx" +
"AAAAAQAKAAAABgABAAAAAgABAAsACAABAAkAAAAZAAAAAQAAAAGxAAAAAQAKAAAABgABAAAABAAJ" +
"AAwACAABAAkAAAAZAAAAAAAAAAGxAAAAAQAKAAAABgABAAAACAABAA0ACAABAAkAAAAlAAIAAQAA" +
"AAmyAAISA7YABLEAAAABAAoAAAAKAAIAAAAMAAgADQABAA4AAAACAA8=" );
public static byte [] DEX_BYTES = Base64.getDecoder().decode(
"ZGV4CjAzNQAbYkxNjiZ8a+fNWF4smR2+uXbrq88/FNoYAwAAcAAAAHhWNBIAAAAAAAAAAHgCAAAP" +
"AAAAcAAAAAYAAACsAAAAAgAAAMQAAAABAAAA3AAAAAYAAADkAAAAAQAAABQBAADkAQAANAEAAJoB" +
"AACiAQAAsAEAAMcBAADbAQAA7wEAAAMCAAAQAgAAEwIAABcCAAAiAgAAKQIAAC4CAAA3AgAAPgIA" +
"AAEAAAACAAAAAwAAAAQAAAAFAAAABwAAAAcAAAAFAAAAAAAAAAgAAAAFAAAAlAEAAAQAAQALAAAA" +
"AAAAAAAAAAAAAAAACQAAAAAAAAANAAAAAAAAAA4AAAABAAEADAAAAAIAAAAAAAAAAAAAAAEAAAAC" +
"AAAAAAAAAAYAAAAAAAAAYgIAAAAAAAABAAEAAQAAAE0CAAAEAAAAcBAFAAAADgAAAAAAAAAAAFIC" +
"AAABAAAADgAAAAEAAQAAAAAAVwIAAAEAAAAOAAAAAwABAAIAAABcAgAACAAAAGIAAAAaAQoAbiAE" +
"ABAADgABAAAAAwAGPGluaXQ+AAxMYXJ0L1RhcmdldDsAFUxqYXZhL2lvL1ByaW50U3RyZWFtOwAS" +
"TGphdmEvbGFuZy9PYmplY3Q7ABJMamF2YS9sYW5nL1N0cmluZzsAEkxqYXZhL2xhbmcvU3lzdGVt" +
"OwALVGFyZ2V0LmphdmEAAVYAAlZMAAlkb05vdGhpbmcABWhlbGxvAANvdXQAB3ByaW50bG4ABXNh" +
"eUhpAA1zdGF0aWNOb3RoaW5nAAIABw4ACAAHDgAEAAcOAAwABw54AAAAAgIAgYAEtAIDCcwCAQHg" +
"AgEB9AINAAAAAAAAAAEAAAAAAAAAAQAAAA8AAABwAAAAAgAAAAYAAACsAAAAAwAAAAIAAADEAAAA" +
"BAAAAAEAAADcAAAABQAAAAYAAADkAAAABgAAAAEAAAAUAQAAASAAAAQAAAA0AQAAARAAAAEAAACU" +
"AQAAAiAAAA8AAACaAQAAAyAAAAQAAABNAgAAACAAAAEAAABiAgAAABAAAAEAAAB4AgAA" );
public static byte [][] DO_NOTHING_BYTECODES = new byte [][] {
// Dex Bytecodes for doNothing
// 0e00 |0000: return-void
new byte [] { 14 , 0 },
// Java bytecodes
// 0: return
new byte [] { -79 },
};
public static byte [][] STATIC_NOTHING_BYTECODES = new byte [][] {
// Dex Bytecodes for staticNothing
// 0e00 |0000: return-void
new byte [] { 14 , 0 },
// Java bytecodes
// 0: return
new byte [] { -79 },
};
public static byte [][] SAY_HI_NOTHING_BYTECODES = new byte [][] {
// Dex Bytecodes for sayHi
// 6200 0000 |0000: sget-object v0, Ljava/lang/System;.out:Ljava/io/PrintStream; // field@0000
// 1a01 0a00 |0002: const-string v1, "hello" // string@000a
// 6e20 0400 1000 |0004: invoke-virtual {v0, v1}, Ljava/io/PrintStream;.println:(Ljava/lang/String;)V // method@0004
// 0e00 |0007: return-void
new byte [] { 98 , 0 , 0 , 0 , 26 , 1 , 10 , 0 , 110 , 32 , 4 , 0 , 16 , 0 , 14 , 0 },
// Java bytecodes
// 0: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
// 3: ldc #3 // String hello
// 5: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
// 8: return
new byte [] { -78 , 0 , 2 , 18 , 3 , -74 , 0 , 4 , -79 },
};
public static ClassLoader getClassLoader() throws Exception {
try {
Class <?> class_loader_class = Class .forName("dalvik.system.InMemoryDexClassLoader" );
Constructor<?> ctor =
class_loader_class.getConstructor(ByteBuffer.class , ClassLoader.class );
// We are on art since we got the InMemoryDexClassLoader.
return (ClassLoader)ctor.newInstance(
ByteBuffer.wrap(DEX_BYTES), Test1901.class .getClassLoader());
} catch (ClassNotFoundException e) {
// Running on RI.
return new ClassLoader(Test1901.class .getClassLoader()) {
protected Class <?> findClass(String name) throws ClassNotFoundException {
if (name.equals("art.Target" )) {
return defineClass(name, CLASS_BYTES, 0 , CLASS_BYTES.length);
} else {
return super .findClass(name);
}
}
};
}
}
public static void CheckMethodBytes(Method m, byte [][] possible_bytecodes) {
byte [] real_codes = getBytecodes(m);
for (byte [] pos : possible_bytecodes) {
if (Arrays.equals(pos, real_codes)) {
return ;
}
}
System.out.println("Unexpected bytecodes for " + m);
System.out.println("Received: " + Arrays.toString(real_codes));
System.out.println("Expected one of:" );
for (byte [] pos : possible_bytecodes) {
System.out.println("\t" + Arrays.toString(pos));
}
}
public static void run() throws Exception {
Class <?> target = getClassLoader().loadClass("art.Target" );
CheckMethodBytes(target.getDeclaredMethod("doNothing" ), DO_NOTHING_BYTECODES);
CheckMethodBytes(target.getDeclaredMethod("staticNothing" ), STATIC_NOTHING_BYTECODES);
CheckMethodBytes(target.getDeclaredMethod("sayHi" ), SAY_HI_NOTHING_BYTECODES);
}
public static native byte [] getBytecodes(Method m);
}
Messung V0.5 in Prozent C=90 H=94 G=91
¤ Dauer der Verarbeitung: 0.11 Sekunden
(vorverarbeitet am 2026-06-29)
¤
*© Formatika GbR, Deutschland