目的:
程序分析:用于分析程序,动态生成proxy等。
程序生成:可在内存中生成java类并编译,所谓的just in time complie
程序转换:优化程序插入debugging或平台观察代码(AOP)
ASM库提供生成、转换类的2种API,一直API是基于事件一种是基于数的。基于事件的就类似于xml的SAX,而基于树的就像DOM.这2种API都有各自的有点与缺点。基于事件的API快速并且需要的内存比基于树的少。
组织结构:
org.objectweb.asm与org.objectweb.asm.signature是定义基于事件的API并提供了class的读写组建。
org.objectweb.asm.util是工具包。
org.objectweb.asm.commons定义了预定义类的转行器
org.objectweb.asm.tree定义了基于树的API
org.objectweb.asm.tree.analysis定义了基于树API的分析框架和预定义类的分析器
java字节码的结构
+----------------------------------------------------+
|Modifiers, name, super class, interfaces |
+----------------------------------------------------+
|Constant pool: numeric, string and type constants |
+----------------------------------------------------+
|Source file name (optional) |
+----------------------------------------------------+
|Enclosing class reference |
+----------------------------------------------------+
|Annotation* |
+----------------------------------------------------+
|Attribute* |
+----------------------------------------------------+
|Inner class* Name |
+----------------------------------------------------+
|Field* Modifiers, name, type |
| Annotation* |
| Attribute* |
+----------------------------------------------------+
|Method* Modifiers, name, return and parameter types |
| Annotation* |
| Attribute* |
| Compiled code |
+----------------------------------------------------+
内部名
在class文件里面使用的是内部名,如String的内部名是 java/lang/String
类型描述:
java类型->类型描述
boolean->Z
char->C
byte->B
short->S
int->I
float->F
long->J
double->D
Object->Ljava/lang/Object;
int[]->[I
Object[][]->[[Ljava/lang/Object;
方法描述:
方法描述是类型描述列表,用于描述方法的参数类型以及返回值类型
方法声明->方法描述
void m(int i, float f)->(IF)V
int m(Object o)->(Ljava/lang/Object;)I
int[] m(int i, String s)->(ILjava/lang/String;)[I
Object m(int[] i)->([I)Ljava/lang/Object;
生成和解析编译好的类文件是基于ClassVisitor接口。这个接口的每个方法对应类文件相同的段名如下:
public interface ClassVisitor {
void visit(int version, int access, String name, String signature,
String superName, String[] interfaces);
void visitSource(String source, String debug);
void visitOuterClass(String owner, String name, String desc);
AnnotationVisitor visitAnnotation(String desc, boolean visible);
void visitAttribute(Attribute attr);
void visitInnerClass(String name, String outerName, String innerName,
int access);
FieldVisitor visitField(int access, String name, String desc,
String signature, Object value);
MethodVisitor visitMethod(int access, String name, String desc,
String signature, String[] exceptions);
void visitEnd();
}
使用方法必须符合下面规则:
visit visitSource? visitOuterClass? ( visitAnnotation | visitAttribute )*
( visitInnerClass | visitField | visitMethod )*
visitEnd
visit必须是第一个被调用的方法,然后调用visitOuterClass,接着调用visitAnnotation和visitAttribute依次类推,最后调用visitEnd
ASM提供3个核心基于ClassVisitor的3个核心组件用于产生解析类:
1、ClassReader解析已经编译好的类文件,调用对应的VisitXxx方法
2、ClassWriter实现了ClassVisitor接口,生成类
3、ClassAdapter实现了ClassVisitor接口,代理调用接口的所有方法
以下是类解析的例子相关信息,通过Visitor打印类
- package com.appspot.coder9527;
-
-
import java.io.IOException;
-
-
import org.objectweb.asm.AnnotationVisitor;
-
import org.objectweb.asm.Attribute;
-
import org.objectweb.asm.ClassReader;
-
import org.objectweb.asm.ClassVisitor;
-
import org.objectweb.asm.FieldVisitor;
-
import org.objectweb.asm.MethodVisitor;
-
-
public class ClassInfoVisitor implements ClassVisitor {
-
@Override
-
public void visit(int version, int access, String name, String signature,
- String superName, String[] interfaces) {
-
System.out.println(name + " extends " + superName + " {");
- }
-
@Override
-
public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
-
return null;
- }
-
@Override
-
public void visitAttribute(Attribute attr) {
- }
-
@Override
-
public void visitEnd() {
-
System.out.println("}");
- }
-
@Override
-
public FieldVisitor visitField(int access, String name, String desc,
- String signature, Object value) {
-
System.out.println(" " + desc + " " + name);
-
return null;
- }
-
@Override
-
public void visitInnerClass(String name, String outerName,
-
String innerName, int access) {
- }
-
@Override
-
public MethodVisitor visitMethod(int access, String name, String desc,
- String signature, String[] exceptions) {
-
System.out.println(" " + name + desc);
-
return null;
- }
-
@Override
-
public void visitOuterClass(String owner, String name, String desc) {
- }
-
@Override
-
public void visitSource(String source, String debug) {
- }
-
public static void main(String argv[]) throws IOException {
-
ClassReader reader = new ClassReader("com.appspot.coder9527.ClassInfoVisitor");
-
ClassInfoVisitor visitor = new ClassInfoVisitor();
-
reader.accept(visitor, 0);
- }
- }
package com.appspot.coder9527;
import java.io.IOException;
import org.objectweb.asm.AnnotationVisitor;
import org.objectweb.asm.Attribute;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.FieldVisitor;
import org.objectweb.asm.MethodVisitor;
public class ClassInfoVisitor implements ClassVisitor {
@Override
public void visit(int version, int access, String name, String signature,
String superName, String[] interfaces) {
System.out.println(name + " extends " + superName + " {");
}
@Override
public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
return null;
}
@Override
public void visitAttribute(Attribute attr) {
}
@Override
public void visitEnd() {
System.out.println("}");
}
@Override
public FieldVisitor visitField(int access, String name, String desc,
String signature, Object value) {
System.out.println(" " + desc + " " + name);
return null;
}
@Override
public void visitInnerClass(String name, String outerName,
String innerName, int access) {
}
@Override
public MethodVisitor visitMethod(int access, String name, String desc,
String signature, String[] exceptions) {
System.out.println(" " + name + desc);
return null;
}
@Override
public void visitOuterClass(String owner, String name, String desc) {
}
@Override
public void visitSource(String source, String debug) {
}
public static void main(String argv[]) throws IOException {
ClassReader reader = new ClassReader("com.appspot.coder9527.ClassInfoVisitor");
ClassInfoVisitor visitor = new ClassInfoVisitor();
reader.accept(visitor, 0);
}
}
来看看ClassReader,要了解ClassReader.
首先要理解要理解Class文件定义的格式
struct Class_File_Format {
u4 magic_number; //4个字节的魔幻数 是16进制的0xcafe 0xbabe cafe呵呵有点好耍
u2 minor_version; //2个字节的主版本号
u2 major_version; //2个字节次版本号
u2 constant_pool_count; //常量池大小
cp_info constant_pool[constant_pool_count - 1]; //常量池信息
u2 access_flags; //类或接口访问表示
u2 this_class; //本类在常量池的索引
u2 super_class; //父类在常量池的索引
u2 interfaces_count; //接口计数
u2 interfaces[interfaces_count]; //接口对应常量池的索引
u2 fields_count; //类的域个数
field_info fields[fields_count]; //域数据,包括属性名称索引,域修饰符掩码等
u2 methods_count; //方法计数
method_info methods[methods_count]; //方法信息
u2 attributes_count; //类附加属性个数
attribute_info attributes[attributes_count];//类附加属性数据,包括源文件名等。
};
看看常量表cp_info的定义。
cp_info {
u1 tag;
u1 info[];
}
cp_info的tag保存着类型信息,如下:
类型 值
CONSTANT_Class 7
CONSTANT_Fieldref 9
CONSTANT_Methodref 10
CONSTANT_InterfaceMethodref 11
CONSTANT_String 8
CONSTANT_Integer 3
CONSTANT_Float 4
CONSTANT_Long 5
CONSTANT_Double 6
CONSTANT_NameAndType 12
CONSTANT_Utf8 1
指定的类型又显示了info指向的每种结构,比如CONSTANT_Class这种类型的指向的结构是
CONSTANT_Class_info {
u1 tag;
u2 name_index;
}
以下是Class_File_Format的结构图
分享到:
相关推荐
asm-1.3.3.jar, asm-1.3.4.jar, asm-1.3.5.jar, asm-1.4.1.jar, asm-1.4.2.jar, asm-1.4.3.jar, asm-1.4.jar, asm-1.5.1.jar, asm-1.5.2.jar, asm-1.5.3.jar, asm-2.0.jar, asm-2.1.jar, asm-2.2.1-sources.jar, asm...
汇编工具ASM汇编工具ASM汇编工具ASM汇编工具ASM汇编工具ASM
包含如下oracleasm包: kmod-oracleasm-2.0.6.rh1-3.el6.x86_64.rpm oracleasm-2.0.8-4.el6_6.src.rpm oracleasm-2.0.8-6.el6_7.src.rpm oracleasm-2.0.8-8.el7.src.rpm oracleasm-2.0.8-15.el7.centos.src.rpm ...
EditPlus是很好用的编辑软件 但网上下的很多EP版本需要自己添加asm.acp,asm.stx,不是很方便 这个里面附带了asm.acp,asm.stx
开发工具 asm-5.1开发工具 asm-5.1开发工具 asm-5.1开发工具 asm-5.1开发工具 asm-5.1开发工具 asm-5.1开发工具 asm-5.1开发工具 asm-5.1开发工具 asm-5.1开发工具 asm-5.1开发工具 asm-5.1开发工具 asm-5.1开发工具...
ASM4使用指南 ASM GUIDE
赠送jar包:asm-9.1.jar; 赠送原API文档:asm-9.1-javadoc.jar; 赠送源代码:asm-9.1-sources.jar; 赠送Maven依赖信息文件:asm-9.1.pom; 包含翻译后的API文档:asm-9.1-javadoc-API文档-中文(简体)版.zip; ...
ASM1061 原理图 PCIE转2 port Sata芯片 ASM1061 原理图 PCIE转2 port Sata芯片
asm-util-1.3.4.jar, asm-util-1.3.5.jar, asm-util-1.4.1.jar, asm-util-1.4.3.jar, asm-util-1.5.1.jar, asm-util-1.5.2.jar, asm-util-1.5.3.jar, asm-util-2.0.jar, asm-util-2.1.jar, asm-util-2.2.1-sources....
盈高入网要求规范管理系统ASM6000产品说明书V1.1.pdf盈高入网要求规范管理系统ASM6000产品说明书V1.1.pdf盈高入网要求规范管理系统ASM6000产品说明书V1.1.pdf盈高入网要求规范管理系统ASM6000产品说明书V1.1.pdf盈高...
ASM实例+ASM数据库安装(Win8+Ora10) 1 第一篇 创建未格式化的磁盘分区 1 1.1 打开压缩卷窗口 1 1.2 输入卷大小 3 1.3 选择挂载目录 4 1.4 格式化分区选项 5 1.5汇总信息 6 1.6分区完成后磁盘情况 7 1.7挂载目录...
ASM内网安全解决方案ASM内网安全解决方案ASM内网安全解决方案ASM内网安全解决方案ASM内网安全解决方案ASM内网安全解决方案ASM内网安全解决方案ASM内网安全解决方案ASM内网安全解决方案ASM内网安全解决方案ASM内网...
oracle不使用oracleasm的包配置ASM磁盘配置方法
Oracle 10.2 ASM 最佳实践 ASM installation ASM SGA and parameter sizing ASM and privileges ASMLIB Disks ASM and Multipathing DiskGroups Diskgroups and databases ASM redundancy and Failure Groups New ...
赠送jar包:asm-4.2.jar; 赠送原API文档:asm-4.2-javadoc.jar; 赠送源代码:asm-4.2-sources.jar; 赠送Maven依赖信息文件:asm-4.2.pom; 包含翻译后的API文档:asm-4.2-javadoc-API文档-中文(简体)版.zip; ...
java字节码操作相关工具asm asm-util asm-tree asm-analysis
ASM7使用指南;
asm1053 asm1153e datasheet asm1053 asm1153e 手册
ASM1153 USB转sata芯片datasheet
ASM1166datasheet.pdf