jetbrains_cracker/readme.md

188 lines
7.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 引言
tb上买过教育版结果用了一年多就封了我记得之前用过ja-netfilter用的是激活码但是看起来直接替换的这种解决方案不太靠谱现在是使用jetbra.in激活服务器激活但是如果断网条件下或者某一天这个网站down了就没办法了尝试过通过fiddler拦截激活服务器的响应发现相同请求所获得的响应是不同的加密算法也搞不懂power.conf也看不懂用着就不放心还是社区版搞起吧毕竟社区版也够用了。这里也是从52大神那里作为参考想到的另一种方案此方法仅供技术研究和讨论切勿用于商业用途否则后果自负。
经测试idea,datagrip,clion均过许可
# 版本
idea 2024.1.3
# 准备工作
jadx
idea
arthas
jdk
# 思路
## 找到窗口
![image.png](https://www.zunmx.top/usr/uploads/2024/06/799549738.png)
![image.png](https://www.zunmx.top/usr/uploads/2024/06/3547910640.png)
通过arthas获取awt的窗口`$ ognl '@java.awt.Window@getWindows()'`
尝试关闭窗口`ognl '@javax.swing.JDialog@getWindows()[3].dispose()'`
发现idea并没有完全退出如果直接手动点退出的话程序会结束
## 找到类名
上文中找到窗口了,类名其实也就出来了,但是如何判断`com.intellij.openapi.ui.impl.DialogWrapperPeerImpl$MyDialogWrapperImpl`具体在哪个包里,还是有些困难,通过`sc -d -f com.intellij.openapi.ui.impl.DialogWrapperPeerImpl`并没有找到这里就是猜猜到app-client.jar文件
## 分析代码
找到注入位置这里也踩了很多坑比如说关闭了不该关闭的窗口但是开发过java的应该都熟悉get/set方法那么在setTitle时检查名称是不是就可以判断出这个窗口是不是应该关闭了
## 写代码
### 依赖
```xml
<dependencies>
<dependency>
<groupId>org.javassist</groupId>
<artifactId>javassist</artifactId>
<version>3.28.0-GA</version>
</dependency>
</dependencies>
```
### 代码
```java
package org.example;
import javassist.*;
import java.io.*;
import java.util.Enumeration;
import java.util.jar.*;
public class ModifyDialogWrapperPeerImpl {
public static void main(String[] args) {
try {
ClassPool pool = ClassPool.getDefault();
String jarPath = "G:\\test\\app-client-old.jar"; // jar文件路径
String exportPath = "G:\\test\\app-client.jar"; // jar文件路径
pool.insertClassPath(jarPath);
CtClass ctClass = pool.get("com.intellij.openapi.ui.impl.DialogWrapperPeerImpl"); // 类名
CtMethod setTitleMethod = ctClass.getDeclaredMethod("setTitle",
new CtClass[]{pool.get("java.lang.String")}); // 方法名
setTitleMethod.insertBefore("{ System.out.println(\"即将打开窗口-->\"+$1);" +
"boolean isLicenseWindow = false;" +
"if($1.indexOf(\"许可证\")>-1) {isLicenseWindow=true; this.dispose();}" +
"if($1.indexOf(\"Licenses\")>-1) {isLicenseWindow=true; this.dispose();}" +
"if(isLicenseWindow)System.out.println(\"发现激活窗口,即将关闭\");" +
" }"); // 注入的代码
String tempDir = "G:\\test\\modified_classes";
ctClass.writeFile(tempDir);
ctClass.detach();
updateJarFile("G:\\test\\app-client-old.jar", tempDir, exportPath);
System.out.println("Method modified successfully.");
} catch (NotFoundException | CannotCompileException | IOException e) {
e.printStackTrace();
}
}
public static void updateJarFile(String originalJarPath, String modifiedClassesPath, String outputJarPath) throws IOException {
JarFile originalJar = new JarFile(originalJarPath);
FileOutputStream fos = new FileOutputStream(outputJarPath);
JarOutputStream jos = new JarOutputStream(fos);
// 复制原始JAR中的所有文件到新的JAR中跳过要修改的类文件
Enumeration<JarEntry> entries = originalJar.entries();
while (entries.hasMoreElements()) {
JarEntry entry = entries.nextElement();
if (!entry.getName().equals("com/intellij/openapi/ui/impl/DialogWrapperPeerImpl.class")) { // 跳过要修改的类文件
InputStream is = originalJar.getInputStream(entry);
jos.putNextEntry(new JarEntry(entry.getName()));
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = is.read(buffer)) != -1) {
jos.write(buffer, 0, bytesRead);
}
is.close();
jos.closeEntry();
}
}
originalJar.close();
// 添加修改后的类文件到新的JAR中
File modifiedClassesDir = new File(modifiedClassesPath);
addModifiedFilesToJar(modifiedClassesDir, "", jos);
jos.close();
}
private static void addModifiedFilesToJar(File source, String parent, JarOutputStream jos) throws IOException {
File[] files = source.listFiles();
for (File file : files) {
if (file.isDirectory()) {
addModifiedFilesToJar(file, parent + file.getName() + "/", jos);
} else {
FileInputStream fis = new FileInputStream(file);
jos.putNextEntry(new JarEntry(parent + file.getName()));
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = fis.read(buffer)) != -1) {
jos.write(buffer, 0, bytesRead);
}
fis.close();
jos.closeEntry();
}
}
}
}
```
执行完成后,需要把生成的文件替换回去。
# 测试
![image.png](https://www.zunmx.top/usr/uploads/2024/06/2847269302.png)
![image.png](https://www.zunmx.top/usr/uploads/2024/06/709101366.png)
# 注意
这里需要注意的是上文代码中的Licenses和许可证是写死的如果使用其他语言的语言包需要手动修改一下。
jar文件路径
idea == > app-client.jar
clion ==> app-client.jar
datagrip ==> app.jar
操作前需要先备份一下
经过测试MyDialog是所有子窗口的类如果一股脑全部关闭设置新建打开关于你都将无法看到。
但是用了这个方法,注册窗口也是无法显示出来的
这种方法不能绕过插件的激活
IntelliJ IDEA 2025.2 (Ultimate Edition) 可以配合ja-netfilter使用因为是不是提示 'Ultimate'功能需要许可证
# 工程实例
![image.png](https://www.zunmx.top/usr/uploads/2024/06/3344638210.png)
![image.png](https://www.zunmx.top/usr/uploads/2024/06/92482229.png)
[jc.zip](https://www.zunmx.top/usr/uploads/2024/06/1200008417.zip)
运行:
```bash
java -jar jetbrains_cracker-1.0-SNAPSHOT-jar-with-dependencies.jar
```
⚠ 仅以开源和学习精神,切勿用于商业用途。
# 结语
请支持正版,仅供研究学习使用,请勿用于非法用途。