使用javassist修改.class文件,并重新打包
Javassist是一款字节码编辑工具,可以直接编辑和生成Java生成的字节码,以达到对.class文件进行动态修改的效果。熟练使用这套工具,可以让Java编程更接近与动态语言编程。
下面实现如何修改jar包里的方法
Javassist下载地址 查看
1.准备jar包
my/Solution.java
packagemy.tools;public classSolution{public intlengthOfLongestSubstring(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
str= str.substring(pos+1)+arr[i];
}else{
str+=arr[i];
}if(str.length()>longSub) longSub =str.length();
}returnlongSub;
}public intstrStr(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
String tempStr=haystack.substring(i,l+i);if(tempStr.equals(needle))returni;
}return -1;
}
}
View Code
my/Encrypt.java
packagemy.tools;importjavax.crypto.Cipher;importjavax.crypto.SecretKey;importjavax.crypto.SecretKeyFactory;importjavax.crypto.spec.DESKeySpec;importjavax.crypto.spec.IvParameterSpec;importjava.math.BigInteger;importjava.net.URLDecoder;importjava.security.MessageDigest;importjava.security.NoSuchAlgorithmException;public classEncrypt {public staticString 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;
}returnmd5code;
}public static String decrypt(String message, String key) throwsException {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 newString(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);
}returndigest;
}public staticString 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.0Created-By: 1.8.0_151 (Oracle Corporation)
进入resource打包 jar -cvfm mytools.jar META-INF\MANIFEST.MF *
使用
importmy.tools.Solution;public classMain {public static voidmain(String[] args) {
System.out.println(new Solution().strStr("aacabseew", "ab"));
}
}
输出:3
实现的查找第二个字符串出现的位置
2.修改编译后的class
导入下载的Javassist里的javassist.jar
importjavassist.ClassPool;importjavassist.CtClass;importjavassist.CtMethod;public classMain {public static voidmain(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包
测试
importmy.tools.Solution;public classMain {public static voidmain(String[] args) {
System.out.println(new Solution().strStr("aacabseew","ab"));
}
}
输出
aacabseew
0
完成