public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException
try { className = className.replace("/", File.separator); StringBuilder buf = new StringBuilder(); buf.append(dumpDir); buf.append(File.separatorChar); int index = className.lastIndexOf(File.separatorChar); if (index != -1) buf.append(className.substring(0, index)); String dir = buf.toString(); new File(dir).mkdirs(); String fileName = dumpDir + File.separator + className + ".class"; FileOutputStream fos = new FileOutputStream(fileName); fos.write(classBuf); fos.close(); } catch (Exception exp) { exp.printStackTrace(); }
public static void agentmain(String agentArgs, Instrumentation inst) { inst.addTransformer(new ClassFileTransformerImpl(), true); inst.retransformClasses(inst.getAllLoadedClasses()); // }
import sun.jvmstat.monitor.MonitoredHost; import sun.jvmstat.monitor.event.HostEvent; import sun.jvmstat.monitor.event.HostListener; import sun.jvmstat.monitor.event.VmStatusChangeEvent; public class VMUpdater { public static MonitoredHost MH; public VMUpdater() { try { MH = MonitoredHost.getMonitoredHost("localhost"); MH.addHostListener(new HostListenerAction()); } catch (Exception e) {} } private class HostListenerAction implements HostListener { @Override public void vmStatusChanged(VmStatusChangeEvent vmStatusChangeEvent) {} @Override public void disconnected(HostEvent hostEvent) {} } }
private static final String PATH = getClass().getProtectionDomain().getCodeSource().getLocation().getPath(); private static VirtualMachine vm; // pid , GUI public static void attach(int pid) throws Exception { vm = VirtualMachine.attach(String.valueOf(pid)); vm.loadAgent(PATH); // jar c ( , ) AttachedGUI.getInstance().draw(); // GUI }
import java.io.BufferedInputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.util.Enumeration; import java.util.Hashtable; import java.util.jar.JarEntry; import java.util.jar.JarFile; public class JarClassLoader extends ClassLoader { private Hashtable<String, Class<?>> classes = new Hashtable<String, Class<?>>(); public JarClassLoader(ClassLoader parent) { super(parent); } @Override public synchronized Class<?> loadClass(String className, boolean resolve) throws ClassNotFoundException { Class<?> result = null; result = classes.get(className); if(result == null) result = super.findSystemClass(className); if(result == null) result = super.loadClass(className); classes.put(className, result); return result; } public Hashtable<String, Class<?>> loadJar(String jarPath, String dumpPath) throws IOException, ClassNotFoundException { classes.clear(); JarFile jar = new JarFile(jarPath); Enumeration<JarEntry> entries = jar.entries(); while (entries.hasMoreElements()) { String name = entries.nextElement().getName(); if(name.endsWith(".class")) { String className = name; if(name.contains(".")) className = name.substring(0, name.lastIndexOf(".")).replace("/", "."); Class<?> c = loadClass(className); if(c != null) classes.put(className, c); } else if(jar.getEntry(name).isDirectory()) { name = slash2sep(name); new File(dumpPath + File.separator + name).mkdirs(); } else { FileOutputStream fos = new FileOutputStream(dumpPath + File.separator + name); BufferedInputStream bis = new BufferedInputStream(jar.getInputStream(jar.getEntry(name))); byte[] data = new byte[(int) jar.getEntry(name).getSize()]; bis.read(data); fos.write(data); bis.close(); fos.close(); } } jar.close(); return classes; } private static String slash2sep(String src) { int i; char[] chDst = new char[src.length()]; String dst; for(i = 0; i < src.length(); i++) { if(src.charAt(i) == '/') chDst[i] = File.separatorChar; else chDst[i] = src.charAt(i); } dst = new String(chDst); return dst; } }
Premain-Class: ClassDumperAgent Agent-Class: ClassDumperAgent Can-Redefine-Classes: true Can-Retransform-Classes: true
Source: https://habr.com/ru/post/164855/
All Articles