修改jar的.class文件,并重新打包

使用javassist修改.class文件,并重新打包

Javassist是一款字节码编辑工具,可以直接编辑和生成Java生成的字节码,以达到对.class文件进行动态修改的效果。熟练使用这套工具,可以让Java编程更接近与动态语言编程。

下面实现如何修改jar包里的方法

Javassist下载地址 查看

1.准备jar包

my/Solution.java

package my.tools;
public class Solution{

    public int lengthOfLongestSubstring(String s) {
        int longSub = 0;
        if(s.isEmpty()) return 0;
        if(s.length()==1) return 1;
        char[] arr = s.toCharArray();
        String str = String.valueOf(arr[0]);
        longSub = 1;
        for(int i=1;i<s.length();i++){
            int pos = str.indexOf(arr[i]);
            if (pos !=-1) {
                str = str.substring(pos+1)+arr[i];
            }else{
                str+=arr[i];
            }
            if(str.length()>longSub) longSub = str.length();
        }
        return longSub;
    }

    public int strStr(String haystack, String needle) {
        
        if(needle.isEmpty()||needle.equals(haystack)) return 0;
        int l=needle.length();
        int r = haystack.length()-l;
        for(int i=0;i<r+1;i++){
            String tempStr=haystack.substring(i,l+i);
            if(tempStr.equals(needle))
                return i;
        }
        return -1;
    }

 }
View Code

my/Encrypt.java

package my.tools;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.IvParameterSpec;
import java.math.BigInteger;
import java.net.URLDecoder;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class Encrypt {
    public static String md5(String plainText) {
        byte[] secretBytes = null;
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            md.update(plainText.getBytes());
            secretBytes = md.digest();
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("dont have algorithm");
        }

        String md5code = new BigInteger(1, secretBytes).toString(16);

        for (int i = 0; i < 32 - md5code.length(); i++) {
            md5code = "0" + md5code;
        }
        return md5code;
    }

    public static String decrypt(String message, String key) throws Exception {
        byte[] bytesrc = convertHexString(message);
        Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
        DESKeySpec desKeySpec = new DESKeySpec(key.getBytes("UTF-8"));
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
        SecretKey secretKey = keyFactory.generateSecret(desKeySpec);
        IvParameterSpec iv = new IvParameterSpec(key.getBytes("UTF-8"));

        cipher.init(2, secretKey, iv);

        byte[] retByte = cipher.doFinal(bytesrc);
        return new String(retByte);
    }

    public static byte[] convertHexString(String ss) {
        byte[] digest = new byte[ss.length() / 2];
        for (int i = 0; i < digest.length; i++) {
            String byteString = ss.substring(2 * i, 2 * i + 2);
            int byteValue = Integer.parseInt(byteString, 16);
            digest[i] = ((byte) byteValue);
        }
        return digest;
    }

    public static String decode(String value) {
        try {
            return URLDecoder.decode(decrypt(value, "Yst@2_BI"), "utf-8");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}
View Code

新建resource

编译 javac  -sourcepath my my\tools\*.java -d resource

META-INF/MANIFEST.MF

Manifest-Version: 1.0
Created-By: 1.8.0_151 (Oracle Corporation)

进入resource打包  jar -cvfm mytools.jar META-INF\MANIFEST.MF *

使用

import my.tools.Solution;

public class Main {

    public static void main(String[] args) {

        System.out.println(new Solution().strStr("aacabseew", "ab"));
    }
}

输出:3

实现的查找第二个字符串出现的位置

2.修改编译后的class

 

导入下载的Javassist里的javassist.jar

import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtMethod;

public class Main {

    public static void main(String[] args) {

        try {
            ClassPool.getDefault().insertClassPath("data/mytools.jar");
            CtClass c2 = ClassPool.getDefault().getCtClass("my.tools.Solution");
            CtMethod[] ms = c2.getDeclaredMethods();
            for (CtMethod c : ms) {
                System.out.println(c.getName());
                CtClass[] ps = c.getParameterTypes();
                for (CtClass cx : ps) {
                    System.out.println("\t" + cx.getName());
                }
                if (c.getName().equals("strStr") && ps.length == 2
                        && ps[0].getName().equals("java.lang.String")
                        && ps[1].getName().equals("java.lang.String")) {
                    c.setBody("{System.out.println($1);return 0;}");
                }
            }
            c2.writeFile();

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

运行后会在项目根目录下生成修改后的class文件

 

3.生成新的jar

将以前的jar包修改mytools.zip

解压mytools.zip为mytools1,将刚才生成的my/tools/Solution.class替换掉mytools1里的Solution.class,

压缩mytools1为mytools1.zip

 修改文件名为mytools1.jar

导入新的jar包

测试

import my.tools.Solution;

public class Main {

    public static void main(String[] args) {

        System.out.println(new Solution().strStr("aacabseew","ab"));

    }
}

输出

aacabseew
0

 完成

posted @ 2019-05-15 18:05  慕尘  阅读(8267)  评论(0编辑  收藏  举报