`

使用javassist对.class文件进行修改

    博客分类:
  • java
阅读更多

最近重新再看<Inside JVM>,对JAVA编译成的字节码结构很感兴趣,希望找个工具能够对.class文件进行的解析和查看。没找到,倒发现javaassist可以对字节码进行操作和修改。此工具是JBOSS项目的一部分,JBOSS实现AOP的基础。呵呵,开眼界了,原来我们可以直接对字节码文件进行修改,哪怕不知道源文件(跟反编译完全不同)。一个简单例子:

import javassist.*;
class Hello {
    public void say() {
        System.out.println("Hello");
    }
}

public class Test {
    public static void main(String[] args) throws Exception {
        ClassPool cp = ClassPool.getDefault();
        CtClass cc = cp.get("Hello");
        CtMethod m = cc.getDeclaredMethod("say");
        m.setBody("{System.out.println(/"/");}");
        m.insertBefore("System.out.println(/"/");");
        Class c = cc.toClass();
        Hello h = (Hello)c.newInstance();
        h.say();
    }
}

编译运行此文件,输出:

我们在

 CtMethod m = cc.getDeclaredMethod("say");
  m.setBody("{System.out.println(/"/");}");

  m.insertBefore("System.out.println(/"/");");

修改了say()方法,改成了

System.out.println("");

System.out.println("");

这里的ClassPool是CtClass的容器,它读取class文件,并根据要求保存CtClass的结构以便日后使用,默认状态下是从当前的类装载器获得,当然你可以指定:

pool.insertClassPath("/usr/local/javalib");

当然,不仅仅是修改方法,你还可以新建一个class,利用makeClass()方法,如:

ClassPool pool = ClassPool.getDefault();
CtClass cc = pool.makeClass("Point");

还可以新增方法,下面是sample里的一个例子,同样的:

package sample;

import javassist.*;
import java.lang.reflect.*;

/*
   A very simple sample program

   This program overwrites sample/Test.class (the class file of this
   class itself) for adding a method g().  If the method g() is not
   defined in class Test, then this program adds a copy of
   f() to the class Test with name g().  Otherwise, this program does
   not modify sample/Test.class at all.

   To see the modified class definition, execute:

   % javap sample.Test

   after running this program.
*/
public class Test {
    public int f(int i) {
     i++;
    return i;
    }

    public static void main(String[] args) throws Exception {
 ClassPool pool = ClassPool.getDefault();

 CtClass cc = pool.get("sample.Test");
 Test test=new Test();
 Class c=test.getClass();
 Method []method=c.getDeclaredMethods();
 for(int i=0;i<method.length;i++){
  System.out.println(method[i]);
 }
 try {
     cc.getDeclaredMethod("g");
     System.out.println("g() is already defined in sample.Test.");
 }
 catch (NotFoundException e) {
     /* getDeclaredMethod() throws an exception if g()
      * is not defined in sample.Test.
      */
     CtMethod fMethod = cc.getDeclaredMethod("f");
     CtMethod gMethod = CtNewMethod.copy(fMethod, "g", cc, null);
     cc.addMethod(gMethod);
     cc.writeFile(); // update the class file
     System.out.println("g() was added.");
 }
    }
}
第一次运行时,因为Test里并没有g()方法,所以执行

 CtMethod fMethod = cc.getDeclaredMethod("f");
     CtMethod gMethod = CtNewMethod.copy(fMethod, "g", cc, null);  //把f方法复制给g
     cc.addMethod(gMethod);
     cc.writeFile(); //更新class文件

     System.out.println("g() was added.");
打印:g() was added

第2次运行时,因为以上步骤已经在class文件中增加了一个g方法,所以

 System.out.println("g() is already defined in sample.Test.");
打印:g() is already defined in sample.Test

 

Javassist不仅能修改你自己的class文件,而且可以同样修改JDK自带的类库(废话,类库也是人写的^_^)具体请看它的tutorial。

分享到:
评论
1 楼 liuxuejin 2011-08-16  
好东西啊!!

相关推荐

    使用Javassist对.class文件进行修改.doc

    Javassist 提供了一套 API,使得开发者可以轻松地对 `.class` 文件进行解析、修改和生成,即使没有原始的源代码。 在给定的例子中,展示了如何使用 Javassist 修改已有的 `.class` 文件中的方法。以下是一些关键...

    使用javassist修改class文件.pdf

    使用javassist修改class文件.pdf

    javassistDemo.zip

    - 保存或加载修改:修改完成后,可以使用`toClass()`方法将CtClass对象转换回实际的Java类,或者将其保存为新的.class文件。 这个"javassistDemo.zip"的示例可能涵盖了这些基本操作,并提供了具体的代码示例,帮助...

    借助jclasslib与javassist修改java class字节码

    通过遍历常量池找到对应的字符串,并使用`javassist`提供的API进行修改。 3. **写入新的`.class`文件**: 最后将修改后的字节码重新写入到一个新的`.class`文件中。 以下是一段使用`javassist`实现上述功能的...

    修改.class文件.zip

    总结来说,修改.class文件涉及到使用如jclasslib这样的工具进行分析,以及编写Java程序利用javassist等库进行字节码级别的修改。这个过程需要对Java虚拟机的工作原理、字节码表示以及反射有充分的理解。务必谨慎操作...

    javassist-3.7.ga.jar

    `javassist-3.7.ga.jar` 文件是 Javaassist 库的一个版本,版本号为 3.7 GA(General Availability),意味着这是一个公开可用的稳定版本。 Javaassist 提供了一系列的 API,使得开发者可以方便地读取、修改和创建 ...

    jclasslib与javassist案例.doc

    在没有源代码的情况下,如果我们想要修改或分析这些类文件,可以借助第三方库如`javassist`和可视化工具`jclasslib`。 `javassist`是一个强大的Java字节码操作库,它允许我们动态地修改或创建类。在给定的案例中,...

    javassist-3.9.0.GA.jar.zip

    1. **类转换(Class Transformation)**:Javaassist通过` CtClass `对象来表示Java类,我们可以加载一个已经存在的类,然后对它的字段、方法、构造函数进行添加、删除或修改。例如,我们可以动态添加一个新的方法到...

    Javassist 修改class字节码

    功能包括:运行时创建java class,修改class。与其他同类工具(asm等)不同的是,Javassist提供了两个层面的API: 1.java代码层 2.字节码层 通过java代码层,开发者即时对字节码不是很熟悉,也可以非常方便快速的...

    javassist.jar

    ava 字节码以二进制的形式存储在 .class 文件中,每一个 .class 文件包含一个 Java 类或接口。Javaassist 就是一个用来 处理 Java 字节码的类库。它可以在一个已经编译好的类中添加新的方法,或者是修改已有的方法,...

    jclasslib修改class文件

    java修改class文件使用的jclasslib.jar、javassist.jar等等文件。相关步骤、还有一个idea项目示例。(当时找了好久的jclasslib.jar文件,最后才找到一个可用的)

    运用javassist和annotation修改class的特定method的class byte code

    4. **生成新的类文件**:最后,我们需要将修改后的字节码写回到磁盘,或者在内存中直接使用这个新版本的类。 ```java ctClass.writeFile(); // 写入磁盘 // 或者 Class&lt;?&gt; modifiedClass = ctClass.toClass(); // ...

    修改javaclass工具包

    在这种情况下,如果需要对已有的`.class`文件进行修改,传统的通过修改源代码并重新编译的方式就行不通了。这时,我们就需要借助一些专门的工具来对`.class`文件进行反编译、修改和再编译。标题为“修改javaclass...

    javassist-3.18.0-GA

    4. **使用javassist修改class文件.txt**: 这个文件可能是一个示例或教程,解释了如何利用 Javaassist 修改已存在的 `.class` 文件。通过读取这个文件,开发者可以学习到如何在运行时改变类的行为,例如添加新的...

    Javassist学习手册

    一旦使用 `writeFile()`、`toClass()` 或 `toBytecode()` 方法将 `CtClass` 对象转化为类文件后,该对象就会被冻结,无法再进行任何修改。这主要是为了避免对已加载到 JVM 中的类进行非法修改。 - **解冻**: 通过...

    Java下的Class代码查看器+修改器

    Java下的Class代码查看器与修改器是用于深入理解与操作Java字节码的重要工具,它们可以帮助开发者查看并可能修改已编译的Java类文件(即.class文件),这对于调试、逆向工程、性能优化以及理解Java运行时机制具有...

    jboss-javassist和JByteMode整合包

    与Javassist不同,JByteMode专注于对字节码进行读取、分析和反编译,尤其适用于查看和修改已打包的.jar文件中的.class文件。其特点包括: 1. 能够将字节码反编译为可读的Java源代码。 2. 提供了修改已编译类的方法,...

    javassist-3.18.2-GA.jar

    8. **ClassFile** 和 **ConstPool**:这两个类分别代表 Class 文件结构和常量池,提供了对 Java 类文件底层结构的访问。 在实际应用中,Javaassist 常用于 AOP(面向切面编程)、动态代理、性能监控、测试工具和...

    通过自定义Gradle插件修改编译后的class文件

    下面是一个简单的自定义Gradle插件示例,展示了如何使用ByteBuddy修改编译后的class文件: 1. 创建一个新的Gradle插件项目,包含以下目录结构: ``` my-plugin/ ├── src/main/groovy │ └── ...

Global site tag (gtag.js) - Google Analytics