微信公众号:bugstack虫洞栈 | 博客:bugstack.cn
沉淀、分享、成长,专一于原创专题案例,以最易学习编程的方式分享知识,让本身和他人都能有所收获。目前已完成的专题有;Netty4.x实战专题案例、用Java实现JVM、基于JavaAgent的全链路监控、手写RPC框架、架构设计专题案例、源码分析等。
你用剑🗡、我用刀🔪,好的代码都很烧😏,望你不吝出招💨!html
2020年了,对于一个程序猿来讲;java
2020 = 1024 + 996 | 404 + 404 + 404 + 404 + 404
2021 = 1024 + 997
2022 = 1024 + 9106
2023 = 1024 + 9107
...
20xx = 从今年开始可怕
复制代码
当你过了元旦,爽了周末,清早上班,拿起杯子,加点新(薪)水,打开电脑,收起烦恼,翘起小脚,上扬嘴角。一切就绪都准备好,好!撸代码!啊!!!IDEA duang duang duang,过时了!apache
脑瓜一热赶忙搜索破解码;编程
可能大部分伙伴都在搜各类一堆一大串的破解码往里面粘,一个个试到最后终于过了。但也有一部分老司机是不搜破解码的,他们使用jar包破解,有效期100年。微信
那么!本文并不想引导用户都去使用破解版,像IDEA这么优秀,其实给你提供了不少选择;架构
因此,我的开发使用社区版本便可,不要使用破解。框架
好!回归正题,本文主要讲解是为何放个Jar包就能破解,最后在使用一个jar进行破解演示。在如下章节中你能够学习到以下知识;maven
咱们经过一个案例工程来模拟破解过程是怎么作到的,其实每一个版本的IDEA都在加强防御机制,破解也愈来愈难。ide
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;
}
}
复制代码