`
shihuan830619
  • 浏览: 576637 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Java字节码删除或者添加一个类方法

    博客分类:
  • asm
阅读更多
以下代码需要asm-5.0.2.jar和asm-commons-5.0.2.jar两个包。

package com.shihuan.method;

public class AccountMethod {

	String sql = "select * from tables";

	public AccountMethod() {
		
	}
	
	public AccountMethod(String sql) {
		super();
		this.sql = sql;
	}

	public void operation() {
        System.out.println("shihuan operation...");
    }
	
	int executeInternal() {
		
		System.out.println("shihuan executeInternal...");
		
		if (true) {
			System.out.println(this.sql);
			return 2;
		}
		
		return 3;
	}
	
}


package com.shihuan.method;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;

import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import org.objectweb.asm.commons.GeneratorAdapter;
import org.objectweb.asm.commons.Method;

public class AsmAddMethod {

	public static void main(String[] args) throws IOException {
		
		ClassReader cr = new ClassReader("com.shihuan.method.AccountMethod");
        ClassWriter cw = new ClassWriter(cr, ClassWriter.COMPUTE_MAXS);
        ClassVisitor cv = new ClassVisitor(Opcodes.ASM5, cw){};
        cr.accept(cv, Opcodes.ASM5);
        
      //新增加一个方法
        MethodVisitor mw= cw.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC,
                "add",
                "([Ljava/lang/String;)V",
                null,
                null);
        // pushes the 'out' field (of type PrintStream) of the System class
        mw.visitFieldInsn(Opcodes.GETSTATIC,
                "java/lang/System",
                "out",
                "Ljava/io/PrintStream;");
        // pushes the "Hello World!" String constant
        mw.visitLdcInsn("this is add method print!");
        // invokes the 'println' method (defined in the PrintStream class)
        mw.visitMethodInsn(Opcodes.INVOKEVIRTUAL,
                "java/io/PrintStream",
                "println",
                "(Ljava/lang/String;)V", false);
        mw.visitInsn(Opcodes.RETURN);
        // this code uses a maximum of two stack elements and two local
        // variables
        mw.visitMaxs(0, 0);
        mw.visitEnd();
        
		byte[] code = cw.toByteArray();
		OutputStream fos = new FileOutputStream("D:/myworkspace/JavaAsm/bin/com/shihuan/method/AccountMethod.class");
		fos.write(code);
		fos.close();

	}

}


package com.shihuan.method;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;

import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;

public class AsmDeleteMethod {

	public static void main(String[] args) throws IOException {
		ClassReader cr = new ClassReader("com.shihuan.method.AccountMethod");
		ClassWriter cw = new ClassWriter(cr, ClassWriter.COMPUTE_MAXS);
		ClassVisitor cv = new ClassVisitor(Opcodes.ASM5, cw) {
			
			public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
				if("executeInternal".equals(name)) {
		            return null;
		        }
				return super.visitMethod(access, name, desc, signature, exceptions); //不为null,保留
		    }
			
		};
		cr.accept(cv, ClassReader.SKIP_DEBUG);

		byte[] code = cw.toByteArray();
		OutputStream fos = new FileOutputStream("D:/myworkspace/JavaAsm/bin/com/shihuan/method/AccountMethod.class");
		fos.write(code);
		fos.close();
	}

}


AsmAddMethod2.java这种方式会清空掉AccountMethod.java文件中的所有内容,然后加入新方法,一般用的情况比较少。
package com.shihuan.method;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;

import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import org.objectweb.asm.commons.GeneratorAdapter;
import org.objectweb.asm.commons.Method;

public class AsmAddMethod2 {

	public static void main(String[] args) throws IOException {

		ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
		cw.visit(38, Opcodes.ACC_PUBLIC, "com.shihuan.method.AccountMethod", null, "java/lang/Object", null);
		Method m = Method.getMethod("void <init> ()");
		GeneratorAdapter ga = new GeneratorAdapter(Opcodes.ACC_PUBLIC, m, null, null, cw);
		ga.loadThis();
		ga.invokeConstructor(Type.getType(Object.class), m);
		ga.returnValue();
		ga.endMethod();

		m = Method.getMethod("void doSomething()");
		ga = new GeneratorAdapter(Opcodes.ACC_PUBLIC, m, null, null, cw);
		ga.getStatic(Type.getType(System.class), "out", Type.getType(PrintStream.class));
		ga.push("动态生成,动态加载调用方法");
		ga.invokeVirtual(Type.getType(PrintStream.class), Method.getMethod("void println(String)"));
		ga.returnValue();
		ga.endMethod();

		byte[] code = cw.toByteArray();
		OutputStream fos = new FileOutputStream("D:/myworkspace/JavaAsm/bin/com/shihuan/method/AccountMethod.class");
		fos.write(code);
		fos.close();

	}

}
分享到:
评论

相关推荐

    java混淆器ProGuard4.7

    ProGuard是一个压缩、优化和混淆Java字节码文件的免费的工具,它可以删除无用的类、字段、方法和属性。可以删除没用的注释,最大限度地优化字节码文件。它还可以使用简短的无意义的名称来重命名已经存在的类、字段、...

    JAVA_API1.6文档(中文)

    java.util.concurrent.locks 为锁和等待条件提供一个框架的接口和类,它不同于内置同步和监视器。 java.util.jar 提供读写 JAR (Java ARchive) 文件格式的类,该格式基于具有可选清单文件的标准 ZIP 文件格式。 ...

    java源码包---java 源码 大量 实例

     Tcp服务端与客户端的JAVA实例源代码,一个简单的Java TCP服务器端程序,别外还有一个客户端的程序,两者互相配合可以开发出超多的网络程序,这是最基础的部分。 递归遍历矩阵 1个目标文件,简单! 多人聊天室 3...

    JAVA上百实例源码以及开源项目

     Tcp服务端与客户端的JAVA实例源代码,一个简单的Java TCP服务器端程序,别外还有一个客户端的程序,两者互相配合可以开发出超多的网络程序,这是最基础的部分。 递归遍历矩阵 1个目标文件,简单! 多人聊天室 3...

    西工大JavaUML实验报告一.doc

    * 创建一个名称为 Vehicle 的接口,在接口中添加两个带有一个参数的方法 start() 和 stop()。在两个名称分别为 Bike 和 Bus 的类中实现 Vehicle 接口。 * 创建一个名称为 interfaceDemo 的类,在 interfaceDemo 的 ...

    JAVA上百实例源码以及开源项目源代码

     Tcp服务端与客户端的JAVA实例源代码,一个简单的Java TCP服务器端程序,别外还有一个客户端的程序,两者互相配合可以开发出超多的网络程序,这是最基础的部分。 递归遍历矩阵 1个目标文件,简单! 多人聊天室 3...

    java开源包11

    JCarder 是一个用来查找多线程应用程序中一些潜在的死锁,通过对 Java 字节码的动态分析来完成死锁分析。 Java的Flash解析、生成器 jActionScript jActionScript 是一个使用了 JavaSWF2 的 Flash 解析器和生成器。...

    java开源包6

    JCarder 是一个用来查找多线程应用程序中一些潜在的死锁,通过对 Java 字节码的动态分析来完成死锁分析。 Java的Flash解析、生成器 jActionScript jActionScript 是一个使用了 JavaSWF2 的 Flash 解析器和生成器。...

    java开源包9

    JCarder 是一个用来查找多线程应用程序中一些潜在的死锁,通过对 Java 字节码的动态分析来完成死锁分析。 Java的Flash解析、生成器 jActionScript jActionScript 是一个使用了 JavaSWF2 的 Flash 解析器和生成器。...

    java开源包4

    JCarder 是一个用来查找多线程应用程序中一些潜在的死锁,通过对 Java 字节码的动态分析来完成死锁分析。 Java的Flash解析、生成器 jActionScript jActionScript 是一个使用了 JavaSWF2 的 Flash 解析器和生成器。...

    java开源包101

    JCarder 是一个用来查找多线程应用程序中一些潜在的死锁,通过对 Java 字节码的动态分析来完成死锁分析。 Java的Flash解析、生成器 jActionScript jActionScript 是一个使用了 JavaSWF2 的 Flash 解析器和生成器。...

    java开源包5

    JCarder 是一个用来查找多线程应用程序中一些潜在的死锁,通过对 Java 字节码的动态分析来完成死锁分析。 Java的Flash解析、生成器 jActionScript jActionScript 是一个使用了 JavaSWF2 的 Flash 解析器和生成器。...

    java开源包8

    JCarder 是一个用来查找多线程应用程序中一些潜在的死锁,通过对 Java 字节码的动态分析来完成死锁分析。 Java的Flash解析、生成器 jActionScript jActionScript 是一个使用了 JavaSWF2 的 Flash 解析器和生成器。...

    java开源包10

    JCarder 是一个用来查找多线程应用程序中一些潜在的死锁,通过对 Java 字节码的动态分析来完成死锁分析。 Java的Flash解析、生成器 jActionScript jActionScript 是一个使用了 JavaSWF2 的 Flash 解析器和生成器。...

    java api最新7.0

    java.util.concurrent.locks 为锁和等待条件提供一个框架的接口和类,它不同于内置同步和监视器。 java.util.jar 提供读写 JAR (Java ARchive) 文件格式的类,该格式基于具有可选清单文件的标准 ZIP 文件格式。 java...

    java开源包1

    JCarder 是一个用来查找多线程应用程序中一些潜在的死锁,通过对 Java 字节码的动态分析来完成死锁分析。 Java的Flash解析、生成器 jActionScript jActionScript 是一个使用了 JavaSWF2 的 Flash 解析器和生成器。...

    java开源包3

    JCarder 是一个用来查找多线程应用程序中一些潜在的死锁,通过对 Java 字节码的动态分析来完成死锁分析。 Java的Flash解析、生成器 jActionScript jActionScript 是一个使用了 JavaSWF2 的 Flash 解析器和生成器。...

    Java 1.6 API 中文 New

    java.util.concurrent.locks 为锁和等待条件提供一个框架的接口和类,它不同于内置同步和监视器。 java.util.jar 提供读写 JAR (Java ARchive) 文件格式的类,该格式基于具有可选清单文件的标准 ZIP 文件格式。 java...

    java 面试题 总结

    声明方法的存在而不去实现它的类被叫做抽象类(abstract class),它用于要创建一个体现某些基本行为的类,并为该类声明方法,但不能在该类中实现该类的情况。不能创建abstract 类的实例。然而可以创建一个变量,其...

    java源码包4

     Tcp服务端与客户端的JAVA实例源代码,一个简单的Java TCP服务器端程序,别外还有一个客户端的程序,两者互相配合可以开发出超多的网络程序,这是最基础的部分。 递归遍历矩阵 1个目标文件,简单! 多人聊天室 ...

Global site tag (gtag.js) - Google Analytics