使用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;
} }

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;
}
}

新建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

完成

修改jar的.class文件,并重新打包的更多相关文章

  1. linux下修改jar中的文件

    解压修改后再打包 解压: jar xvf xxx.jar 打包: jar cvfm0 xxx.jar META-INF/MANIFEST.MF ./ 注: -m参数可以将 一个具体的mainfest文 ...

  2. Java实现动态修改Jar包内文件内容

    import java.io.*; import java.util.Enumeration; import java.util.LinkedList; import java.util.List; ...

  3. Java 操作jar包工具类以及如何快速修改Jar包里的文件内容

    需求背景:写了一个实时读取日志文件以及监控的小程序,打包成了Jar包可执行文件,通过我们的web主系统上传到各个服务器,然后调用ssh命令执行.每次上传前都要通过解压缩软件修改或者替换里面的配置文件, ...

  4. Java如何快速修改Jar包里的文件内容

    需求背景:写了一个实时读取日志文件以及监控的小程序,打包成了Jar包可执行文件,通过我们的web主系统上传到各个服务器,然后调用ssh命令执行.每次上传前都要通过解压缩软件修改或者替换里面的配置文件, ...

  5. Android 编程下如何修改 jar 文件的包名

    首先我们要说说为什么要修改 jar 文件的包名,jar 包我们会非常高频率的使用,尤其是用一些其他三方库的时候,往往把 java 代码打包成 jar 文件,方便项目依赖使用.笔者在开发过程中遇到过一些 ...

  6. 修改jar中的class文件

    在工作中有可能会遇到需要修改jar的情况.正常情况下,如果有源代码的话,就比较容易,直接修改源代码,再导出新的jar文件即可.但是如果没有源代码就比较麻烦了,下面记录了没有源代码的情况修改jar的方法 ...

  7. 曹工杂谈:Linux服务器上,Spring Boot 原地修改 jar 包配置文件/替换class文件,免去重复上传的麻烦

    一.前言 相信很多同学有这样的需求,现在很多公司都有多地的研发中心,经常需要跨地区部署,比如,博主人在成都,但是服务器是北京的.一般城市间网络都不怎么好,上传一个几十兆的jar包那是真的慢,别说现在微 ...

  8. 修改jar包配置文件的正确操作,jar包解压出来的文件夹重新打成jar,不依靠开发工具!!!!

    修改jar包配置文件的正确操作,有的时候通过一些解压工具可以对内部的文件进行修改,但是有时候会无效.这就很烦了 一.背景:       有一个springboot项目,事先我已经用编译好打成jar包以 ...

  9. 使用fat jar和exe4j把java程序打包成exe执行文件---转载的

    java应用编写测试好之后都是jar包或class文件,客户拿到这个东西后一般是不会java开发者那样在命令窗口下面输入运行的.客户要求的就是直接点击应用名称运行.java在方面做得很不友好,开发人员 ...

随机推荐

  1. LGOJP3959 宝藏

    题目链接 题目链接 题解 一开始想了一个错误的状压dp,水了40分. 这里先记录一下错误的做法: 错解: 设\(g[i,j,S]\)从\(i\)到\(j\),只经过集合\(S\)中的点的最短路,这个可 ...

  2. B-树,B+树,B*树总结

    链接地址:https://blog.csdn.net/v_JULY_v/article/details/6530142 B+树 B+ 树是一种树数据结构,是一个n叉树,每个节点通常有多个孩子,一棵B+ ...

  3. CTF入门(一)

    ctf入门指南 如何入门?如何组队? capture the flag 夺旗比赛 类型: Web密码学pwn 程序的逻辑分析,漏洞利用windows.linux.小型机等misc 杂项,隐写,数据还原 ...

  4. 洛谷 P5146 最大差值 题解

    P5146 最大差值 题目描述 HKE最近热衷于研究序列,有一次他发现了一个有趣的问题: 对于一个序列\(A_1,A_2\cdots A_n\)​,找出两个数\(i,j\),\(1\leq i< ...

  5. 洛谷P1076 寻宝

    寻宝 模拟加优化,细节比较重要. 我们用ti[i]表示i这一层有楼梯的个数,然后我们把当前1号点的数据mod上ti[i],然后使该数不能等于0,就行了. #include <bits/stdc+ ...

  6. Python之NumPy(axis=0/1/2...)的透彻理解

    https://blog.csdn.net/sky_kkk/article/details/79725646 numpy中axis取值的说明首先对numpy中axis取值进行说明:一维数组时axis= ...

  7. a标签伪类选择器+过度模块

    a标签的伪类选择器 1.什么是a标签的伪类选择器?a标签的伪类选择器是专门用来修改a标签不同状态的样式的. 2.格式: 1):link 修改从未被访问过状态下的样式. 2):visited 修改被访问 ...

  8. 【转】ANDROIDROM制作(一)——ROM结构介绍、精简和内置、一般刷机过程

    作为对Rom制作的一个总结,本节主要介绍以下内容:  1.Rom介绍  2.Rom文件结构  3.app的精简与内置  4.Recovery简介  5.radio包简介  6.一般刷机过程.刷机过程中 ...

  9. redis-sentinel 高可用方案实践

    近期公司的一块核心业务使用redis作为配置转发中心,存在单点问题,考虑服务的可靠性.针对业务需求,我们确定了我们的需求: 异地跨机房容灾 故障自动切换 尽可能高的保证数据不丢失 针对以上需求,我们分 ...

  10. 工具系列 | 使用Lodop进行WEB打印程序开发

    Lodop(标音:劳道谱,俗称:露肚皮)是专业WEB控件,用它既可裁剪输出页面内容,又可用程序代码直接实现 复杂打印.控件功能强大,却简单易用,所有调用如同JavaScript扩展语句. WEB套打可 ...