agentmain
巴海和
2013-08-08
今天,编写一个小程序,想通过agentmain去获取运行时有哪些类已经加载了以及相关的信息,我想通过Instrumentation和ClassFileTransformer去获取类的名称以及字节流,我重写了transform这个函数,可以实验发现它根本就没有被调用,这是为啥呢?
|
|
RednaxelaFX
2013-08-08
您具体写了怎样的代码…?
有没有显式调用inst.retransformClasses(inst.getAllLoadedClasses())之类的? |
|
巴海和
2013-08-09
没有呀。为什么需要显式调用呢?牛人!
|
|
巴海和
2013-08-09
RednaxelaFX 写道 您具体写了怎样的代码…?
有没有显式调用inst.retransformClasses(inst.getAllLoadedClasses())之类的? 具体代码如下: package agentmain; import java.io.FileNotFoundException; import java.io.IOException; import java.lang.instrument.Instrumentation; import java.lang.instrument.UnmodifiableClassException; public class Agent { public static void agentmain(String agentArgs, Instrumentation inst) throws FileNotFoundException, IOException { inst.addTransformer(new Transformer(), true); try { for (Class<?> c : inst.getAllLoadedClasses()) { if (c.getClassLoader() != null) if (c.getClassLoader().toString() .contains("AppClassLoader")) inst.retransformClasses(c); } } catch (UnmodifiableClassException e) { e.printStackTrace(); } } } |
|
巴海和
2013-08-09
RednaxelaFX 写道 您具体写了怎样的代码…?
有没有显式调用inst.retransformClasses(inst.getAllLoadedClasses())之类的? 具体代码如下: package agentmain; import java.io.FileNotFoundException; import java.io.IOException; import java.lang.instrument.Instrumentation; import java.lang.instrument.UnmodifiableClassException; public class Agent { public static void agentmain(String agentArgs, Instrumentation inst) throws FileNotFoundException, IOException { inst.addTransformer(new Transformer(), true); try { for (Class<?> c : inst.getAllLoadedClasses()) { if (c.getClassLoader() != null) if (c.getClassLoader().toString() .contains("AppClassLoader")) inst.retransformClasses(c); } } catch (UnmodifiableClassException e) { e.printStackTrace(); } } } |
|
巴海和
2013-08-09
package agentmain;
import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.lang.instrument.ClassFileTransformer; import java.lang.instrument.IllegalClassFormatException; import java.security.ProtectionDomain; import java.util.Properties; public class Transformer implements ClassFileTransformer { private Properties digest; private String address; public Transformer() { digest = new Properties(); address = System.getProperty("user.home") + File.separator + ".tjvm" + File.separator + "agent" + File.separator + "RunningClass.xml"; File parent = new File(address).getParentFile(); if (!parent.exists()) { parent.getParentFile().mkdirs(); } } @Override public byte[] transform(ClassLoader classloader, String classname, Class<?> redefinedclass, ProtectionDomain protectiondomain, byte b[]) throws IllegalClassFormatException { if (classloader.toString().contains("AppClassLoader")) { String name = classname.replace(File.separator, "."); try { if (new File(address).exists()) { digest.load(new FileInputStream(address)); } else { System.out.println("Error: not find digest table!"); // System.exit(0); } } catch (FileNotFoundException e1) { e1.printStackTrace(); } catch (IOException e1) { e1.printStackTrace(); } String value = Digest.measure(b, "SHA"); if (digest.containsKey(name)) { String v = digest.getProperty(name); if (v.contains(value)) { System.out.printf("%-40s %-40s %-5s\n", name, value, true); } else { System.out.printf("%-40s %-40s %-5s\n", name, value, false); } } else { System.out.println("Error: not have this class: " + name); } } return null; } } 这里有问题,通过premain获取到类的字节流与通过agentmain获取到的类的字节流是不一样的,为什么? |
|
巴海和
2013-08-09
package agentmain;
import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; public class Digest { public static String measure(byte[] sBytes, String arithmetic) { try { MessageDigest sha = MessageDigest.getInstance(arithmetic); sha.update(sBytes); byte[] rBytes = sha.digest(); return byteArrayToHexString(rBytes); } catch (NoSuchAlgorithmException e) { return null; } } // byte to HexString private static String byteToHexString(byte b) { char[] Digit = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; char[] c = new char[2]; c[0] = Digit[b >>> 4 & 0x0F]; c[1] = Digit[b & 0x0F]; String s = new String(c); return s; } // byte[] to HexString private static String byteArrayToHexString(byte[] byteArray) { String strDigest = ""; for (int i = 0; i < byteArray.length; i++) { strDigest += byteToHexString(byteArray[i]); } return strDigest; } } |
|
巴海和
2013-08-09
package main;
import java.io.IOException; import com.sun.tools.attach.AgentInitializationException; import com.sun.tools.attach.AgentLoadException; import com.sun.tools.attach.AttachNotSupportedException; import rm.RMeasure; public class Monitor { public static void main(String[] args) { RMeasure rm=new RMeasure("/home/kylin/AgentMain.jar"); try { rm.measure(); } catch (AttachNotSupportedException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (AgentLoadException e) { e.printStackTrace(); } catch (AgentInitializationException e) { e.printStackTrace(); } } } |
|
巴海和
2013-08-09
package rm;
import java.io.IOException; //import java.util.List; import com.sun.tools.attach.AgentInitializationException; import com.sun.tools.attach.AgentLoadException; import com.sun.tools.attach.AttachNotSupportedException; import com.sun.tools.attach.VirtualMachine; //import com.sun.tools.attach.VirtualMachineDescriptor; public class RMeasure { private String address; //private List<VirtualMachineDescriptor> vmds; public RMeasure(String address){ this.address=address; //vmds=null; } public void measure() throws AttachNotSupportedException, IOException, AgentLoadException, AgentInitializationException{ //vmds=VirtualMachine.list(); VirtualMachine vm=null; //for(VirtualMachineDescriptor vmd:vmds){ vm=VirtualMachine.attach("20991"); vm.loadAgent(address); try { System.out.println("Waiting......"); Thread.sleep(10000); } catch (InterruptedException e) { e.printStackTrace(); } vm.detach(); //Thread.sleep(10000); //} } } |
|
巴海和
2013-08-09
RednaxelaFX 写道 您具体写了怎样的代码…?
有没有显式调用inst.retransformClasses(inst.getAllLoadedClasses())之类的? 现在有调用了,可是获取到的字节流与通过premain获取到的字节流是不一样的,为什么呢? PS: 不能显式调用inst.retransformClasses(inst.getAllLoadedClasses()),会报agent已加载但无法初始化的错误,为什么呢? |