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已加载但无法初始化的错误,为什么呢?
Global site tag (gtag.js) - Google Analytics