Javassist
实现类方法修改比ASM简单多了,我们只需要调用CtMethod
类的对应的API就可以了。CtMethod
提供了类方法修改的API,如:setModifiers
可修改类的访问修饰符,insertBefore
和insertAfter
能够实现在类方法执行的前后插入任意的Java代码片段,setBody
可以修改整个方法的代码等。
Javassist修改类方法示例代码:**
package com.anbai.sec.bytecode.javassist;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtMethod;
import javassist.Modifier;
import org.javaweb.utils.FileUtils;
import java.io.File;
public class JavassistClassModifyTest {
public static void main(String[] args) {
// 创建ClassPool对象
ClassPool classPool = ClassPool.getDefault();
try {
CtClass ctClass = classPool.get("com.anbai.sec.bytecode.TestHelloWorld");
// 获取hello方法
CtMethod helloMethod = ctClass.getDeclaredMethod("hello", new CtClass[]{classPool.get("java.lang.String")});
// 修改方法的访问权限为private
helloMethod.setModifiers(Modifier.PRIVATE);
// 输出hello方法的content参数值
helloMethod.insertBefore("System.out.println($1);");
// 输出hello方法的返回值
helloMethod.insertAfter("System.out.println($_); return \"Return:\" + $_;");
File classFilePath = new File(new File(System.getProperty("user.dir"), "javaweb-sec-source/javase/src/main/java/com/anbai/sec/bytecode/"), "TestHelloWorld.class");
// 使用类CtClass,生成类二进制
byte[] bytes = ctClass.toBytecode();
// 将class二进制内容写入到类文件
FileUtils.writeByteArrayToFile(classFilePath, bytes);
} catch (Exception e) {
e.printStackTrace();
}
}
}
程序执行后结果如下: