我有一个第三方 jar 包,咋们一起修改 class 文件吧 | 您所在的位置:网站首页 › jar包class类替换 › 我有一个第三方 jar 包,咋们一起修改 class 文件吧 |
你有没有遇到需要修改 class 文件重新打包的场景呢? 巧得很,最近刚好遇到需要修改一个已存在的 jar 包,为了满足自己的需求, 不过对于 class 文件修改的是比较简单的字符常量,尚未涉及到比较复杂的逻辑, 用于记录一下如何修改,如何快速修改完成需求,希望可以抛砖引玉,剩下的较为复杂的逻辑修改就交给你们了 :) 比如我有这样一个修改 class 文件的场景: 问题: 某弹窗文本显示不正确此弹窗代码是在某第三方 jar 包里,显示内容格式是: 客服:配置内容, 我的需求是不需要 jar 内置的固定格式(看代码其实就是字符串拼接),我需要去掉 客服: 这个固定前缀,让配置内容更加灵活。 那么想要实现这个,我想到的是通过修改 jar 包,去除显示格式 客服: 固定前缀,实现内容灵活配置。 这里简单记录两种修改方式 第一种方式是直接使用 javac 命令 第二种方式是借助工具 jclasslib bytecode editor 快速修改 稍微温故 jar 命令 jar 简洁手册:jar -h 用法: jar {ctxui}[vfmn0PMe] [jar-file] [manifest-file] [entry-point] [-C dir] files ...\ 选项: -c 创建新档案 -t 列出档案目录 -x 从档案中提取指定的 (或所有) 文件 -u 更新现有档案 -v 在标准输出中生成详细输出 -f 指定档案文件名 -m 包含指定清单文件中的清单信息 -n 创建新档案后执行 Pack200 规范化 -e 为捆绑到可执行 jar 文件的独立应用程序 指定应用程序入口点 -0 仅存储; 不使用任何 ZIP 压缩 -P 保留文件名中的前导 '/' (绝对路径) 和 ".." (父目录) 组件 -M 不创建条目的清单文件 -i 为指定的 jar 文件生成索引信息 -C 更改为指定的目录并包含以下文件 如果任何文件为目录, 则对其进行递归处理。清单文件名, 档案文件名和入口点名称的指定顺序 与 'm', 'f' 和 'e' 标记的指定顺序相同。 打包生成 jar 将两个 class 文件打包为 classes.jar 文件 jar cvf classes.jar Foo.class Bar.class将 folder/ 目录下的所有文件打包成 classes.jar 文件 jar cvf classes.jar -C folder/ . 查看 jar 文件列表: jar -tvf classes.jar 解压 jar 文件: jar -xvf classes.jar 工具下载 jclasslib bytecode editor JD-GUI 方式一:javac 命令1、使用 JD-GUI 打开 jar 文件并导出 java 代码,对代码进行修改 2、使用 javac 命令把 .java 文件转换为 .class 文件 javac -classpath [待生成的文件名.jar] [已修改的文件.java]实际操作过程中直接执行该命令可能往往不是自己期望的那么顺利,那么我们要对特殊情况进行特殊处理。 当遇到编码问题时:需要添加额外参数-encoding utf-8注意: 这里有个坑,如果打包过程有依赖 android jar,那么!!!android.jar 必须是 android sdk 目录下的 jar,不能随便找一个,否则编译失败。` 3、经过上述操作,最后使用的命令可能是这样的 javac -encoding utf-8 -classpath [依赖的1.jar;依赖的2.jar;依赖的3.jar;...] [已修改的单个 .java 文件或者待转换的 .java 文件所在目录]例如 javac -encoding utf-8 -classpath android.jar;classes-dex2jar.jar GRAppStoreActivity.java这就成功把 java 代码编译为 class 代码 4、把编译好了的 class 文件替换原先的文件打包成 jar jar cvf [新文件名.jar] -C [待打包的class文件目录] [输出到指定目录]例如 jar cvf jsonlili.jar -C primer/ .到这里就打包成功了,如果遇到什么问题欢迎评论 :) 看起来操作步骤是有点繁琐。那么下面简明介绍可以快速实现的方法。 方式二:jclasslib 工具1、把 jar 包拖入工具中并打开指定 class 文件【也可以使用 jar 命令先解压获取 class 文件】 2、代码定位并修改(我们以开头的客服提示弹窗为例) 在原始 classes.all.dex.jar 文件中定位到客服:固定前缀在 MyMainActivity 类的某个匿名方法中。 我们知道匿名实现经过编译成 class 文件之后生成单独的文件,且文件名往往带有$符号,所以我们解压 jar 文件之后可以缩小范围查找。 一番查阅后定位到 MyMainActivity$2$1.class 文件中,Methods -》onClick -》Code ldc:是 JVM 指令,将从常量池中取出值 JVM 相关知识我自己也要加强,不过多介绍,这里推荐一个学习地址 字节码指令 3、修改并保存 从刚才的 ldc #61 中点击 #61 跳转到编辑处 到这里,其实我们对 class 文件的修改已经完成了,省去了方法一中的 java 代码转换为 class 的操作和 jar 打包操作。 最后的最后我在想,如果想要修改更复杂的代码满足更大的需求呢?怎么办? 个人总结了一点,那就是:持续学习 比如,我对 JVM 指令掌握的不够,那我需要深入学习;我对反编译相关知识掌握不足,也需要找资源学习..... 推荐一个反编译工具的下载地址: 在线破解工具包: |
CopyRight 2018-2019 实验室设备网 版权所有 |