微信公众号:bugstack虫洞栈 | 博客: bugstack.cn
沉淀、分享、成长,专注于原创专题案例,以最易学习编程的方式分享知识,让自己和他人都能有所收获。目前已完成的专题有;Netty4.x实战专题案例、用Java实现JVM、基于JavaAgent的全链路监控、手写RPC框架、架构设计专题案例、源码分析等。
你用剑 、我用刀:hocho:,好的代码都很烧:smirk:,望你不吝出招:dash:!
2020年了,对于一个程序猿来说;
2020 = 1024 + 996 | 404 + 404 + 404 + 404 + 404 2021 = 1024 + 997 2022 = 1024 + 9106 2023 = 1024 + 9107 ... 20xx = 从今年开始可怕 复制代码
当你过了元旦,爽了周末,清早上班,拿起杯子,加点新(薪)水,打开电脑,收起烦恼,翘起小脚,上扬嘴角。一切就绪都准备好,好!撸代码!啊!!!IDEA duang duang duang,过期了!
脑瓜一热赶紧搜索破解码;
可能大部分伙伴都在搜各种一堆一大串的破解码往里面粘,一个个试到最后终于过了。但也有一部分老司机是不搜破解码的,他们使用jar包破解,有效期100年。
那么!本文并不想引导用户都去使用破解版,像IDEA这么优秀,其实给你提供了很多选择;
所以,个人开发使用社区版本即可,不要使用破解。
好!回归正题,本文主要讲解是为什么放个Jar包就能破解,最后在使用一个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 复制代码
在案例中我们模拟 IDEA 有一个 DecodeCertificates 类,用于做授权码校验。之后通过我们的 java agent 编程模拟授权被破解。
在 JDK1.5 以后,JVM 提供了 agent 技术构建一个独立于应用程序的代理程序(即为Agent),用来协助监测、运行甚至替换其他JVM上的程序。使用它可以实现虚拟机级别的AOP功能。
ASM 是一个 JAVA 字节码分析、创建和修改的开源应用框架。在 ASM 中提供了诸多的API用于对类的内容进行字节码操作的方法。与传统的 BCEL 和 SERL 不同,在 ASM 中提供了更为优雅和灵活的操作字节码的方式。目前 ASM 已被广泛的开源应用架构所使用,例如:Spring、Hibernate 等。
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<MethodNode> 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(); } } } } } 复制代码
public class DecodeCertificates { public String decodeLicense(String usingKey) { // 模拟校验授权码 return "usingKey is error:"+ usingKey; } } 复制代码
/** * 博客:http://bugstack.cn * 公众号:bugstack虫洞栈 | 更多原处优质干货 * 测试类配置 VM 参数 * Idea VM options:-javaagent:E:/itstack/GIT/itstack.org/itstack-demo-code/itstack-demo-code-idea/target/itstack-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); } } 复制代码
Manifest-Version: 1.0 Premain-Class: org.itstack.demo.JetbrainsCrack Can-Redefine-Classes: true 复制代码
<!-- 将javassist包打包到Agent中 --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> </execution> </executions> <configuration> <artifactSet> <includes> <include>asm:asm-all:jar:</include> </includes> </artifactSet> </configuration> </plugin> 复制代码
先单纯的直接运行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:/itstack/GIT/itstack.org/itstack-demo-code/itstack-demo-code-idea/target/itstack-demo-code-idea-1.0-SNAPSHOT.jar to D:/Program Files (x86)/apache-maven-3.6.2/repository/org/itstack/demo/itstack-demo-code-idea/1.0-SNAPSHOT/itstack-demo-code-idea-1.0-SNAPSHOT.jar [INFO] Installing E:/itstack/GIT/itstack.org/itstack-demo-code/itstack-demo-code-idea/dependency-reduced-pom.xml to D:/Program Files (x86)/apache-maven-3.6.2/repository/org/itstack/demo/itstack-demo-code-idea/1.0-SNAPSHOT/itstack-demo-code-idea-1.0-SNAPSHOT.pom [INFO] Installing E:/itstack/GIT/itstack.org/itstack-demo-code/itstack-demo-code-idea/target/itstack-demo-code-idea-1.0-SNAPSHOT-sources.jar to D:/Program Files (x86)/apache-maven-3.6.2/repository/org/itstack/demo/itstack-demo-code-idea/1.0-SNAPSHOT/itstack-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] ------------------------------------------------------------------------ 复制代码
配置 VM options:-javaagent:E:/itstack/GIT/itstack.org/itstack-demo-code/itstack-demo-code-idea/target/itstack-demo-code-idea-1.0-SNAPSHOT.jar
运行 ApiTest 测试,正确结果如下;
23:29:42.803 [main] INFO org.itstack.demo.test.ApiTest - 测试结果:usingKey is error:Subscription is active until July 8, 2089 Process finished with exit code 0 复制代码
别忘了我们还在 Agent 中输出了新的字节码,看看这个时候的类是什么样(你大爷还是你大爷,但你大娘可不是你大娘了)
被代理前
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; } } 复制代码