本文版权归赣州兆鑫软件所有,原创未经许可禁止转载!
本文仅作学习交流目的,提倡软件正版,反对盗版!


工欲善其事必先利其器

  • Java Decompiler 1.4.0,简称JD
  • InteliJ IDEA  2017,简称IDEA
  • dirtyJOE
  • Oracle JDK 1.8

做事要先掌握大局

  1. 将已签名包转化为未签名包;
  2. 定位关键代码位置;
  3. 修改class文件字节码;
  4. 替换class文件重新打包;

不行动总也不能成功

1.将已签名包转化为未签名包

如果你用到的Jar文件使用了签名,它会保证里面的每个class文件不能被修改,所以即使你成功修改了class文件中的字节码,得到的Jar也是无法运行的。这些经过签名的Jar包的META-INF文件夹中一般包含了*.SF和相应的*.RSA文件。这些文件记录Jar包中每个文件的签名信息,以保证代码不被篡改。

使用下面的方法可以重新生成一个未签名Jar包。参考自stackoverflow作者Houtman的回答

// 使用JDK编译代码
javac JarUnsigner.java// 执行JarUnsigner,如果是同一个文件夹
java -cp . JarUnsigner <inJar> <outJar>

附上源代码,免得回答被删

// JarUnsigner.java
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;public class JarUnsigner {private static final String MANIFEST = "META-INF/MANIFEST.MF";public static void main(String[] args){if (args.length!=2){System.out.println("Arguments: <infile.jar> <outfile.jar>");System.exit(1);}String infile = args[0];String outfile = args[1];if ((new File(outfile)).exists()){System.out.println("Output file already exists:" + outfile);System.exit(1);}try{ZipFile zipFile = new ZipFile(infile);final ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(outfile));for (Enumeration e = zipFile.entries(); e.hasMoreElements();) {ZipEntry entryIn = (ZipEntry) e.nextElement();if (! exclude_file( entryIn.getName() ) ) {/* copy the entry as-is */zos.putNextEntry( new ZipEntry( entryIn.getName() ));InputStream is = zipFile.getInputStream(entryIn);byte[] buf = new byte[1024];int len;while ((len = (is.read(buf))) > 0) {zos.write(buf, 0, len);}zos.closeEntry();} else {if (MANIFEST.equals(entryIn.getName())){/* if MANIFEST, adjust the entry */zos.putNextEntry(new ZipEntry(MANIFEST));// manifest entries until first empty line. i.e. the 'MainAttributes' section// (this method is used so to keep the formatting exactly the same)InputStream mIS = zipFile.getInputStream(entryIn);BufferedReader in = new BufferedReader(new InputStreamReader(mIS));String line = in.readLine();byte[] mNL = "\n".getBytes("UTF-8");while( line != null && !line.trim().isEmpty() ) {zos.write( line.getBytes("UTF-8"));zos.write( mNL );line = in.readLine();}zos.write( mNL );zos.closeEntry();}else{/* else: Leave out the Signature files */}}}zos.close();System.out.println("Successfully unsigned " + outfile);}catch(IOException ex){System.err.println("Error for file: " + infile);ex.printStackTrace();System.exit(1);}}/*** Exclude .SF signature file* Exclude .RSA and DSA (signed version of .SF file) * Exclude SIG-  files  (unknown sign types for signed .SF file)* Exclude Manifest file* @param filename* @return */public static boolean exclude_file(String filename){return filename.equals("META-INF/MANIFEST.MF") ||filename.startsWith("META-INF/SIG-") || filename.startsWith("META-INF/") && ( filename.endsWith(".SF") || filename.endsWith(".RSA") || filename.endsWith(".DSA") );}}

2. 定位代码关键位置

举一个需要输入序列号才能试用的库文件的例子,但是为了保护Jar包作者权益,对包名进行打码了。通过Jar包的说明书,可以知道如何使用它,就知道是什么地方输入序列号啦,要不然是个正常人也没法用对吧。例如

// 文档说这样子可以验证序列号
authentication.User("333");
authentication.Serial("94306-56191-128286-2967422");

rock & roll

  1. 使用JD反编译Jar包,然后Save All Sources,具体步骤这里省略;
  2. 从IDEA新建一个工程,把反编译的源代码放到源目录,Jar包可能是经过混淆过的,不过这个关系不大,我们字节码都能改,还怕看不懂混淆?继续往下走
  3. 右击authentication这个类文件,选择Find Usages,快捷键一般是Ctrl+G,看到有个叫做p.java的文件用到,做了一些判断操作Blabla,看屏幕截图1:

  1. 点开这个p.java类搜索到的地方,可以看到,它在比较一个返回结果,然后给出不同的错误提示,这个结果是由一个t.a(三个参数)的方法计算得到,并且看得出来当计算结果的a属性值为0时就是Licence OK!,看屏幕截图2:

  1. 好,我们再来看t.java这个文件的a方法又有什么东东(按住Ctrl键,鼠标点击那个t.a),我们只要保证他得到的结果的a属性等于0就好了,可以看到只有一种情况下a属性才会等于0,其他时候都是等于-1的,到这一步IDEA的使命就完成了,看屏幕截图3:

结果

通过上面5步(取决于不同的包,不一定都是5步),我们知道了需要改动t类里面的a方法,让它里面操作属性a时,值为-1的都改为0就能成功。

3. 修改class文件字节码

接下来就要使用dirtyJOE软件来定位并修改字节码了,作者也试过Class Editor, Java Bytecode Editor都因年久失修,没改成功。通过查阅JVM文档我们知道给整数赋值有几种指令,这里就说两种:

  • iconst_<i> i可以为 m1,0,1,2,3,4,5,分别设置的值为-1,0,1,2,3,4,5,指令16进制字节码分别是02设置-1,03设置0,04设置1,以此类推
  • bipush <i> i范围可以是0-255,指令16进制字节码是10,比如代码里面有的21就是bipush 21,16字节码表示为10 15

let's go

  1. 使用dirtyJOE打开t.class文件,切换到 Methods 页上,如下图所示:

  1. 双击我们需要修改的方法(同名时通过比对方法签名来区分),进入编辑界面,图中的两个指令的组合就是将值-1赋值给t$a.a属性,双击图中的iconst_ml,字节码是02,改为03,然后回车即可,可以使用Ctrl+F查找多处进行修改:

  1. 关闭编辑窗口,保存修改。

warning

要保证字节码的数量不增多,也不减少,因为类和类之间代码调用跟字节位置关系密切。不然会导致修改的class文件无法使用。原来一行是1个字节的,继续用1个字节,2个的就继续两个,3个的继续保持三个。

4. 替换class文件重新打包

这是最简单的一步,将修改好的class文件,使用zip压缩工具替换掉即可。如果是你Windows用户不推荐使用WinRaR,可以将jar文件(第一步生成的未签名包)重命名为zip文件,然后选择用Windows资源管理器打开,将修改的class文件复制粘贴进去。

如何破解已签名JAR包相关推荐

  1. maven本地仓库中已有jar包,项目却读取不了

    1.问题描述 前置条件:项目中有些jar包需要从私服获取,在pom.xml中配置了私服的仓库地址(通过<repository>标签). 问题1:由于在maven的配置文件(setting. ...

  2. 本地已存在jar包,maven却还是要直接上网下载的解决

    情况说明 本地已经有项目需要的所有依赖,但是maven总是会去网上下载,因为网络不好等原因,一直下载失败,但是本地明明就已经有依赖了. maven的settings配置 maven已经配置成自己下载的 ...

  3. java jar 签名_JAR包数字签名与验证

    经签名的Jar包内包含了以下内容: 原Jar包内的class文件和资源文件 签名文件 META-INF/*.SF:这是一个文本文件,包含原Jar包内的class文件和资源文件的Hash 签名block ...

  4. jar包 jdk 停_一文读懂jar包的小秘密

    简介 java程序员每天不是在创建jar包就是在创建jar包的路上,并且各种依赖引用都是以jar包的形式展示的.但是随着现代IDE的出现,我想很多程序员已经基本上很少直接和jar包打交道了. 换句话说 ...

  5. 一文读懂jar包的小秘密

    简介 java程序员每天不是在创建jar包就是在创建jar包的路上,并且各种依赖引用都是以jar包的形式展示的.但是随着现代IDE的出现,我想很多程序员已经基本上很少直接和jar包打交道了. 换句话说 ...

  6. 给jar包进行数字签名(2014-06-28记)

    整理一下两年前用到的一些资料. 为了使Applet或者Java Web Start程序能够访问客户端本地资源,需要对Applet或者JWS程序jar包进行数据签名,当客户端打开Applet或者JWS程 ...

  7. java jar包详解_Jar打包用法详解

    这篇文章主要介绍了Jar打包用法,详解分析了jar打包命令的各种常见用法及参数含义,非常具有实用价值,需要的朋友可以参考下 本文较为详细的分析了Jar打包的用法.分享给大家供大家参考.具体分析如下: ...

  8. 启动jar包shell脚本

    1.创建shell脚本 makir start.sh 2.复制以下内容修改自己jar包的文件名和路径 jar_name=xxx.jar jar_path=/xxx/xxxx log_path=/xxx ...

  9. idea引入本地jar包

    在开发过程中,往往会遇到在原有的项目上重写新功能的情况,而且有一部分包是maven所拉取不了的,这时候就需要将已有的jar包导入到项目中. 1.首先找到项目结构file->Project Str ...

  10. IDEA引入jar包显示为红色

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 一.现象 二.处理步骤 1.重新引入 2.缓存 总结 提示:以下是本篇文章正文内容,下面案例可供参考 一.现象 在引入了外部 ...

最新文章

  1. CI框架如何删除地址栏的 index.php
  2. 北卡教堂山计算机科学专业,UNC的CS「北卡罗来纳大学教堂山分校计算机科学系」...
  3. watch深度监听数组_vue watch普通监听和深度监听实例详解(数组和对象)
  4. android bench内存测试,华为p10内存测试软件(androbench) v5.0.1 免费版
  5. 项目实战|100个蓝牙接收器发货了
  6. 华为云大数据轻模式体验:忘掉底层烦恼,专注数据开发
  7. HP刀箱无法识别刀片的处理方法
  8. java集合类程序代码_Java集合类源代码分析二:ArrayList(1)
  9. 如何利用大数据打造智慧交通
  10. 基于TensorFlow的深度学习 揭示数据隐含的奥秘3 卷积神经网络
  11. 人证合一验证目前逐渐普及大众
  12. 基于Java前后端分离的在线蛋糕销售系统(含优秀毕业论文)
  13. 计算机应用基础课程学什么,计算机专业本科课程 主要学什么
  14. 新华系“雄文”为何引发游戏产业3000亿市值蒸发?
  15. C++内部链接与外部链接
  16. python画机器猫
  17. 9 张手绘图:阐明机器学习模型训练全流程
  18. landsat、spot、ikonos等各种卫星信息介绍及几种遥感影像下载方法
  19. 7-3 水仙花数(20 分) (20 分)(PTA Python版本)
  20. 了解寄存器: EBP寄存器

热门文章

  1. uni-app调用android方法,uni-app 调用 jar 包
  2. MongoDB学习总结四(详细记录使用MongoTemplate操作MongoDB数据库)
  3. wps教鞭功能_你未必知道的WPS神奇功能
  4. 计算机给文件重命名快捷键,计算机中文件重命名快捷键是什么
  5. 小鸡啄米之React事件处理
  6. 关于STM32F105 软硬件环境搭建
  7. php soh stx,symbol NULL SOH STX ETX EOT ENQ ACK ASCII(符号零SOH STX ETX传输结束询问ACK ASCII).pdf...
  8. [Simulink] 从手写代码到自动生成代码
  9. 免费录屏软件哪个好用 ? 7 款免费又好用的录屏工具 , 打工人必备
  10. 关于PAT报错:warning: ignoring return value of ‘scanf’, declared with attribute warn_unused_result