Search in sources :

Example 11 with ClassWriter

use of org.objectweb.asm.ClassWriter in project Valkyrien-Warfare-Revamped by ValkyrienWarfare.

the class ValkyrienWarfareTransformer method transform.

@Override
public byte[] transform(String name, String transformedName, byte[] classData) {
    classData = transformer.transform(classData);
    TransformAdapter adapter = new TransformAdapter(ASM5, ValkyrienWarfarePlugin.isObfuscatedEnvironment, transformedName);
    ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_MAXS);
    adapter.setCV(classWriter);
    try {
        new ClassReader(classData).accept(adapter, ClassReader.EXPAND_FRAMES);
        classData = classWriter.toByteArray();
    //Performs sanity checks and frame stack recalculations before pushing the new bytecode
    //			ClassReader cr = new ClassReader(byteArray);
    //			ClassWriter checkedWriter = new ClassWriter(ClassWriter.COMPUTE_MAXS);
    //			CheckClassAdapter adapterChecker = new CheckClassAdapter(checkedWriter, true);
    //			cr.accept(adapterChecker, ClassReader.EXPAND_FRAMES);
    //			return checkedWriter.toByteArray();
    } catch (Exception e) {
        //			System.out.println(transformedName);
        e.printStackTrace();
    }
    return classData;
}
Also used : ClassReader(org.objectweb.asm.ClassReader) ClassWriter(org.objectweb.asm.ClassWriter)

Example 12 with ClassWriter

use of org.objectweb.asm.ClassWriter in project android_frameworks_base by ResurrectionRemix.

the class DelegateClassAdapterTest method testConstructorsNotSupported.

/**
     * {@link DelegateMethodAdapter} does not support overriding constructors yet,
     * so this should fail with an {@link UnsupportedOperationException}.
     *
     * Although not tested here, the message of the exception should contain the
     * constructor signature.
     */
@Test(expected = UnsupportedOperationException.class)
public void testConstructorsNotSupported() throws IOException {
    ClassWriter cw = new ClassWriter(0);
    String internalClassName = NATIVE_CLASS_NAME.replace('.', '/');
    HashSet<String> delegateMethods = new HashSet<>();
    delegateMethods.add("<init>");
    DelegateClassAdapter cv = new DelegateClassAdapter(mLog, cw, internalClassName, delegateMethods);
    ClassReader cr = new ClassReader(NATIVE_CLASS_NAME);
    cr.accept(cv, 0);
}
Also used : ClassReader(org.objectweb.asm.ClassReader) ClassWriter(org.objectweb.asm.ClassWriter) HashSet(java.util.HashSet) Test(org.junit.Test)

Example 13 with ClassWriter

use of org.objectweb.asm.ClassWriter in project android_frameworks_base by ResurrectionRemix.

the class DelegateClassAdapterTest method testDelegateInner.

@Test
public void testDelegateInner() throws Throwable {
    // We'll delegate the "get" method of both the inner and outer class.
    HashSet<String> delegateMethods = new HashSet<>();
    delegateMethods.add("get");
    delegateMethods.add("privateMethod");
    // Generate the delegate for the outer class.
    ClassWriter cwOuter = new ClassWriter(0);
    String outerClassName = OUTER_CLASS_NAME.replace('.', '/');
    DelegateClassAdapter cvOuter = new DelegateClassAdapter(mLog, cwOuter, outerClassName, delegateMethods);
    ClassReader cr = new ClassReader(OUTER_CLASS_NAME);
    cr.accept(cvOuter, 0);
    // Generate the delegate for the inner class.
    ClassWriter cwInner = new ClassWriter(0);
    String innerClassName = INNER_CLASS_NAME.replace('.', '/');
    DelegateClassAdapter cvInner = new DelegateClassAdapter(mLog, cwInner, innerClassName, delegateMethods);
    cr = new ClassReader(INNER_CLASS_NAME);
    cr.accept(cvInner, 0);
    // Load the generated classes in a different class loader and try them
    ClassLoader2 cl2 = null;
    try {
        cl2 = new ClassLoader2() {

            @Override
            public void testModifiedInstance() throws Exception {
                // Check the outer class
                Class<?> outerClazz2 = loadClass(OUTER_CLASS_NAME);
                Object o2 = outerClazz2.newInstance();
                assertNotNull(o2);
                // The original Outer.get returns 1+10+20,
                // but the delegate makes it return 4+10+20
                assertEquals(4 + 10 + 20, callGet(o2, 10, 20));
                assertEquals(1 + 10 + 20, callGet_Original(o2, 10, 20));
                // The original Outer has a private method,
                // so by default we can't access it.
                boolean gotIllegalAccessException = false;
                try {
                    callMethod(o2, "privateMethod", false);
                } catch (IllegalAccessException e) {
                    gotIllegalAccessException = true;
                }
                assertTrue(gotIllegalAccessException);
                // The private method from original Outer has been
                // delegated. The delegate generated should have the
                // same access.
                gotIllegalAccessException = false;
                try {
                    assertEquals("outerPrivateMethod", callMethod(o2, "privateMethod_Original", false));
                } catch (IllegalAccessException e) {
                    gotIllegalAccessException = true;
                }
                assertTrue(gotIllegalAccessException);
                // Check the inner class. Since it's not a static inner class, we need
                // to use the hidden constructor that takes the outer class as first parameter.
                Class<?> innerClazz2 = loadClass(INNER_CLASS_NAME);
                Constructor<?> innerCons = innerClazz2.getConstructor(outerClazz2);
                Object i2 = innerCons.newInstance(o2);
                assertNotNull(i2);
                // The original Inner.get returns 3+10+20,
                // but the delegate makes it return 6+10+20
                assertEquals(6 + 10 + 20, callGet(i2, 10, 20));
                assertEquals(3 + 10 + 20, callGet_Original(i2, 10, 20));
            }
        };
        cl2.add(OUTER_CLASS_NAME, cwOuter.toByteArray());
        cl2.add(INNER_CLASS_NAME, cwInner.toByteArray());
        cl2.testModifiedInstance();
    } catch (Throwable t) {
        throw dumpGeneratedClass(t, cl2);
    }
}
Also used : Constructor(java.lang.reflect.Constructor) ClassWriter(org.objectweb.asm.ClassWriter) IOException(java.io.IOException) InvocationTargetException(java.lang.reflect.InvocationTargetException) ClassReader(org.objectweb.asm.ClassReader) OuterClass(com.android.tools.layoutlib.create.dataclass.OuterClass) StaticInnerClass(com.android.tools.layoutlib.create.dataclass.OuterClass.StaticInnerClass) InnerClass(com.android.tools.layoutlib.create.dataclass.OuterClass.InnerClass) HashSet(java.util.HashSet) Test(org.junit.Test)

Example 14 with ClassWriter

use of org.objectweb.asm.ClassWriter in project android_frameworks_base by ResurrectionRemix.

the class StubMethodAdapterTest method testBoolean.

/**
     * @param methodPredicate tests if the method should be replaced
     */
private void testBoolean(BiPredicate<String, Type> methodPredicate, Consumer<Boolean> assertion, String methodName) throws Exception {
    ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS);
    // Always rename the class to avoid conflict with the original class.
    String newClassName = STUB_CLASS_NAME + '_';
    new ClassReader(STUB_CLASS_NAME).accept(new ClassAdapter(newClassName, writer, methodPredicate), 0);
    MyClassLoader myClassLoader = new MyClassLoader(newClassName, writer.toByteArray());
    Class<?> aClass = myClassLoader.loadClass(newClassName);
    assertTrue("StubClass not loaded by the classloader. Likely a bug in the test.", myClassLoader.findClassCalled);
    Method method = aClass.getMethod(methodName);
    Object o = aClass.newInstance();
    assertion.accept((Boolean) method.invoke(o));
}
Also used : ClassReader(org.objectweb.asm.ClassReader) Method(java.lang.reflect.Method) ClassWriter(org.objectweb.asm.ClassWriter)

Example 15 with ClassWriter

use of org.objectweb.asm.ClassWriter in project android_frameworks_base by ResurrectionRemix.

the class AsmGenerator method transform.

/**
     * Transforms a class.
     * <p/>
     * There are 3 kind of transformations:
     *
     * 1- For "mock" dependencies classes, we want to remove all code from methods and replace
     * by a stub. Native methods must be implemented with this stub too. Abstract methods are
     * left intact. Modified classes must be overridable (non-private, non-final).
     * Native methods must be made non-final, non-private.
     *
     * 2- For "keep" classes, we want to rewrite all native methods as indicated above.
     * If a class has native methods, it must also be made non-private, non-final.
     *
     * Note that unfortunately static methods cannot be changed to non-static (since static and
     * non-static are invoked differently.)
     */
byte[] transform(ClassReader cr, boolean stubNativesOnly) {
    boolean hasNativeMethods = hasNativeMethods(cr);
    // Get the class name, as an internal name (e.g. com/android/SomeClass$InnerClass)
    String className = cr.getClassName();
    String newName = transformName(className);
    // transformName returns its input argument if there's no need to rename the class
    if (!newName.equals(className)) {
        mRenameCount++;
        // This class is being renamed, so remove it from the list of classes not renamed.
        mClassesNotRenamed.remove(className);
    }
    mLog.debug("Transform %s%s%s%s", className, newName.equals(className) ? "" : " (renamed to " + newName + ")", hasNativeMethods ? " -- has natives" : "", stubNativesOnly ? " -- stub natives only" : "");
    // Rewrite the new class from scratch, without reusing the constant pool from the
    // original class reader.
    ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
    ClassVisitor cv = cw;
    // FIXME Generify
    if ("android/content/res/Resources".equals(className)) {
        cv = new FieldInjectorAdapter(cv);
    }
    if (mReplaceMethodCallsClasses.contains(className)) {
        cv = new ReplaceMethodCallsAdapter(cv, className);
    }
    cv = new RefactorClassAdapter(cv, mRefactorClasses);
    if (!newName.equals(className)) {
        cv = new RenameClassAdapter(cv, className, newName);
    }
    String binaryNewName = newName.replace('/', '.');
    if (mInjectedMethodsMap.keySet().contains(binaryNewName)) {
        cv = new InjectMethodsAdapter(cv, mInjectedMethodsMap.get(binaryNewName));
    }
    cv = new TransformClassAdapter(mLog, mStubMethods, mDeleteReturns.get(className), newName, cv, stubNativesOnly);
    Set<String> delegateMethods = mDelegateMethods.get(className);
    if (delegateMethods != null && !delegateMethods.isEmpty()) {
        // known to have no native methods, just skip this step.
        if (hasNativeMethods || !(delegateMethods.size() == 1 && delegateMethods.contains(DelegateClassAdapter.ALL_NATIVES))) {
            cv = new DelegateClassAdapter(mLog, cv, className, delegateMethods);
        }
    }
    Set<String> promoteFields = mPromotedFields.get(className);
    if (promoteFields != null && !promoteFields.isEmpty()) {
        cv = new PromoteFieldClassAdapter(cv, promoteFields);
    }
    cr.accept(cv, 0);
    return cw.toByteArray();
}
Also used : ClassVisitor(org.objectweb.asm.ClassVisitor) ClassWriter(org.objectweb.asm.ClassWriter)

Aggregations

ClassWriter (org.objectweb.asm.ClassWriter)471 ClassReader (org.objectweb.asm.ClassReader)275 MethodVisitor (org.objectweb.asm.MethodVisitor)115 Test (org.junit.Test)94 ClassVisitor (org.objectweb.asm.ClassVisitor)82 ClassNode (org.objectweb.asm.tree.ClassNode)70 IOException (java.io.IOException)57 SemanticVersioningClassVisitor (org.apache.aries.versioning.utils.SemanticVersioningClassVisitor)52 Label (org.objectweb.asm.Label)51 HashSet (java.util.HashSet)37 Method (java.lang.reflect.Method)36 BinaryCompatibilityStatus (org.apache.aries.versioning.utils.BinaryCompatibilityStatus)32 Type (org.objectweb.asm.Type)30 File (java.io.File)27 InvocationTargetException (java.lang.reflect.InvocationTargetException)27 FieldVisitor (org.objectweb.asm.FieldVisitor)26 InputStream (java.io.InputStream)25 MethodNode (org.objectweb.asm.tree.MethodNode)25 OuterClass (com.android.tools.layoutlib.create.dataclass.OuterClass)23 InnerClass (com.android.tools.layoutlib.create.dataclass.OuterClass.InnerClass)23