百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程字典 > 正文

一种无源代码文件的Java程序修改方法

toyiye 2024-06-21 12:04 10 浏览 0 评论

一、前言

公司有个老旧项目忽然报错,追踪代码发现逻辑有问题,可又由于公司代码管理不当,导致源码丢失,当前只有可运行的jar包;如果要修复这个问题,只能通过修改字节码文件的方式,然后重新打包部署。

二、准备工作

①:需要反编译的xxx.jar包;

②:反编译工具:JD-JUI.exe;

③:代码编辑工具(IDEA);

三、两种解决方案:

方案一:

第一步,在IDEA中新建一个maven项目第二步,把xxx.jar导入到该项目中第三步,定位要修改的xxx.class文件,在src–>main–>java里面创建一个同路径的package,并新建xxx.java,然后在xxx.class文件的内容复制到当前xxx.java中。注意:当前文件可能除了依赖第三方库依赖,还依赖其它文件,需要同时copy出来,复制的时候注意保持包名一致。

第四步,找到xxx.jar包下的pom.xml文件复制到当前项目的pom.xml文件中,解决依赖第三方库的问题。

第五步,修改新创建的java源码,修改完成后右键重新编译该文件。

第六步,编译完成以后,在target文件下找到新生成的xxx.class文件第七步,使用压缩包工具打开原始xxx.jar包,找到xxx.class文件,使用新生成的xxx.class文件替换覆盖掉即可。

优点:如果修改文件依赖少,操作简单快捷缺点:如果修改文件依赖比较多,除了考虑依赖的第三方包,也要粘贴复制其它文件,这样费时繁琐,本来只需要更改一个文件,但是却需要其他文件支持,产生依赖爆炸的问题。

方案二:

JavaAssist简单介绍:JavaAssist又叫编译时的类,是Jboss开源的分析、编辑和创建Java字节码的类库,它能够直接用java编码的形式,而不需要了解虚拟机指令,就能动态改变类的结构,或者动态生成类。

案例1:重新生成字节码文件

public static void main(String[] args) throws Exception{
       //CtClass对象容器
       ClassPool classPool=ClassPool.getDefault();
       //CtClass对象容器中创建一个public的JATest类
       CtClass jATestClazz=classPool.makeClass("com.tyun.javaassist.MyTest");

       //***属性操作
       //MyTest类中添加private int id
       CtField ctIdField=new CtField(classPool.getCtClass("int"),"id",jATestClazz);
       ctIdField.setModifiers(Modifier.PRIVATE);
       jATestClazz.addField(ctIdField);

       //MyTest类中添加private String username
       CtField ctUserNameField=new CtField(classPool.getCtClass("java.lang.String"),"username",jATestClazz);
       ctUserNameField.setModifiers(Modifier.PRIVATE);
       jATestClazz.addField(ctUserNameField);

       //添加getter,setter方法
       jATestClazz.addMethod(CtNewMethod.getter("getId",ctIdField));
       jATestClazz.addMethod(CtNewMethod.getter("setId",ctIdField));
       jATestClazz.addMethod(CtNewMethod.getter("getUsername",ctUserNameField));
       jATestClazz.addMethod(CtNewMethod.getter("setUsername",ctUserNameField));

       //添加构造函数
       CtConstructor ctConstructor=new CtConstructor(new CtClass[]{},jATestClazz);
       //添加构造函数方法体
       StringBuffer sb = new StringBuffer();
       sb.append("{\n").append("this.id = 27;\n").append("this.username=\"卓耿\";\n}");
       ctConstructor.setBody(sb.toString());
       jATestClazz.addConstructor(ctConstructor);

       // 添加自定义方法
       CtMethod method = new CtMethod(CtClass.voidType, "sayHello", new CtClass[]{}, jATestClazz);
       method.setModifiers(Modifier.PUBLIC);
       StringBuffer printSb = new StringBuffer();
       printSb.append("{\nSystem.out.println(\"begin!\");\n")
              .append("System.out.println(id);\n")
              .append("System.out.println(username);\n")
              .append("System.out.println(\"end!\");\n")
              .append("}");
       method.setBody(printSb.toString());
       jATestClazz.addMethod(method);

       //生成一个Class对象
       Class<?> clazz=jATestClazz.toClass();
       Object object=clazz.newInstance();

       //反射执行方法
       clazz.getMethod("sayHello",new Class[]{}).invoke(object,new Object[]{});

       //将生成的class写入文件中
       FileOutputStream fileOutputStream=new FileOutputStream(new File("JATest.class"));
       fileOutputStream.write(jATestClazz.toBytecode());
       fileOutputStream.close();
      }

运行代码,生成MyTest.class文件;

案例二:修改字节码文件文件中的指定方法

未修改前源代码。

public class TyunTest {
   public static void main(String[] args) {
       sayHello();
  }
   public static void sayHello(){
       System.out.println("你好,世界");

  }
}

将源文件打成jar;

使用使用JavaAssist读取jar包修改字节码文件;

ClassPool classPool=ClassPool.getDefault();
       // 设置jar包路径
       classPool.insertClassPath("/Users/wyw_yong/Desktop/tyun/Tiyun.jar");
       // 获取修改的类
       CtClass ctClazz = classPool.getCtClass("TyunTest");

       // 获取类中的方法
       CtMethod sayHelloMethod = ctClazz.getDeclaredMethod("sayHello");
       // 修改类中的方法内容
       sayHelloMethod.setBody("System.out.println(\"hello javaAssist\");");

       Class newTestJarClass = ctClazz.toClass();
       // 使用修改过的类创建对象
       Object newTestJar = newTestJarClass.newInstance();
       Method newPrintTestMethod = newTestJarClass.getDeclaredMethod("sayHello");
       newPrintTestMethod.invoke(newTestJar);
       // 解除代码锁定,恢复可编辑状态
       ctClazz.defrost();
       // 写出到外存中
       ctClazz.writeFile();

执行代码,在文件路径下查看字节码文件;

可以看到方法中的输出打印"你好,世界"变成了"hello javaAssist"。

四、结尾

以上就是丢失源码的情况下,只能通过修改字节码文件的两种方法。?

来源:https://www.51cto.com/article/719349.html

相关推荐

为何越来越多的编程语言使用JSON(为什么编程)

JSON是JavascriptObjectNotation的缩写,意思是Javascript对象表示法,是一种易于人类阅读和对编程友好的文本数据传递方法,是JavaScript语言规范定义的一个子...

何时在数据库中使用 JSON(数据库用json格式存储)

在本文中,您将了解何时应考虑将JSON数据类型添加到表中以及何时应避免使用它们。每天?分享?最新?软件?开发?,Devops,敏捷?,测试?以及?项目?管理?最新?,最热门?的?文章?,每天?花?...

MySQL 从零开始:05 数据类型(mysql数据类型有哪些,并举例)

前面的讲解中已经接触到了表的创建,表的创建是对字段的声明,比如:上述语句声明了字段的名称、类型、所占空间、默认值和是否可以为空等信息。其中的int、varchar、char和decimal都...

JSON对象花样进阶(json格式对象)

一、引言在现代Web开发中,JSON(JavaScriptObjectNotation)已经成为数据交换的标准格式。无论是从前端向后端发送数据,还是从后端接收数据,JSON都是不可或缺的一部分。...

深入理解 JSON 和 Form-data(json和formdata提交区别)

在讨论现代网络开发与API设计的语境下,理解客户端和服务器间如何有效且可靠地交换数据变得尤为关键。这里,特别值得关注的是两种主流数据格式:...

JSON 语法(json 语法 priority)

JSON语法是JavaScript语法的子集。JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔花括号保存对象方括号保存数组JS...

JSON语法详解(json的语法规则)

JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔大括号保存对象中括号保存数组注意:json的key是字符串,且必须是双引号,不能是单引号...

MySQL JSON数据类型操作(mysql的json)

概述mysql自5.7.8版本开始,就支持了json结构的数据存储和查询,这表明了mysql也在不断的学习和增加nosql数据库的有点。但mysql毕竟是关系型数据库,在处理json这种非结构化的数据...

JSON的数据模式(json数据格式示例)

像XML模式一样,JSON数据格式也有Schema,这是一个基于JSON格式的规范。JSON模式也以JSON格式编写。它用于验证JSON数据。JSON模式示例以下代码显示了基本的JSON模式。{"...

前端学习——JSON格式详解(后端json格式)

JSON(JavaScriptObjectNotation)是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。它基于JavaScriptProgrammingLa...

什么是 JSON:详解 JSON 及其优势(什么叫json)

现在程序员还有谁不知道JSON吗?无论对于前端还是后端,JSON都是一种常见的数据格式。那么JSON到底是什么呢?JSON的定义...

PostgreSQL JSON 类型:处理结构化数据

PostgreSQL提供JSON类型,以存储结构化数据。JSON是一种开放的数据格式,可用于存储各种类型的值。什么是JSON类型?JSON类型表示JSON(JavaScriptO...

JavaScript:JSON、三种包装类(javascript 包)

JOSN:我们希望可以将一个对象在不同的语言中进行传递,以达到通信的目的,最佳方式就是将一个对象转换为字符串的形式JSON(JavaScriptObjectNotation)-JS的对象表示法...

Python数据分析 只要1分钟 教你玩转JSON 全程干货

Json简介:Json,全名JavaScriptObjectNotation,JSON(JavaScriptObjectNotation(记号、标记))是一种轻量级的数据交换格式。它基于J...

比较一下JSON与XML两种数据格式?(json和xml哪个好)

JSON(JavaScriptObjectNotation)和XML(eXtensibleMarkupLanguage)是在日常开发中比较常用的两种数据格式,它们主要的作用就是用来进行数据的传...

取消回复欢迎 发表评论:

请填写验证码