java asm 修改jar 包源代码

1.实体类

[java]  view plain  copy
 print ?
  1. package com.study.asm;  
  2.   
  3. public class Person {  
  4.   
  5.     private String name;  
  6.     public void sayName(){  
  7.         System.out.println(name);  
  8.     }  
  9. }  


2.Client

[java]  view plain  copy
 print ?
  1. package com.study.asm;  
  2.   
  3. import java.io.File;  
  4. import java.io.FileOutputStream;  
  5.   
  6. import org.objectweb.asm.ClassAdapter;  
  7. import org.objectweb.asm.ClassReader;  
  8. import org.objectweb.asm.ClassVisitor;  
  9. import org.objectweb.asm.ClassWriter;  
  10. import org.objectweb.asm.MethodAdapter;  
  11. import org.objectweb.asm.MethodVisitor;  
  12. import org.objectweb.asm.Opcodes;  
  13. import org.objectweb.asm.Type;  
  14.   
  15.   
  16. public class GenerateNewPerson {  
  17.   
  18.     public static void main(String[] args) throws Exception{  
  19.           
  20.         // 使用全限定名,创建一个ClassReader对象     
  21.         ClassReader classReader = new ClassReader("com.study.asm.Person");  
  22.           
  23.         // 构建一个ClassWriter对象,并设置让系统自动计算栈和本地变量大小  
  24.         ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_MAXS);  
  25.           
  26.         ClassAdapter classAdapter = new GeneralClassAdapter(classWriter);  
  27.           
  28.         classReader.accept(classAdapter, ClassReader.SKIP_DEBUG);  
  29.           
  30.         byte[] classFile = classWriter.toByteArray();  
  31.           
  32.         File file = new File("D://Person.class");  
  33.           
  34.         FileOutputStream fos = new FileOutputStream(file);  
  35.         fos.write(classFile);  
  36.         fos.close();  
  37.           
  38.     }  
  39. }  
  40.      class GeneralClassAdapter extends ClassAdapter{  
  41.   
  42.         public GeneralClassAdapter(ClassVisitor cv) {  
  43.             super(cv);  
  44.         }  
  45.           
  46.         @Override  
  47.         public MethodVisitor visitMethod(int access, String name, String desc,  
  48.                 String signature, String[] exceptions) {  
  49.             MethodVisitor mv = cv.visitMethod(access, name, desc, signature, exceptions);  
  50.             // 当是sayName方法是做对应的修改     
  51.             if(name.equals("sayName")){  
  52.                 MethodVisitor newMv = new sayNameMethodAdapter(mv);  
  53.                 return newMv;  
  54.             }else{  
  55.                 return mv;  
  56.             }  
  57.         }  
  58.           
  59.         // 定义一个自己的方法访问类   
  60.         class sayNameMethodAdapter extends MethodAdapter{  
  61.   
  62.             public sayNameMethodAdapter(MethodVisitor mv) {  
  63.                 super(mv);  
  64.             }  
  65.               
  66.             // 在源方法前去修改方法内容,这部分的修改将加载源方法的字节码之前  
  67.             @Override  
  68.             public void visitCode() {  
  69.                 // 记载隐含的this对象,这是每个JAVA方法都有的  
  70.                 mv.visitVarInsn(Opcodes.ALOAD, 0);  
  71.                 // 从常量池中加载“yy”字符到栈顶    
  72.                 mv.visitLdcInsn("yy");  
  73.                 // 将栈顶的"yy"赋值给name属性    
  74.                 mv.visitFieldInsn(Opcodes.PUTFIELD, Type.getInternalName(Person.class), "name", Type.getDescriptor(String.class));  
  75.             }  
  76.         }  
  77.     }  


3.结果

通过jd-gui反编译后,得到的结果如下:

[java]  view plain  copy
 print ?
  1. package com.study.asm;  
  2.   
  3. import java.io.PrintStream;  
  4.   
  5. public class Person  
  6. {  
  7.   private String name;  
  8.   
  9.   public void sayName()  
  10.   {  
  11.     this.name = "yy";  
  12.     System.out.println(this.name);  
  13.   }  
  14. }  


通过javap -c Person命令,得到如下结果:

[java]  view plain  copy
 print ?
  1. public class com.study.asm.Person extends java.lang.Object{  
  2. public com.study.asm.Person();  
  3.   Code:  
  4.    0:   aload_0  
  5.    1:   invokespecial   #10//Method java/lang/Object."<init>":()V  
  6.    4:   return  
  7.   
  8. public void sayName();  
  9.   Code:  
  10.    0:   aload_0  
  11.    1:   ldc     #13//String yy  
  12.    3:   putfield        #15//Field name:Ljava/lang/String;  
  13.    6:   getstatic       #21//Field java/lang/System.out:Ljava/io/PrintStream;  
  14.    9:   aload_0  
  15.    10:  getfield        #15//Field name:Ljava/lang/String;  
  16.    13:  invokevirtual   #27//Method java/io/PrintStream.println:(Ljava/lang/St  
  17. ring;)V  
  18.    16:  return  
  19.   
  20. }  
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值