微信公衆號: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;
}
}
複製代碼