推荐阅读:

阿里P8架构师“呕心沥血”1年总结出这份Linux基础到进阶学习文档

年前面试京东3面凉经~ 面试过程与真题全分享+备战春招(java)

一、前言介绍

2020年了,对于一个程序猿来说;

2020 = 1024 + 996 | 404 + 404 + 404 + 404 + 4042021 = 1024 + 9972022 = 1024 + 91062023 = 1024 + 9107...20xx = 从今年开始可怕

当你过了元旦,爽了周末,清早上班,拿起杯子,加点新(薪)水,打开电脑,收起烦恼,翘起小脚,上扬嘴角。一切就绪都准备好,好!撸代码!啊!!!IDEA duang duang duang,过期了!

脑瓜一热赶紧搜索破解码;

  • 第一个,失败
  • 第二个,失败
  • 第三个,失败
  • ...
  • 第N个,终于,破解了三个月,先用着,先用着,以后再说!

可能大部分伙伴都在搜各种一堆一大串的破解码往里面粘,一个个试到最后终于过了。但也有一部分老司机是不搜破解码的,他们使用jar包破解,有效期100年。

那么!本文并不想引导用户都去使用破解版,像IDEA这么优秀,其实给你提供了很多选择;

  1. 如果你是学生可以免费使用
  2. 分为社区版和旗舰版,你可以使用社区版 Free, open-source
  3. 一般大公司都是有正版授权的,可以使用
  4. 如果你有开源项目也可以申请 IDEA 授权

所以,个人开发使用社区版本即可,不要使用破解。

好!回归正题,本文主要讲解是为什么放个Jar包就能破解,最后在使用一个jar进行破解演示。在以下章节中你可以学习到如下知识;

  • Java Agent 非硬编码式代理类,这也就是常说的探针技术
  • ASM 字节码编程简单使用
  • 工程打包额外加载其他 jar 方法
  • 最后是一个破解演示,仅适合个人学习使用

二、案例工程

我们通过一个案例工程来模拟破解过程是怎么做到的,其实每个版本的IDEA都在增强防护机制,破解也越来越难。

itstack-demo-code-idea└── src    ├── main    │   ├── java    │   │   └── org.itstack.demo    │   │       └── JetbrainsCrack.java    │   └── resources        │       └── META-INF        │           └── MANIFEST.MF    └── test         └── java             ├── com.jetbrains.ls.newLicenses             │   └── DecodeCertificates.java                          └── org.itstack.demo.test                 └── ApiTest.java

三、环境配置

  1. JDK 1.8
  2. IDEA 2019.3.1
  3. asm-all 3.3.1

四、代码讲述

在案例中我们模拟 IDEA 有一个 DecodeCertificates 类,用于做授权码校验。之后通过我们的 java agent 编程模拟授权被破解。

1. Java Agent 介绍

在 JDK1.5 以后,JVM 提供了 agent 技术构建一个独立于应用程序的代理程序(即为Agent),用来协助监测、运行甚至替换其他JVM上的程序。使用它可以实现虚拟机级别的AOP功能。

2. ASM 介绍

ASM 是一个 JAVA 字节码分析、创建和修改的开源应用框架。在 ASM 中提供了诸多的API用于对类的内容进行字节码操作的方法。与传统的 BCEL 和 SERL 不同,在 ASM 中提供了更为优雅和灵活的操作字节码的方式。目前 ASM 已被广泛的开源应用架构所使用,例如:Spring、Hibernate 等。

3. 开始我们的模拟破解之路

JetbrainsCrack.java & Agent 操作类

/** * 博客:http://bugstack.cn * 公众号:bugstack虫洞栈 | 更多原处优质干货 * Agent 类,所有程序启动只要配置了 -javaagent: 都会走到 premain 方法 */public class JetbrainsCrack {    public static void premain(String args, Instrumentation inst) {        System.out.println("**************************************");        System.out.println("*       公众号:bugstack虫洞栈       *");        System.out.println("*     博客:https://bugstack.cn      *");        System.out.println("*   你用剑,我用刀,好的代码都很烧! *");        System.out.println("**************************************");        inst.addTransformer(new MethodEntryTransformer());    }    static class MethodEntryTransformer implements ClassFileTransformer {        private Logger logger = LoggerFactory.getLogger(MethodEntryTransformer.class);        public byte[] transform(ClassLoader loader, String className, Class> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {            try {                if (className.equals("com/jetbrains/ls/newLicenses/DecodeCertificates")) {                    ClassReader cr = new ClassReader(classfileBuffer);                    ClassNode cn = new ClassNode();                    cr.accept(cn, 0);                    List methodNodes = cn.methods;                    for (MethodNode methodNode : methodNodes) {                        if ("decodeLicense".equals(methodNode.name)) {                            InsnList insns = methodNode.instructions;                            //清除指令                            insns.clear();                            insns.add(new VarInsnNode(Opcodes.ALOAD, 1)); // 将本地指定的引用存入栈中                            insns.add(new InsnNode(Opcodes.ARETURN));          // 从方法中返回引用类型的数据                            // 访问结束                            methodNode.visitEnd();                            ClassWriter cw = new ClassWriter(0);                            cn.accept(cw);                            byte[] bytes = cw.toByteArray();                            // 输出字节码到Class                            this.outputClazz(bytes);                            // 返回最新字节码                            return cw.toByteArray();                        }                    }                }            } catch (Exception e) {                return classfileBuffer;            }            return classfileBuffer;        }        private void outputClazz(byte[] bytes) {            // 输出类字节码            FileOutputStream out = null;            try {                out = new FileOutputStream("ASMDecodeCertificates.class");                logger.info("ASM类输出路径:{}", (new File("")).getAbsolutePath());                out.write(bytes);            } catch (Exception e) {                e.printStackTrace();            } finally {                if (null != out) try {                    out.close();                } catch (IOException e) {                    e.printStackTrace();                }            }        }    }}
  • 在这个类中可以看到有一个 premain 方法,这个是在被 java agent 处理后的程序入口,所有信息类和方法都会到这个入口
  • 之后我们使用 inst.addTransformer(new MethodEntryTransformer()); 添加我们自己的处理逻辑,这个逻辑也是用字节码编程技术代理类的过程。这个过程也就是我们平时开发中那些不需硬编码就可以监控方法执行时长的逻辑一样
  • MethodEntryTransformer 实现了 ClassFileTransformer 的 transform 方法,也就是真正操作字节码的过程。在这个类方法中首先需要找到我们的授权码校验类 com/jetbrains/ls/newLicenses/DecodeCertificates ,每一个版本的IDEA不一样,同时授权逻辑校验也不一样紧接着在找到授权校验类里面的校验方法,if ("decodeLicense".equals(methodNode.name))接下来就需要对字节码进行处理了,这里面的处理过程比较粗暴,直接将原来方法里的指令内容清空。然后使用 new VarInsnNode(Opcodes.ALOAD, 1) 将本地指定的引用存入栈中之后将我们的入参内容直接返回,new InsnNode(Opcodes.ARETURN),从方法中返回引用类型的数据。在以往旧版本的 IDEA 破解中比较简单,直接把最终需要的破解内容返回即可,里面描述了 IDEA 各个软件的使用期限最终将我们处理后的字节码返回给方法,return cw.toByteArray();这个时候虽然你大爷还是你大爷,但你大娘已经不是你大娘了
  • 为了测试的验证我们将变更后的字节码代码(大娘)输出到工程目录下,也就是一个 class 文件,下文测试时候验证

4. DecodeCertificates.java & 模拟 ideaIU-15.0.1 软件授权码校验类

public class DecodeCertificates {    public String decodeLicense(String usingKey) {        // 模拟校验授权码        return "usingKey is error:"+ usingKey;    }}
  • 这个类比较简单只是模拟有这么个方法用于校验授权码

5. ApiTest.java & 测试类

/** * 博客:http://bugstack.cn * 公众号:bugstack虫洞栈 | 更多原处优质干货 * 测试类配置 VM 参数 * Idea VM options:-javaagent:E:itstackGITitstack.orgitstack-demo-codeitstack-demo-code-ideaargetitstack-demo-code-idea-1.0-SNAPSHOT.jar */public class ApiTest {    private static Logger logger = LoggerFactory.getLogger(ApiTest.class);    public static void main(String[] args) throws Exception {        DecodeCertificates decodeCertificates = new DecodeCertificates();        // 模拟usingKey:认购有效期至2089年7月8日        String license = decodeCertificates.decodeLicense("Subscription is active until July 8, 2089");        logger.info("测试结果:{}", license);    }}

6. MANIFEST.MF 配置引导启动时加载

Manifest-Version: 1.0Premain-Class: org.itstack.demo.JetbrainsCrackCan-Redefine-Classes: true

7. POM 配置打包时加入ASM包

org.apache.maven.plugins    maven-shade-plugin    packageshadeasm:asm-all:jar:

五、工程测试

  1. 先单纯的直接运行ApiTest.java ,测试结果如下(模拟返回授权不可用);
21:23:46.101 [main] INFO org.itstack.demo.test.ApiTest - 测试结果:usingKey is error:Subscription is active until July 8, 2089

第二步测试前先打包下工程,这个时候你会看到如下结果;

[INFO] --- maven-install-plugin:2.4:install (default-install) @ itstack-demo-code-idea ---[INFO] Installing E:itstackGITitstack.orgitstack-demo-codeitstack-demo-code-ideaargetitstack-demo-code-idea-1.0-SNAPSHOT.jar to D:Program Files (x86)apache-maven-3.6.2epositoryorgitstackdemoitstack-demo-code-idea1.0-SNAPSHOTitstack-demo-code-idea-1.0-SNAPSHOT.jar[INFO] Installing E:itstackGITitstack.orgitstack-demo-codeitstack-demo-code-ideadependency-reduced-pom.xml to D:Program Files (x86)apache-maven-3.6.2epositoryorgitstackdemoitstack-demo-code-idea1.0-SNAPSHOTitstack-demo-code-idea-1.0-SNAPSHOT.pom[INFO] Installing E:itstackGITitstack.orgitstack-demo-codeitstack-demo-code-ideaargetitstack-demo-code-idea-1.0-SNAPSHOT-sources.jar to D:Program Files (x86)apache-maven-3.6.2epositoryorgitstackdemoitstack-demo-code-idea1.0-SNAPSHOTitstack-demo-code-idea-1.0-SNAPSHOT-sources.jar[INFO] ------------------------------------------------------------------------[INFO] BUILD SUCCESS[INFO] ------------------------------------------------------------------------[INFO] Total time:  3.080 s[INFO] Finished at: 2020-01-05T23:25:08+08:00[INFO] ------------------------------------------------------------------------

被代理前

public class DecodeCertificates {    public String decodeLicense(String usingKey) {        // 模拟校验授权码        return "usingKey is error:"+ usingKey;    }}

被代理后

package com.jetbrains.ls.newLicenses;public class DecodeCertificates {    public DecodeCertificates() {    }    public String decodeLicense(String usingKey) {        return usingKey;    }}

六、综上总结

  • 建议个人使用社区版即可,不要尝试破解尊重IDEA,本文只为学习 javaagent 技术
  • ASM 这个东西特别强大,其实字节码编程还有 javassist,在一起 RPC 框架中有非常多的使用

hibernate jar包_源码分析 | 咋嘞?你的IDEA过期了吧!加个Jar包就破解了为什么?相关推荐

  1. SpringBoot Jar包构建源码分析

    我们知道,SpringBoot仅凭一个Jar包就能将我们构建的整个工程跑起来,如果你也想知道这个能跑起来的jar内部结构是如何构建出来的,请耐心读完本篇,本篇内容可能有点多,但包你有收获.如果读完没有 ...

  2. 集合的get方法中参数从多少开始_源码分析CopyOnWriteArrayList 中的隐藏知识,你Get了吗?...

    欢迎点击 "未读代码" ,关注公众号,文章每周更新 杭州-阿里园区墙 前言 本觉 CopyOnWriteArrayList 过于简单,寻思看名字就能知道内部的实现逻辑,所以没有写这 ...

  3. 第4课第4节_Android灯光系统_源码分析_电池灯

    电池的监听器: Android灯光系统的源码分析与使用 4. 电池灯 a. batteryPropertiesRegistrar.registerListener(new BatteryListene ...

  4. 极光实时监听怎么调用_源码分析 Sentinel 实时数据采集实现原理(图文并茂)

    本篇将重点关注 Sentienl 实时数据收集,即 Sentienl 具体是如何收集调用信息,以此来判断是否需要触发限流或熔断. Sentienl 实时数据收集的入口类为 StatisticSlot. ...

  5. C# list集合 重复元素 索引_源码分析专题10-纯手写JDK不同版本下的List接口

    纯手写集合框架(下一篇:LinkeList原理) 集合框架介绍 说明:对于以上的框架图有如下几点说明 1.所有集合类都位于java.util包下.Java的集合类主要由两个接口派生而出:Collect ...

  6. Redis进阶-JedisCluster初始化 自动管理连接池中的连接 _ 源码分析

    文章目录 Pre Code 初始化 槽计算 无需手工调用close方法 Pre Redis进阶-Redis集群原理剖析及gossip协议初探 集群原理部分 简单的提了下Jest是如何实现Redis C ...

  7. 模仿Hibernate的逆向工程_java版_源码下载

    在这篇blog:"Hibernate逆向工程原理_java版本"中谈到了Hibernate逆向工程原理. 我喜欢理论和实践相结合....so,今天我试着模仿hibernate的逆向 ...

  8. 【Android 性能优化】应用启动优化 ( 阶段总结 | Trace 文件分析及解决方案 | 源码分析梳理 | 设置主题的方案总结 ) ★

    文章目录 一. 常用的耗时方法优化方案 ( 重要 ) 二. 源码分析梳理 1. 应用启动时间计算相关源码分析 2. Launcher 应用中启动 Android 应用流程 三. 启动白屏解决方案 An ...

  9. 插件式换肤框架搭建 - 资源加载源码分析

    资源加载源码分析 1.首先我们来看一下ImageView是如何加载资源的: public ImageView(Context context, @Nullable AttributeSet attrs ...

最新文章

  1. 比特币现金反弹,区块链是极好机遇
  2. PHP的echo和print小谈
  3. MySQL 命令行导出、导入Select 查询结果
  4. freemarker list size问题
  5. 一文带你学会 UML 统一建模语言
  6. Java反射机制深入研究
  7. 1260 不一样的A+B
  8. Win10提示不是有效的字体文件怎么解决
  9. 【技术文档】JEECG 页面字典控件与Popup使用
  10. Anaconda各版本安装包存档
  11. leetcode刷题:不同路径II
  12. html 签到日历,写一个签到日历
  13. linux程序没有对日志文件写的权限_好程序员云计算培训分享Linux文件权限简单说明...
  14. 多个kinect标定,颜色和深度的标定
  15. 电脑公司ghost win8 64位家庭克隆版v2020.05
  16. List转Map的三种方法
  17. 软件项目风险控制-公益讲座视频,供大家学习参考。
  18. [HDU5956]The Elder
  19. mysql实验训练2 数据查询操作_实验训练2:数据查询操作
  20. 图像的形状因子计算方法

热门文章

  1. Python traceback 模块, 打印异常信息
  2. css之文本两端对齐的两种解决方法
  3. iOS下Html页面中input获取焦点弹出键盘时挡住input解决方案—scrollIntoView()
  4. 解决 IntelliJ IDEA Tomcat 控制台中文输出乱码问题
  5. ORA-01502:索引或这类索引的分区处于不可用状态 的解决方法
  6. SAP ABAP里数据库表的Storage Parameters从哪里来的
  7. hdu 多校数论 GuGuFishtion
  8. k8s 关键字以及管理流程。
  9. Moebius实现Sqlserver集群~介绍篇
  10. CISCO上ADSL配置的方法