public static byte[] patchByteCode(ClassLoader l, String className, ProtectionDomain pd, byte[] arr) throws IllegalClassFormatException { if (ACTIVE == null) { return arr; } if (Boolean.TRUE.equals(IN.get())) { return arr; } try { IN.set(Boolean.TRUE); for (NbInstrumentation inst : ACTIVE) { for (ClassFileTransformer t : inst.transformers) { arr = t.transform(l, className, null, pd, arr); } } } finally { IN.set(null); } return arr; }
@Override public byte[] transform( ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] arr ) throws IllegalClassFormatException { byte[] ret = arr; for (int i = 0; i < arr.length - 4; i++) { if (arr[i] == 'H' && arr[i + 1] == 'e' && arr[i + 2] == 'l' && arr[i + 3] == 'o' ) { ret = ret.clone(); ret[i] = 'A'; ret[i + 1] = 'h'; ret[i + 2] = 'o'; ret[i + 3] = 'j'; } } return ret; }
public byte[] transform(ClassLoader loader, String className, Class classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException { try { pool.insertClassPath(new ByteArrayClassPath(className, classfileBuffer)); CtClass cclass = pool.get(className.replaceAll("/", ".")); if (!cclass.getName().startsWith("ru.otus.")) { return null; // the same as return classfileBuffer; without changes } for (CtMethod currentMethod : cclass.getDeclaredMethods()) { AddLog annotation = (AddLog) currentMethod.getAnnotation(AddLog.class); if (annotation != null) { currentMethod.insertBefore("{System.out.println(\"" + annotation.message() + "\");}"); } } return cclass.toBytecode(); } catch (Exception e) { e.printStackTrace(); } return null; }
@Override public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException { String classNameFinal = className.replace('/', '.'); byte[] retorno = classfileBuffer; ClassPool cp = ClassPool.getDefault(); cp.appendClassPath(new LoaderClassPath(loader)); Iterator<String> iterator = this.mapClasse.keySet().iterator(); while (iterator.hasNext()) { String classNameParam = iterator.next(); if (classNameFinal.equals(classNameParam)) { Clazz classe = this.mapClasse.get(classNameFinal); this.mapClasse.remove(classNameParam); return instrumentalize(cp, classNameFinal, retorno, classe); } } return retorno; }
/** * Apply transformation on a given class byte definition. * The method will always return a non-null byte array (if no transformation has taken place * the array content will be identical to the original one). * @param className the full qualified name of the class in dot format (i.e. some.package.SomeClass) * @param internalName class name internal name in / format (i.e. some/package/SomeClass) * @param bytes class byte definition * @param pd protection domain to be used (can be null) * @return (possibly transformed) class byte definition */ public byte[] transformIfNecessary(String className, String internalName, byte[] bytes, ProtectionDomain pd) { byte[] result = bytes; for (ClassFileTransformer cft : this.transformers) { try { byte[] transformed = cft.transform(this.classLoader, internalName, null, pd, result); if (transformed != null) { result = transformed; } } catch (IllegalClassFormatException ex) { throw new IllegalStateException("Class file transformation failed", ex); } } return result; }
public static void main(String[] args) throws IllegalClassFormatException { Scanner scanner = new Scanner(System.in); String driverName = scanner.nextLine(); Car ferrari = new Ferrari(driverName); System.out.println(ferrari); String ferrariName = Ferrari.class.getSimpleName(); String carInterface = Car.class.getSimpleName(); boolean isCreated = Car.class.isInterface(); if (!isCreated) { throw new IllegalClassFormatException("No interface created!"); } }
@Override public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException { if (className.contains("TypeAnnotatedTestClass")) { try { // Here we remove and re-add the dummy fields. This shuffles the constant pool return asm(loader, className, classBeingRedefined, protectionDomain, classfileBuffer); } catch (Throwable e) { // The retransform native code that called this method does not propagate // exceptions. Instead of getting an uninformative generic error, catch // problems here and print it, then exit. e.printStackTrace(); System.exit(1); } } return null; }
public byte[] transform(ClassLoader loader, String className, Class classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException { byte[] byteCode = classfileBuffer; if (className.equals("beans/Sleeping")) { try { ClassPool cp = ClassPool.getDefault(); CtClass cc = cp.get("beans.Sleeping"); CtMethod m = cc.getDeclaredMethod("sleepNow"); m.addLocalVariable("elapsedTime", CtClass.longType); m.insertBefore("elapsedTime = System.currentTimeMillis();"); m.insertAfter("{elapsedTime = System.currentTimeMillis() - elapsedTime;" + "System.out.println(\"Method Executed in ms: \" + elapsedTime);}"); byteCode = cc.toBytecode(); cc.detach(); } catch (Exception ex) { ex.printStackTrace(); } } return byteCode; }
@Override public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain pd, byte[] byteCode) throws IllegalClassFormatException { if (className.replace("/", ".").equals(clazzName)) { System.out.println("Agent: instrumenting " + className); try { ClassPool classPool = ClassPool.getDefault(); CtClass clazz = classPool.get(clazzName); addTiming(clazz, method); byte[] instrumentedByteCode = clazz.toBytecode(); clazz.detach(); saveByteCode(instrumentedByteCode, clazz.getSimpleName()); System.out.println("Agent: instrumented successfully " + clazzName + "." + method); return instrumentedByteCode; } catch (Throwable t) { t.printStackTrace(); } } return byteCode; }
@Override public byte[] transform(String name, String transformedName, byte[] classBuffer) { String internalClassName = name.replace('.', '/'); for (ClassFileTransformer transformer : AuthlibInjectorTweaker.transformers) { byte[] result = null; try { result = transformer.transform(Launch.classLoader, internalClassName, null, null, classBuffer); } catch (IllegalClassFormatException e) { log("exception while invoking {0}: {1}", transformer, e); e.printStackTrace(); } if (result != null) { classBuffer = result; } } return classBuffer; }
@Override public byte[] transform(ClassLoader loader, String internalClassName, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException { if (internalClassName != null && classfileBuffer != null) { try { String className = internalClassName.replace('/', '.'); for (String prefix : ignores) if (className.startsWith(prefix)) return null; TransformHandle handle = new TransformHandle(className, classfileBuffer); units.forEach(handle::accept); if (handle.getResult().isPresent()) { byte[] classBuffer = handle.getResult().get(); if (debug) { saveClassFile(className, classBuffer); } return classBuffer; } else { return null; } } catch (Throwable e) { log("unable to transform {0}: {1}", internalClassName, e); e.printStackTrace(); } } return null; }
@Override public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException { if(className.startsWith(TransformConfig.getInstance().getPackageScan())) { logger.log(Level.INFO, "-------------------CLASS---------------------"); logger.log(Level.INFO, "className: " + className); ClassReader cr = new ClassReader(classfileBuffer); ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS); ClassVisitor classVisitor = new HookClassAdapter(Opcodes.ASM5, cw); cr.accept(classVisitor, ClassReader.SKIP_FRAMES); // try { // FileOutputStream fos = new FileOutputStream(new File("classMod.class")); // fos.write(cw.toByteArray()); // fos.close(); // } catch (IOException e) { // e.printStackTrace(); // } return cw.toByteArray(); } return null; }
/** * Transformation method - implemented by a ClassFileTransformer in order to change classes' bytecode as they are loaded. * @param classLoader The ClassLoader of the class being transformed. * @param className The class name passed from the JVM. * @param classBeingTransformed The Class object of the class being transformed. * @param protectionDomain The protection domain of the class being transformed. * @param bytes The bytecode of the class being transformed. * @return The redefined array of bytes. * @throws IllegalClassFormatException */ @Override public byte[] transform(ClassLoader classLoader, String className, Class<?> classBeingTransformed, ProtectionDomain protectionDomain, byte[] bytes) throws IllegalClassFormatException { try { if (className != null) { className = className.replace("/", "."); if (className.equals("io.netty.bootstrap.Bootstrap")) { ClassPool pool = ClassPool.getDefault(); pool.appendClassPath(new ByteArrayClassPath(className, bytes)); CtClass ctClass = pool.get(className); CtMethod method = ctClass.getMethod("isBlockedServerHostName", "(Ljava/lang/String;)Z"); method.setBody("{ return false; }"); System.out.println("[MojangBlacklistBypass] Successfully retransformed server blacklist!"); return ctClass.toBytecode(); } } } catch (Exception e) { e.printStackTrace(); } return null; }
@Override public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException { if(MethodDatabase.isJavaCore(className)) { return null; } if(className.startsWith("org/objectweb/asm/")) { return null; } db.log(LogLevel.INFO, "TRANSFORM: %s", className); try { return instrumentClass(db, classfileBuffer, check); } catch(Exception ex) { db.error("Unable to instrument", ex); return null; } }
@Override public byte[] transform(ClassLoader loader, String className, Class<?> clazz, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException { if (!classNameToProcess.equals(className)) return null; ClassReader cr = new ClassReader(classfileBuffer); ClassInfoVisitor ciVisitor = new ClassInfoVisitor(); cr.accept(ciVisitor, 0); ClassInfo cInfo = ciVisitor.buildClassInfo(); ciCache.getOrInitClassInfoMap(loader).put(className, cInfo); ClassWriter cw = new FrameClassWriter(loader, ciCache, cInfo.getVersion()); ClassVisitor transformer = new ClassVisitor(ASM_API, cw) { @Override public MethodVisitor visitMethod(int access, final String mname, final String desc, String signature, String[] exceptions) { if (methodToDelete.equals(mname)) return null; return super.visitMethod(access, mname, desc, signature, exceptions); } }; cr.accept(transformer, 0); return cw.toByteArray(); }
@Override public byte[] transform(ClassLoader loader, String className, Class clazz, ProtectionDomain domain, byte[] originalBytes) throws IllegalClassFormatException { if (!className.startsWith(packagePrefix)) { return originalBytes; } CtClass ctClass = readClass(originalBytes); if (ctClass == null) return originalBytes; try { enhanceMethods(ctClass); return ctClass.toBytecode(); } catch (IOException | CannotCompileException e) { System.err.println("Couldn't enhance class " + className); e.printStackTrace(); return originalBytes; } }
public byte[] transform(ClassLoader loader, String className, Class classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException { try { if(!"javax/servlet/http/HttpServlet".equals(className)) { return null; } hookingCtx.set(loader); ClassReader cr = new ClassReader(classfileBuffer); ClassWriter cw = new ScouterClassWriter(ClassWriter.COMPUTE_FRAMES); ClassVisitor cv = new ServletServiceProbe().transform(cw, className); cr.accept(cv, ClassReader.SKIP_FRAMES); System.out.println(className + "\t[" + loader + "]"); return cw.toByteArray(); } catch (Throwable t) { t.printStackTrace(); } finally { hookingCtx.set(null); } return null; }
@Override public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException { byte[] returnedBuffer = null; for (Plugin plugin : plugins) { if (plugin.handleClassDefinition(loader, className)) { try { String normalizedClassName = className.replaceAll("/", "."); // If a program is running on a web application server such as JBoss and Tomcat, the ClassPool object may not be able to find user classes since such a web application server uses multiple class loaders as well as the system class // loader. classPool.insertClassPath(new LoaderClassPath(loader)); CtClass cc = classPool.get(normalizedClassName); plugin.define(cc); returnedBuffer = cc.toBytecode(); // FIXME verif le detach cc.detach(); } catch (Exception e) { logger.onGenerationFail(e.getMessage(), e); } } } return returnedBuffer; }
public static void premain(String options, Instrumentation inst) { // Handle duplicate agents if (initialized) { return; } initialized = true; inst.addTransformer(new ClassFileTransformer() { public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException { if (classBeingRedefined != null) { try { Field callSiteArrayField = classBeingRedefined.getDeclaredField("$callSiteArray"); callSiteArrayField.setAccessible(true); callSiteArrayField.set(null, null); } catch (Throwable ignored) { } } return removeTimestampField(classfileBuffer); } }); }
protected boolean rewriteClassFile(File source, AsyncAwaitClassFileGenerator generator, File target) throws IOException, IllegalClassFormatException { final byte[] original = toByteArray(source); try { final byte[] transformed = generator.transform(original); if (transformed != original /* Exact equality means not transformed */ || !source.equals(target)) { writeFile(target, transformed != null ? transformed : original); if (transformed != original) { final Map<String, byte[]> extraClasses = generator.getGeneratedClasses(); for (Map.Entry<String, byte[]> e : renameInMemoryResources(extraClasses).entrySet()) { writeFile(new File(target.getParentFile(), e.getKey()), e.getValue()); } } return true; } else { return false; } } finally { generator.reset(); } }
public byte[] transform(final ClassLoader classLoader, final String jvmInternalClassName, final Class<?> classBeingRedefined, final ProtectionDomain protectionDomain, final byte[] originalClassBuffer) throws IllegalClassFormatException { String className = jvmInternalClassName.replace('/', '.'); try { return instrument(classLoader, originalClassBuffer, className); } catch (Throwable t) { mLogger.severe("Failed to transform the class " + className + ": " + t.getMessage()); dumpClassToFile(originalClassBuffer, mOriginalClassesDir, className); return null; } }
private Class<?> createTransformedClass(String className, byte[] classBuffer) throws ClassNotFoundException, IllegalClassFormatException, ClassNotTransformedException { byte[] transformedClassBuffer = mTransformer.transform(this, className, null, null, classBuffer); if (transformedClassBuffer == null) { throw new ClassNotTransformedException("Class not transformed: " + className); } mTansformedClasses.add(className); return defineClass(className, transformedClassBuffer, 0, transformedClassBuffer.length); }
public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException { if (loader == null || shouldIgnore(className)) { return null; } try { if (classesToTransform != null && classesToTransform.contains(className.replace("/", "."))) { ByteArrayInputStream is = new ByteArrayInputStream(classfileBuffer); CtClass ctClass = null; try { ctClass = ClassPool.getDefault().makeClass(is); } finally { is.close(); } ctClass = mainMockTransformer.transform(ctClass); return ctClass.toBytecode(); } return null; } catch(Exception e) { throw new RuntimeException("Failed to redefine class "+className, e); } }
@Override public byte[] transform(Controller controller, Instrumentation instr, Module module, ClassLoader loader, String className, Class<?> clazz, ProtectionDomain pd, byte[] bytes) throws IllegalClassFormatException { if (clazz == null) { return null; } ControllerClassData classData = controller.getClassData(clazz); if (classData == null) { return null; } try { Transformer classTransformer = new Transformer(bytes, classData); // AsmUtils.printBytecodeSource(classTransformer.getWriter(), System.out); classTransformer.run(); // AsmUtils.printBytecodeSource(classTransformer.getWriter(), System.out); return classTransformer.getWriter().toByteArray(); } catch (Throwable e) { e.printStackTrace(); return null; } }
@Nullable @Override public byte[] transform(Controller controller, Instrumentation instr, Module module, @Nullable ClassLoader loader, String className, @Nullable Class<?> clazz, ProtectionDomain pd, byte[] bytecode) throws IllegalClassFormatException { // skip basic java classes if (loader == null) { return null; } ClassReader cr = new ClassReader(bytecode); ClassWriter cw = new ClassWriter(0); ClinitClassVisitor classVisitor = new ClinitClassVisitor(cw); cr.accept(classVisitor, 0); if (! classVisitor.added) { return null; } return cw.toByteArray(); }
@Override public byte[] transform(final ClassLoader loader, final String className, final Class<?> classBeingRedefined, final ProtectionDomain protectionDomain, final byte[] classfileBuffer) throws IllegalClassFormatException { final boolean include = shouldInclude(className); if (include) { try { return transformBytes(loader, className, classfileBuffer); } catch (final RuntimeException t) { System.err.println("RuntimeException while transforming " + className); throw t; } } else { return null; } }
@Override public byte[] transform(ClassLoader loader,String className,Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException { if (Util.isNotToProfile(className)) { return null; } try { final ClassReader classReader = new ClassReader(classfileBuffer); final ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_MAXS); final ClassVisitor profileAdapter = new ClassNodeAdapter(classWriter); classReader.accept(profileAdapter, ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES); return classWriter.toByteArray(); } catch (final Exception ex) { Debug.getInstance().debug("Field.Instrument", "Error instrumenting class " + className + "."); return null; } }
@Override public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException { String classWithDots = className.replace('/', '.'); if(!active || !RuntimeInstrumentation.checkIfCanInstrument(classWithDots) || classWithDots.startsWith(PackageInfo.getEvoSuitePackage())){ return classfileBuffer; } else { //ClassResetter.getInstance().setClassLoader(loader); ClassReader reader = new ClassReader(classfileBuffer); synchronized(instrumentedClasses){ instrumentedClasses.add(classWithDots); } logger.debug("Going to instrument: "+classWithDots); if(instrumenter.isAlreadyInstrumented(new ClassReader(classfileBuffer))) { logger.debug("Skipping transformation of {} as it is already instrumented", classWithDots); return classfileBuffer; } return instrumenter.transformBytes(loader, className, reader, false); // TODO: Need to set skip instrumentation for test class } }
public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] currentBytes) throws IllegalClassFormatException { String clname = "bootstrap"; if (loader != null) { clname = loader.getClass().getName() + "@" + Integer.toHexString(System.identityHashCode(loader)); } Entry e = entries.get(className); if (e != null) { log.debug(clname + " is loading " + className); } if (e != null && loader != null) { e.loaderRef = new WeakReference<ClassLoader>(loader); } return null; }
public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException { if (loader == null) { /* * Leave the class alone, if it is being loaded by the Bootstrap classloader, * as we don't want to do anything with JDK libs. See Issue #22. */ return classfileBuffer; } else { try { TransformationParameters transformationParameters = calculateTransformationParameters(classfileBuffer); return transform(classfileBuffer, transformationParameters); } catch (Exception e) { System.err.println("Scott: test instrumentation failed for " + className + "!"); e.printStackTrace(); throw e; } } }
public static void premain(final String agentArgs, Instrumentation inst){ Agent.inst = inst; System.out.printf("premain called"); inst.addTransformer(new ClassFileTransformer() { public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException { ClassPool cp = ClassPool.getDefault(); try { if(className.equals("Application")){ final CtClass ctClass = cp.get("Application"); final CtMethod ctMethod = ctClass.getDeclaredMethod("hello"); ctMethod.insertBefore("return \"Bye\";"); classfileBuffer = ctClass.toBytecode(); ctClass.detach(); } } catch (Exception e) { e.printStackTrace(); } return classfileBuffer; } }); }