微信公衆號:bugstack蟲洞棧 | 博客: https://bugstack.cn
沉澱、分享、成長,專一於原創專題案例,以最易學習編程的方式分享知識,讓本身和他人都能有所收穫。目前已完成的專題有;Netty4.x實戰專題案例、用Java實現JVM、基於JavaAgent的全鏈路監控、手寫RPC框架、架構設計專題案例、源碼分析等。
你用劍🗡、我用刀🔪,好的代碼都很燒😏,望你不吝出招💨!
2020年了,對於一個程序猿來講;html
2020 = 1024 + 996 | 404 + 404 + 404 + 404 + 404 2021 = 1024 + 997 2022 = 1024 + 9106 2023 = 1024 + 9107 ... 20xx = 從今年開始可怕
當你過了元旦,爽了週末,清早上班,拿起杯子,加點新(薪)水,打開電腦,收起煩惱,翹起小腳,上揚嘴角。一切就緒都準備好,好!擼代碼!啊!!!IDEA duang duang duang,過時了!java
腦瓜一熱趕忙搜索破解碼;git
可能大部分夥伴都在搜各類一堆一大串的破解碼往裏面粘,一個個試到最後終於過了。但也有一部分老司機是不搜破解碼的,他們使用jar包破解,有效期100年。apache
那麼!本文並不想引導用戶都去使用破解版,像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 編程模擬受權被破解。maven
在 JDK1.5 之後,JVM 提供了 agent 技術構建一個獨立於應用程序的代理程序(即爲Agent),用來協助監測、運行甚至替換其餘JVM上的程序。使用它能夠實現虛擬機級別的AOP功能。ide
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(); } } } } }
MethodEntryTransformer 實現了 ClassFileTransformer 的 transform 方法,也就是真正操做字節碼的過程。
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] ------------------------------------------------------------------------
運行 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
被代理前
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; } }