利用javaagent,javassist 进行热修补

使用命令:

1 java -javaagent:agent.jar -jar target.jar

注意事项: 

  1. -javaagent:agent.jar "-javaagent:"后面没有空格,紧接着的是agent.jar
  2. javaagent资料可以google. 

agent.jar注意事项

  • MANIFEST.MF文件内容
    Manifest-Version: 1.0
    Premain-Class: com.xiaobai.Main
    Can-Redefine-Classes: true

注意每个":" 后面都有一个空格,不加报错

  • 外部jar引用注意. 
    要打包进agent.jar,不要以jar形式存在,否则报错找不到class文件

javassist资料不介绍了,网上很多.

例子:

  • Mian.java
    package com.xiaobai;
    
    import java.lang.instrument.Instrumentation;
    
    public class Main {
        public static void premain(String agentOps, Instrumentation inst) {
            inst.addTransformer(new NewTransformer());
        }
    }
    

      

  • NewTransformer.java
    package com.xiaobai;
    
    import javassist.*;
    
    import java.io.ByteArrayInputStream;
    import java.io.IOException;
    import java.lang.instrument.ClassFileTransformer;
    import java.lang.instrument.IllegalClassFormatException;
    
    import java.security.ProtectionDomain;
    
    /**
     * description: Transformer
     * author: xiaobai
     * data: 2016/8/30
     */
    public class NewTransformer implements ClassFileTransformer {
    
    
        @Override
        public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {
            className = className.replace("/", ".");
            if (!className.equals("com.pnfsoftware.jeb.client.AbstractClientContext"))return null;
            try {
                ClassPool classPool=ClassPool.getDefault();
                ByteArrayInputStream byteArrayInputStream=new ByteArrayInputStream(classfileBuffer);
                CtClass clazz=classPool.makeClass(byteArrayInputStream);
                CtMethod[] methods=clazz.getMethods();
                for (CtMethod method:methods){
                    if (method.getName().equals("ping")){
                        return fixMethod(clazz,method.getName());
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            return new byte[0];
        }
        private byte[] fixMethod(CtClass clazz,String oldmethodName){
            try {
                CtMethod method=clazz.getDeclaredMethod(oldmethodName);
                StringBuilder bodyStr = new StringBuilder();
                bodyStr.append("{");
                bodyStr.append("System.out.println(\"开始热补丁\");\n");
                bodyStr.append("return 0;");
                bodyStr.append("}");
                method.setBody(bodyStr.toString());
                return clazz.toBytecode();
            } catch (NotFoundException e) {
                e.printStackTrace();
            } catch (CannotCompileException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
    
            return null;
        }
    
    }

效果图: 

 

 
 
 
 

转载于:https://www.cnblogs.com/xiaobaiyey/p/5826364.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值