理解字节码java
是否可以从java字节码中读取或识别INVOKESPECIAL指令引用的类?如果是,如何进行?另外,我如何知道跳转后下一行将执行什么理解字节码java,java,exception,jvm,bytecode,Java,Exception,Jvm,Bytecode,是否可以从java字节码中读取或识别INVOKESPECIAL指令引用的类?如果是,如何进行?另外,我如何知道跳转后下一行将执行什么 请记住,我想做一个这样的程序。我想做的是找到一种方法,仅通过字节码自动本地化异常处理。您可以查看这个框架。“ASM框架是执行字节码操作最快、最灵活和最知名的框架”有很多用于字节码操作的框架。但我个人更喜欢。它的XML解析机制更容易学习 例如,您可以使用此代码列出jar文件中的所有INVOKESPECIAL调用: 它将打印如下行: INVOKESPECIAL[opc
请记住,我想做一个这样的程序。我想做的是找到一种方法,仅通过字节码自动本地化异常处理。您可以查看这个框架。“ASM框架是执行字节码操作最快、最灵活和最知名的框架”有很多用于字节码操作的框架。但我个人更喜欢。它的XML解析机制更容易学习 例如,您可以使用此代码列出jar文件中的所有
INVOKESPECIAL
调用:
它将打印如下行:
INVOKESPECIAL[opcode=183,owner=java/lang/StringBuilder,name=,desc=()V]
您可以说,INVOKESPECIAL
引用的是java/lang/StringBuilder
的
函数
JarFile jarFile = new JarFile("xxx.jar");
Enumeration<JarEntry> entries = jarFile.entries();
while (entries.hasMoreElements()) {
JarEntry jarEntry = entries.nextElement();
if (jarEntry != null && jarEntry.getName().endsWith(".class")) {
InputStream eis = jarFile.getInputStream(jarEntry);
ClassReader classReader = new ClassReader(eis);
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
MyClassVisitor mcw = new MyClassVisitor(Opcodes.ASM4, cw);
classReader.accept(mcw, 0);
eis.close();
}
}
class MyClassVisitor extends ClassVisitor {
private int api;
public MyClassVisitor(int api, ClassWriter cw) {
super(api, cw);
this.api = api;
}
@Override
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions);
return new MyMethodVisitor(api, mv);
}
class MyMethodVisitor extends MethodVisitor {
public MyMethodVisitor(int api, MethodVisitor mv) {
super(api, mv);
}
@Override
public void visitMethodInsn(int opcode, String owner, String name, String desc) {
if (opcode == Opcodes.INVOKESPECIAL) {
System.out.println("INVOKESPECIAL[ opcode=" + opcode + ", owner=" + owner + ", name=" + name
+ ", desc=" + desc+"]");
}
super.visitMethodInsn(opcode, owner, name, desc);
}
}
}
JarFile-JarFile=newjarfile(“xxx.jar”);
枚举条目=jarFile.entries();
while(entries.hasMoreElements()){
JarEntry JarEntry=entries.nextElement();
if(jarEntry!=null&&jarEntry.getName().endsWith(“.class”)){
InputStream eis=jarFile.getInputStream(jarEntry);
ClassReader ClassReader=新的ClassReader(eis);
ClassWriter cw=新的ClassWriter(ClassWriter.COMPUTE\u MAXS);
MyClassVisitor mcw=新的MyClassVisitor(opcode.ASM4,cw);
classReader.accept(mcw,0);
eis.close();
}
}
类MyClassVisitor扩展了ClassVisitor{
私有int api;
公共MyClassVisitor(intAPI、ClassWriter cw){
超级(api,cw);;
this.api=api;
}
@凌驾
public方法访问者访问方法(int访问、字符串名称、字符串描述、字符串签名、字符串[]异常){
MethodVisitor mv=super.visitMethod(访问、名称、描述、签名、异常);
返回新的MyMethodVisitor(api、mv);
}
类MyMethodVisitor扩展了MethodVisitor{
公共MyMethodVisitor(intAPI、MethodVisitor mv){
超级(api,mv);
}
@凌驾
public void visitMethodInsn(int操作码、字符串所有者、字符串名称、字符串描述){
if(opcode==opcode.INVOKESPECIAL){
System.out.println(“INVOKESPECIAL[opcode=“+opcode+”,owner=“+owner+”,name=“+name
+“,desc=“+desc+”]”;
}
超级访问方法(操作码、所有者、名称、描述);
}
}
}
异常处理位于异常表中,该表列出了从正常执行到捕获块的重定向。您指的是哪个类?你是指首先定义方法的类/接口,还是实际被调用的方法?如果存在I/O异常,I/O异常类将被调用,对吗?我想知道调用的是这个类如果你有异常抛出的位置,那么你可以检查invokespecial字节码,看看哪个类正在初始化。如果只有捕获异常的位置,则只能检测异常的类型,而不能检测其类别(例如,IOException
vsFileNotFoundException
)。ASM框架向我显示字节码,但是,我的程序如何准确地读取框架所说的内容呢?如何接收一块代码而不是一个jar文件呢?您需要将这段代码编译成.class
文件。然后你可以把它交给类阅读器
!好的,但是如果我接收每个字节码指令的字节码指令,我可以一次给类读取器一条指令吗?不,我认为这在类读取器
中是不可能的。你能详细说明一下吗?您从何处以何种顺序获得本说明?难道不可能将收到的指令收集到.class
文件中吗?我有一个程序,可以获取字节码并将其划分为块。我需要做的是确定哪些块有异常处理,所以我想我可以搜索每个块中的每个指令来找到invokespecial指令,然后看看这些invokespecial是否调用了一些异常处理类。我只是不知道如何实现这个