使用jclasslib修改字节码/源码
查看源码很简单,一些常用IDE里如idea、eclipse都提供了查看class文件源码的功能,虽然跟源码有些出入(解语法糖等),但功能实现上是一致的,且比源码更贴近于JVM运行时的情况。
有时候我们需要修改源码以满足使用要求,对于java代码生成的字节码重新源码就比较简单了,一种方式是继承然后重写待修改的功能,另一种方式是直接创建一个同名类文件,把反编译的源码复制进去,修改后,将新生成的class文件替换原jar包中的class文件,但有些字节码是由其它语言生成的,反编译后的文件并不能满足java编译语法,也就无法编译成新的class文件,对于这种情况,有种通用的方式就是直接修改字节码来实现。
网上有很多修改字节码的文章,但大都是修改常量池来输出不同的值,本文使用jclasslib直接修改字节码中的源码逻辑,为方便演示,本文的demo可能比较简单,但是这种方法可以用到更复杂的类中,如有需要欢迎留言探讨。
1、java源码
package com.zhanghao.test.jclasslib;public class JclasslibTest {public static void main(String[] args) {int a = 1;int b = 2;printMin(a, b);}private static void printMin(int a, int b) {int min = a <= b ? a : b;System.out.println(min);}
}
输出两个参数中的较小值:1
目标:通过修改字节码的方式使printMin方法输出较大值:2
2、class文件反编译结果
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//package com.zhanghao.test.jclasslib;public class JclasslibTest {public JclasslibTest() {}public static void main(String[] args) {int a = 1;int b = 2;printMin(a, b);}private static void printMin(int a, int b) {int min = a <= b ? a : b;System.out.println(min);}
}
可以看出,生成的class文件只是比java源码多加了一个默认的无参构造方法(因为demo比较简单,所以未体现编译优化的多种策略)
3、下载安装jclasslib
https://github.com/ingokegel/jclasslib/releases
4、使用jclasslib打开class文件
字节码各部分名称已经很明确类,这里不在过多解释,看我们需要修改的位置Methods->printMin
printMin方法对应的字节码一共为19行
0:将第一个参数入栈(参数a=1)
1:将第二个参数入栈(参数b=2)
2:比较栈顶两int型数值的大小,当结果大于0时跳转到第9行字节码指令(判断条件进入相应逻辑块)
5:将第一个参数入栈(选择a)
6:无条件跳转到第10行字节码指令
9:将第二个参数入栈(选择b)
10:将栈顶int型数值存入第三个本地变量(存储选择结果c)
11:获取指定类的静态域,并将其压入栈顶(获取待运行的实例及方法)
14:将第三个参数入栈(将c入栈以供11中的实例方法运行参数)
15:调用实例方法
18:从当前方法返回void
更多字节码指令可参考 虚拟机字节码指令表
参照虚拟机字节码指令表,如要实现将pringMin输出参数中的较大值,只要把第三条指令if_icmpgt修改成if_icmple即可。
助记符 | if_icmpgt | if_icmple |
---|---|---|
指令含义 | 比较栈顶两int型数值的大小,当结果大于0时跳转 | 比较栈顶两int型数值的大小,当结果小于或等于0时跳转 |
字节码 | 0xa3 | 0xa4 |
有符号型十进制数 | -93 | -92 |
5、修改字节码
package com.zhanghao.test.jclasslib;import com.alibaba.fastjson.JSON;
import java.io.*;
import org.gjt.jclasslib.io.ClassFileWriter;
import org.gjt.jclasslib.structures.AttributeInfo;
import org.gjt.jclasslib.structures.ClassFile;
import org.gjt.jclasslib.structures.MethodInfo;
import org.gjt.jclasslib.structures.attributes.CodeAttribute;public class JclasslibModify {public static void main(String[] args) throws Exception {String filePath = "/Users/zhanghao/Desktop/jclasslib/JclasslibTest.class";FileInputStream fis = new FileInputStream(filePath);DataInput di = new DataInputStream(fis);ClassFile cf = new ClassFile();cf.read(di);System.out.println(JSON.toJSONString(cf));MethodInfo[] methodInfos = cf.getMethods();MethodInfo methodInfo = methodInfos[2];AttributeInfo[] attributeInfos = methodInfo.getAttributes();CodeAttribute codeAttribute = (CodeAttribute) attributeInfos[0];byte[] bytes = codeAttribute.getCode();bytes[2] = -92;fis.close();File f = new File(filePath);ClassFileWriter.writeToFile(f, cf);}
}
读取class文件,可通过debug或者输出json的方式查看ClassFile的类结构,修改类结构中字节码然后重写文件。
需要用到jclasslib.jar,下载链接:jclasslib.jar
6、查看修改后的结果
package com.zhanghao.test;public class JclasslibTest {public JclasslibTest() {}public static void main(String[] args) {int a = 1;int b = 2;printMin(a, b);}private static void printMin(int a, int b) {int min = a > b ? a : b;System.out.println(min);}
}
本文只是简单的阐述修改字节码的方法,对于实际项目中需要修改字节码时,情况会更为复杂,但是换汤不换药,可以先用java生成待修改部分的字节码,然后替换掉原字节码中相应的字节码块,其它文件也需要相应修改,比如常量池等
使用jclasslib修改字节码/源码相关推荐
- 修改Android10系统源码关闭selinux
一.seandroid简介 SEAndroid是Google在Android4.4上正式推出的一套以SELinux为核心的系统安全机制.在Android源码中,系统默认的seandroid配置存放如下 ...
- c语言比较函数memcmp,c语言函数memcmp()如何比较内存前n个字节实例源码介绍
c语言函数memcmp()如何比较内存前n个字节实例源码介绍.引入头文件:#include 定义memcmp()函数:int memcmp (const void *s1, const void *s ...
- html代码在线解析,VIP在线解析HTML源码(修改论坛的源码、加搜索功能)
本帖最后由 闷骚小贱男 于 2017-3-28 00:08 编辑 今天有朋友问我要TX的VIP看视频来着,就给了他一个在线的网站,心想着自己也弄一个解析的吧.在论坛搜到一个源码 传送门:看到有需要直接 ...
- VC++设置文件最后修改时间(附源码)
VC++开发常用功能一系列文章 (欢迎订阅,持续更新...) 第21章:VC++设置文件最后修改时间(附源码) 源代码demo已上传到百度网盘:永久生效 ,代码实现了设置文件最后修改时间 上一篇 ...
- UV云任务小米运动步数修改PHP网站源码
UV云任务小米运动步数修改PHP网站源码 1.下载小米运动App,打开软件并输入手机号登录(不要使用第三方账号登录) 2.点击我的->第三方接入,绑定你想同步数据的项目. 3.打开小工具,输入账 ...
- [Unity3D]修改PaintIn3D插件源码以便用于VR
修改PaintIn3D插件源码 1. 导入PaintIn3D插件和SteamVR 2. 修改PaintIn3D插件源码 2.1 修改P3dHitScreen.cs 2.2 修改P3dInputMana ...
- 易语言修改html内容,易语言修改网页标题源码
易语言修改网页标题系统结构:取IES对象,GetCursorPos,WindowFromPoint,SendMessageTimeout,ObjectFromLresult,RegisterWindo ...
- 【独立版】翻牌领红包系统一物一码仿口味王验证码抽奖码得红包追溯码源码程序无加密
[独立版]翻牌领红包系统一物一码仿口味王验证码抽奖码得红包追溯码源码程序无加密 本小程序全新独立开发Thinkphp为核心 运行环境: PHP7.1+MySQL5.6+公众号+微信支付商户号 核心功能 ...
- java员工管理系统代码_员工管理系统JAVA源码(源码大小8M)
员工管理系统JAVA源码(源码大小8M) 本站提供几百套大型商业源码,平均一元一套,火爆下载中...... QQ:283072.283672 EMAIL:web@hur.cn.jhwjeffrey@1 ...
- 云转码源码(视频云转码)双码率+秒切
我们之前讨论过一种解决方案是利用云服务的力量对视频进行转码.虽然可以使用本地计算进行转码,但过去三年生成的大量内容--以及大部分内容是以 4K 格式获取的事实--使得云转码成为一个更具吸引力的主张(即 ...
最新文章
- TCGAbiolinks包分析TCGA数据
- 好程序员web前端分享HTML基础篇
- Android TabWidget
- 编程方法学笔记:karel
- php决策管理,报表管理与数据分析:为系统未来发展规划提供决策依据,有效避免IT管理与投资的盲目??...
- 【Hbase】程序批量put数据到Hbase
- 关于服务器耗电量的计算
- (转)Django ==== 实战学习篇二 需求分析及设计,创建第一个模型---购物车的应用...
- 【个人笔记】OpenCV4 C++ 快速入门 22课
- 统一对外的接口,支持requestBody以及表单提交的坑
- python web 文件管理器_利用Python 1分钟搭建测试Web服务器,可实现linux目录文件共享...
- 遭遇 kapjazy.dll,yhpri.dll,WinSys64.Sys,nwiztlbu.exe,myplayer.com 等2
- python读取svg转emf_ppt矢量图标,SVG转换EMF方法
- 菜菜之路-C语言求阶乘和
- 做SEO优化网站跳出率太高怎么办
- 锁定计算机怎么设密码忘记了怎么办,电脑怎么设置锁屏密码 电脑锁屏密码忘记了怎么办...
- JavaScript基础语法
- 关于 error: invalid types ‘int[int]‘ for array subscript 的解决
- Windows安装 choco
- 用户发送的eth值msg.value,在合约中以wei为单位。
热门文章
- 选择易优cms建站的十大理由
- android模拟机新闻APP,Exagear ET(Exagear模拟器)
- mkv格式提取文件方法
- Ubuntu下出现授权问题
- 扩展Alibaba P3C 实现自定义代码规范检查
- android 固件 修改工具箱,固件工具箱(ROM Toolbox)
- python机械数据分析_记一次小机器的 Python 大数据分析
- 独家首发成语类智力多玩法微信小程序源码下载好玩而又强大
- cad有没有网页版_AutoCAD
- java项目集成J2Cache(一级缓存ehCache,二级缓存redis)