first commit
This commit is contained in:
38
.gitignore
vendored
Normal file
38
.gitignore
vendored
Normal file
@ -0,0 +1,38 @@
|
||||
target/
|
||||
!.mvn/wrapper/maven-wrapper.jar
|
||||
!**/src/main/**/target/
|
||||
!**/src/test/**/target/
|
||||
|
||||
### IntelliJ IDEA ###
|
||||
.idea/modules.xml
|
||||
.idea/jarRepositories.xml
|
||||
.idea/compiler.xml
|
||||
.idea/libraries/
|
||||
*.iws
|
||||
*.iml
|
||||
*.ipr
|
||||
|
||||
### Eclipse ###
|
||||
.apt_generated
|
||||
.classpath
|
||||
.factorypath
|
||||
.project
|
||||
.settings
|
||||
.springBeans
|
||||
.sts4-cache
|
||||
|
||||
### NetBeans ###
|
||||
/nbproject/private/
|
||||
/nbbuild/
|
||||
/dist/
|
||||
/nbdist/
|
||||
/.nb-gradle/
|
||||
build/
|
||||
!**/src/main/**/build/
|
||||
!**/src/test/**/build/
|
||||
|
||||
### VS Code ###
|
||||
.vscode/
|
||||
|
||||
### Mac OS ###
|
||||
.DS_Store
|
8
.idea/.gitignore
generated
vendored
Normal file
8
.idea/.gitignore
generated
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
# 默认忽略的文件
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# 基于编辑器的 HTTP 客户端请求
|
||||
/httpRequests/
|
||||
# Datasource local storage ignored files
|
||||
/dataSources/
|
||||
/dataSources.local.xml
|
8
.idea/artifacts/jetbrains_cracker_jar.xml
generated
Normal file
8
.idea/artifacts/jetbrains_cracker_jar.xml
generated
Normal file
@ -0,0 +1,8 @@
|
||||
<component name="ArtifactManager">
|
||||
<artifact type="jar" name="jetbrains_cracker:jar">
|
||||
<output-path>$PROJECT_DIR$/out/artifacts/jetbrains_cracker_jar</output-path>
|
||||
<root id="archive" name="jetbrains_cracker.jar">
|
||||
<element id="module-output" name="jetbrains_cracker" />
|
||||
</root>
|
||||
</artifact>
|
||||
</component>
|
8
.idea/encodings.xml
generated
Normal file
8
.idea/encodings.xml
generated
Normal file
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="Encoding">
|
||||
<file url="file://$PROJECT_DIR$/src/main/java" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/src/main/java/top/zunmx/MWindow.java" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/src/main/resources" charset="UTF-8" />
|
||||
</component>
|
||||
</project>
|
14
.idea/misc.xml
generated
Normal file
14
.idea/misc.xml
generated
Normal file
@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
||||
<component name="MavenProjectsManager">
|
||||
<option name="originalFiles">
|
||||
<list>
|
||||
<option value="$PROJECT_DIR$/pom.xml" />
|
||||
</list>
|
||||
</option>
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" project-jdk-name="1.8" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/out" />
|
||||
</component>
|
||||
</project>
|
124
.idea/uiDesigner.xml
generated
Normal file
124
.idea/uiDesigner.xml
generated
Normal file
@ -0,0 +1,124 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="Palette2">
|
||||
<group name="Swing">
|
||||
<item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
|
||||
</item>
|
||||
<item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
|
||||
</item>
|
||||
<item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
|
||||
</item>
|
||||
<item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.svg" removable="false" auto-create-binding="false" can-attach-label="true">
|
||||
<default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
|
||||
</item>
|
||||
<item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
|
||||
<initial-values>
|
||||
<property name="text" value="Button" />
|
||||
</initial-values>
|
||||
</item>
|
||||
<item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
|
||||
<initial-values>
|
||||
<property name="text" value="RadioButton" />
|
||||
</initial-values>
|
||||
</item>
|
||||
<item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
|
||||
<initial-values>
|
||||
<property name="text" value="CheckBox" />
|
||||
</initial-values>
|
||||
</item>
|
||||
<item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
|
||||
<initial-values>
|
||||
<property name="text" value="Label" />
|
||||
</initial-values>
|
||||
</item>
|
||||
<item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
|
||||
<preferred-size width="150" height="-1" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
|
||||
<preferred-size width="150" height="-1" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
|
||||
<preferred-size width="150" height="-1" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
|
||||
</item>
|
||||
<item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
|
||||
<preferred-size width="200" height="200" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
|
||||
<preferred-size width="200" height="200" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
|
||||
</item>
|
||||
<item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
|
||||
</item>
|
||||
<item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
|
||||
</item>
|
||||
<item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
|
||||
</item>
|
||||
<item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
|
||||
<preferred-size width="-1" height="20" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
|
||||
</item>
|
||||
<item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
|
||||
</item>
|
||||
</group>
|
||||
</component>
|
||||
</project>
|
86
pom.xml
Normal file
86
pom.xml
Normal file
@ -0,0 +1,86 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>org.example</groupId>
|
||||
<artifactId>jetbrains_cracker</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<packaging>jar</packaging>
|
||||
<properties>
|
||||
<maven.compiler.source>1.8</maven.compiler.source>
|
||||
<maven.compiler.target>1.8</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.javassist</groupId>
|
||||
<artifactId>javassist</artifactId>
|
||||
<version>3.28.0-GA</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-assembly-plugin</artifactId>
|
||||
<version>3.3.0</version>
|
||||
<configuration>
|
||||
<archive>
|
||||
<manifest>
|
||||
<mainClass>top.zunmx.Main</mainClass>
|
||||
</manifest>
|
||||
</archive>
|
||||
<descriptorRefs>
|
||||
<descriptorRef>jar-with-dependencies</descriptorRef>
|
||||
</descriptorRefs>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>make-assembly</id>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>single</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<!-- <build>-->
|
||||
<!-- <plugins>-->
|
||||
<!-- <plugin>-->
|
||||
<!-- <groupId>org.apache.maven.plugins</groupId>-->
|
||||
<!-- <artifactId>maven-compiler-plugin</artifactId>-->
|
||||
<!-- <version>3.11.0</version>-->
|
||||
<!-- <configuration>-->
|
||||
<!-- <source>1.8</source>-->
|
||||
<!-- <target>1.8</target>-->
|
||||
<!-- </configuration>-->
|
||||
<!-- </plugin>-->
|
||||
|
||||
<!-- <plugin>-->
|
||||
<!-- <groupId>org.apache.maven.plugins</groupId>-->
|
||||
<!-- <artifactId>maven-jar-plugin</artifactId>-->
|
||||
<!-- <version>3.3.0</version>-->
|
||||
<!-- <configuration>-->
|
||||
<!-- <archive>-->
|
||||
<!-- <manifest>-->
|
||||
<!-- <mainClass>top.zunmx.Main</mainClass>-->
|
||||
<!-- <addClasspath>true</addClasspath>-->
|
||||
<!-- <classpathPrefix>lib/</classpathPrefix>-->
|
||||
<!-- <useUniqueVersions>false</useUniqueVersions>-->
|
||||
<!-- </manifest>-->
|
||||
<!-- <manifestEntries>-->
|
||||
<!-- <Premain-Class>top.zunmx.Main</Premain-Class>-->
|
||||
<!-- </manifestEntries>-->
|
||||
<!-- </archive>-->
|
||||
<!-- </configuration>-->
|
||||
<!-- </plugin>-->
|
||||
<!-- </plugins>-->
|
||||
<!-- </build>-->
|
||||
</project>
|
185
readme.md
Normal file
185
readme.md
Normal file
@ -0,0 +1,185 @@
|
||||
# 引言
|
||||
|
||||
tb上买过教育版,结果用了一年多就封了,我记得之前用过ja-netfilter,用的是激活码,但是看起来直接替换的这种解决方案不太靠谱,现在是使用jetbra.in激活服务器激活,但是如果断网条件下,或者某一天这个网站down了,就没办法了,尝试过通过fiddler拦截激活服务器的响应,发现相同请求所获得的响应是不同的,加密算法也搞不懂,power.conf也看不懂,用着就不放心,还是社区版搞起吧,毕竟社区版也够用了。这里也是从52大神那里作为参考,想到的另一种方案,此方法仅供技术研究和讨论,切勿用于商业用途,否则后果自负。
|
||||
|
||||
经测试idea,datagrip,clion均过许可
|
||||
|
||||
# 版本
|
||||
|
||||
idea 2024.1.3
|
||||
|
||||
# 准备工作
|
||||
|
||||
jadx
|
||||
idea
|
||||
arthas
|
||||
jdk
|
||||
|
||||
# 思路
|
||||
|
||||
## 找到窗口
|
||||
|
||||

|
||||

|
||||
|
||||
通过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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
执行完成后,需要把生成的文件替换回去。
|
||||
|
||||
# 测试
|
||||
|
||||

|
||||

|
||||
|
||||
# 注意
|
||||
|
||||
这里需要注意的是,上文代码中的Licenses和许可证是写死的,如果使用其他语言的语言包,需要手动修改一下。
|
||||
|
||||
jar文件路径
|
||||
idea == > app-client.jar
|
||||
clion ==> app-client.jar
|
||||
datagrip ==> app.jar
|
||||
操作前需要先备份一下
|
||||
|
||||
经过测试,MyDialog是所有子窗口的类,如果一股脑全部关闭,设置,新建,打开,关于,你都将无法看到。
|
||||
但是用了这个方法,注册窗口也是无法显示出来的
|
||||
|
||||
|
||||
这种方法不能绕过插件的激活
|
||||
|
||||
|
||||
# 工程实例
|
||||
|
||||

|
||||

|
||||
|
||||
[jc.zip](https://www.zunmx.top/usr/uploads/2024/06/1200008417.zip)
|
||||
|
||||
运行:
|
||||
|
||||
```bash
|
||||
java -jar jetbrains_cracker-1.0-SNAPSHOT-jar-with-dependencies.jar
|
||||
```
|
||||
|
||||
⚠ 仅以开源和学习精神,切勿用于商业用途。
|
||||
|
||||
# 结语
|
||||
|
||||
|
||||
请支持正版,仅供研究学习使用,请勿用于非法用途。
|
219
src/main/java/top/zunmx/MWindow.java
Normal file
219
src/main/java/top/zunmx/MWindow.java
Normal file
@ -0,0 +1,219 @@
|
||||
package top.zunmx;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import javax.swing.JFileChooser;
|
||||
|
||||
public class MWindow extends Frame {
|
||||
private static MyList logList;
|
||||
private final MyButton selectDirButton;
|
||||
private final MyButton clearListButton;
|
||||
private final MyButton creckButton;
|
||||
private MyTextArea textLabel;
|
||||
private Thread searchThread;
|
||||
public static boolean stop = false;
|
||||
private static ArrayList<String> file_paths = new ArrayList();
|
||||
|
||||
public static String findAppJar(File dir) {
|
||||
File[] files = dir.listFiles();
|
||||
if (files != null) {
|
||||
lab1:
|
||||
for (File file : files) {
|
||||
if (stop) break;
|
||||
if (file.isDirectory()) {
|
||||
if (file.getName().equalsIgnoreCase("lib")) {
|
||||
File[] libFiles = file.listFiles();
|
||||
if (libFiles != null) {
|
||||
for (File libFile : libFiles) {
|
||||
if (stop) break;
|
||||
if (libFile.isFile() && libFile.getName().equalsIgnoreCase("app.jar")) {
|
||||
file_paths.add(file.getAbsolutePath());
|
||||
break lab1;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// 递归检查子目录
|
||||
if (stop) break;
|
||||
if (findAppJar(file) != null) {
|
||||
file_paths.add(file.getAbsolutePath());
|
||||
break lab1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void buttonEnabled(boolean flag) {
|
||||
// clearListButton.setEnabled(flag);
|
||||
creckButton.setEnabled(flag);
|
||||
selectDirButton.setEnabled(flag);
|
||||
}
|
||||
|
||||
|
||||
public MWindow() {
|
||||
// 设置窗口标题
|
||||
super("JetBrains License Cracker V1.0");
|
||||
|
||||
// 设置窗口布局
|
||||
setLayout(new BorderLayout());
|
||||
|
||||
// 创建目录选择器按钮
|
||||
selectDirButton = new MyButton("Select Jetbrains Path");
|
||||
selectDirButton.addActionListener(e -> {
|
||||
File directory = selectDirectory();
|
||||
if (directory != null && directory.isDirectory()) {
|
||||
logList.removeAll();
|
||||
file_paths.clear();
|
||||
if (directory.exists() && directory.isDirectory()) {
|
||||
logList.add("=============================[SEARCHING]=================================");
|
||||
stop = false;
|
||||
logList.add("[i] Searching for jetbrains product in " + directory.getAbsolutePath());
|
||||
new Thread(() -> {
|
||||
this.buttonEnabled(false);
|
||||
Thread searchThread = new Thread(() -> findAppJar(directory));
|
||||
searchThread.start();
|
||||
try {
|
||||
searchThread.join();
|
||||
logList.add("=============================[FOUND " + file_paths.size() + " ITEM]=================================");
|
||||
for (String filePath : file_paths) {
|
||||
logList.add("[#] Found Product: " + filePath);
|
||||
}
|
||||
|
||||
if (stop) {
|
||||
logList.add("[!] STOPPED");
|
||||
}
|
||||
this.buttonEnabled(true);
|
||||
} catch (InterruptedException ex) {
|
||||
logList.add("[x] Exception: " + ex.getMessage());
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
}).start();
|
||||
|
||||
|
||||
} else {
|
||||
logList.add("[!] The specified path is not a directory or does not exist.");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// 创建清除列表按钮
|
||||
clearListButton = new MyButton("Reset / Clear List");
|
||||
clearListButton.addActionListener(e -> {
|
||||
stop = true;
|
||||
logList.removeAll();
|
||||
file_paths.clear();
|
||||
});
|
||||
|
||||
// 创建破解按钮
|
||||
creckButton = new MyButton("Crack!");
|
||||
creckButton.addActionListener(e -> {
|
||||
if (file_paths.isEmpty()) {
|
||||
logList.removeAll();
|
||||
logList.add("[!] No product found");
|
||||
logList.add("[!] Please select the Jetbrains software installation directory.");
|
||||
return;
|
||||
}
|
||||
buttonEnabled(false);
|
||||
new Thread(() -> {
|
||||
Thread thread = new Thread(() -> {
|
||||
for (String filePath : file_paths) {
|
||||
try {
|
||||
String[] split = filePath.split("\\\\");
|
||||
String product = split[filePath.split("\\\\").length - 2];
|
||||
logList.add("=============================[CRACKING " + product + "]=================================");
|
||||
logList.add("[i] Cracking " + filePath);
|
||||
ModifyDialogWrapperPeerImpl modifyDialogWrapperPeer = new ModifyDialogWrapperPeerImpl();
|
||||
modifyDialogWrapperPeer.crack_it(filePath, logList);
|
||||
modifyDialogWrapperPeer = null;
|
||||
System.gc();
|
||||
if (stop) {
|
||||
logList.add("[!] STOPPED");
|
||||
break;
|
||||
}
|
||||
} catch (Exception except) {
|
||||
logList.add("[!] Crack Failed: " + except.getMessage());
|
||||
}
|
||||
}
|
||||
});
|
||||
thread.start();
|
||||
try {
|
||||
thread.join();
|
||||
} catch (InterruptedException ex) {
|
||||
logList.add("[x] Exception: " + ex.getMessage());
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
buttonEnabled(true);
|
||||
}).start();
|
||||
|
||||
});
|
||||
textLabel = new MyTextArea("[i] Usage\n" +
|
||||
" 1. Click [Select Jetbrains Path] Button\n" +
|
||||
" 2. Select Jetbrains software installation directory\n" +
|
||||
" eg. C:\\program files\\Jetbrains\n" +
|
||||
" 3. Click [crack!] Button\n" +
|
||||
" 4. Just a moment. \n\n" +
|
||||
"[!] Recovery\n" +
|
||||
" If you want to restore the original version,\n" +
|
||||
" go to the lib\\JZC-backup directory under the product installation directory,\n" +
|
||||
" find the backup files, and replace the files that in the lib directory.\n" +
|
||||
"[!] Crack by Bypass the license window for trial\n" +
|
||||
"[x] For code academic exchange only, do not use for commercial purposes\n" +
|
||||
"[x] please delete the sample within 24 hours\n" +
|
||||
"[i] Detection to prevent repeated cracking\n" +
|
||||
"[i] Patch by ZunMX\n", 9, 30, TextArea.SCROLLBARS_VERTICAL_ONLY);
|
||||
|
||||
// 创建文件列表
|
||||
logList = new MyList();
|
||||
|
||||
// 创建按钮面板
|
||||
Panel buttonPanel = new Panel();
|
||||
buttonPanel.setLayout(new FlowLayout());
|
||||
buttonPanel.add(selectDirButton);
|
||||
buttonPanel.add(clearListButton);
|
||||
buttonPanel.add(creckButton);
|
||||
|
||||
// 添加组件到窗口
|
||||
add(buttonPanel, BorderLayout.NORTH);
|
||||
add(logList, BorderLayout.CENTER);
|
||||
add(textLabel, BorderLayout.SOUTH);
|
||||
|
||||
// 设置窗口关闭行为
|
||||
addWindowListener(new WindowAdapter() {
|
||||
public void windowClosing(WindowEvent e) {
|
||||
System.exit(0);
|
||||
}
|
||||
});
|
||||
|
||||
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
|
||||
this.setSize(750, 550);
|
||||
Dimension windowSize = this.getSize();
|
||||
int x = (screenSize.width - windowSize.width) / 2;
|
||||
int y = (screenSize.height - windowSize.height) / 2;
|
||||
this.setLocation(x, y);
|
||||
setVisible(true);
|
||||
validate();
|
||||
repaint();
|
||||
}
|
||||
|
||||
private File selectDirectory() {
|
||||
File directory = null;
|
||||
JFileChooser fileChooser = new JFileChooser();
|
||||
fileChooser.setDialogTitle("Choose Jetbrains path");
|
||||
// fileChooser.setCurrentDirectory(new File("d:\\software\\jetbrains"));
|
||||
fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
|
||||
int option = fileChooser.showOpenDialog(this);
|
||||
if (option == JFileChooser.APPROVE_OPTION) {
|
||||
directory = fileChooser.getSelectedFile();
|
||||
}
|
||||
return directory;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
new MWindow();
|
||||
}
|
||||
}
|
13
src/main/java/top/zunmx/Main.java
Normal file
13
src/main/java/top/zunmx/Main.java
Normal file
@ -0,0 +1,13 @@
|
||||
package top.zunmx;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
public class Main {
|
||||
public static void main(String[] args) {
|
||||
// ModifyDialogWrapperPeerImpl.crack_it("D:\\software\\JetBrains\\DataGrip 2024.1.2\\lib");
|
||||
// ModifyDialogWrapperPeerImpl.crack_it("D:\\software\\JetBrains\\CLion 2024.1.4\\lib");
|
||||
JOptionPane.showMessageDialog(null,
|
||||
"此程序仅用于学术交流,切勿用于商业用途,您若花钱购买此产品,请立即举报商家!","注意",2);
|
||||
new MWindow();
|
||||
}
|
||||
}
|
190
src/main/java/top/zunmx/ModifyDialogWrapperPeerImpl.java
Normal file
190
src/main/java/top/zunmx/ModifyDialogWrapperPeerImpl.java
Normal file
@ -0,0 +1,190 @@
|
||||
package top.zunmx;
|
||||
|
||||
|
||||
import javassist.*;
|
||||
|
||||
import java.awt.*;
|
||||
import java.io.*;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.nio.file.*;
|
||||
import java.util.Enumeration;
|
||||
import java.util.jar.*;
|
||||
|
||||
public class ModifyDialogWrapperPeerImpl {
|
||||
public String filename = "";
|
||||
public String backupPath = "";
|
||||
public String middlePath = "";
|
||||
public String bkPath = "";
|
||||
public MyList logList;
|
||||
private CtClass ctClass;
|
||||
private URLClassLoader urlClassLoader;
|
||||
private ClassPool pool = null;
|
||||
private LoaderClassPath jarClassPath = null;
|
||||
|
||||
public boolean deleteDirectory(String dirPath) {
|
||||
File directory = new File(dirPath);
|
||||
|
||||
// 检查目录是否存在
|
||||
if (!directory.exists()) {
|
||||
logList.add("[#] Directory " + dirPath + " does not exist.");
|
||||
return false;
|
||||
}
|
||||
|
||||
// 递归删除目录中的所有文件和子目录
|
||||
File[] files = directory.listFiles();
|
||||
if (files != null) {
|
||||
for (File file : files) {
|
||||
if (file.isDirectory()) {
|
||||
deleteDirectory(file.getAbsolutePath());
|
||||
} else {
|
||||
file.delete();
|
||||
logList.add(" |-[#] Deleted file: " + file.getAbsolutePath());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 最后尝试删除空目录
|
||||
logList.add(" |-[#] Deleting directory: " + directory.getAbsolutePath());
|
||||
return directory.delete();
|
||||
}
|
||||
|
||||
public void moveFile(String sourcePath, String targetPath) throws IOException {
|
||||
Path src = Paths.get(sourcePath);
|
||||
Path dest = Paths.get(targetPath);
|
||||
Files.move(src, dest, StandardCopyOption.REPLACE_EXISTING);
|
||||
logList.add("[#] Moved backup file from " + sourcePath + " to " + targetPath);
|
||||
}
|
||||
|
||||
public String checker(String dirPath) {
|
||||
File file = new File(dirPath + "\\" + "JCZ-backup");
|
||||
boolean directory = file.exists();
|
||||
if (!directory) {
|
||||
logList.add("[#] JCZ-backup folder not found, creating...");
|
||||
file.mkdir();
|
||||
}
|
||||
file = new File(dirPath + "\\" + "JCZ-middle");
|
||||
directory = file.exists();
|
||||
if (!directory) {
|
||||
logList.add("[#] JCZ-middle folder not found, creating...");
|
||||
file.mkdir();
|
||||
}
|
||||
backupPath = dirPath + "\\" + "JCZ-backup";
|
||||
middlePath = dirPath + "\\" + "JCZ-middle";
|
||||
if (new File(dirPath + "\\" + "app-client.jar").exists()) {
|
||||
filename = "app-client.jar";
|
||||
logList.add("[#] app-client.jar found, using it.");
|
||||
return dirPath + "\\" + "app-client.jar";
|
||||
} else {
|
||||
filename = "app.jar";
|
||||
logList.add("[#] app.jar found, using it.");
|
||||
return dirPath + "\\" + "app.jar";
|
||||
}
|
||||
}
|
||||
|
||||
public void crack_it(String dirPath, MyList log_list) throws Exception {
|
||||
logList = log_list;
|
||||
pool = ClassPool.getDefault();
|
||||
String d_jarPath = checker(dirPath);
|
||||
File file = new File(backupPath + "\\" + filename);
|
||||
if (file.exists()) {
|
||||
bkPath = backupPath + "\\" + System.currentTimeMillis() + filename;
|
||||
moveFile(backupPath + "\\" + filename, bkPath); // 将原来的文件备份起来
|
||||
}
|
||||
moveFile(d_jarPath, backupPath + "\\" + filename); // 将原来的文件备份起来
|
||||
bkPath = backupPath + "\\" + filename;
|
||||
String jarPath = backupPath + "\\" + filename;
|
||||
File jar_url = new File(jarPath);
|
||||
urlClassLoader = new URLClassLoader(
|
||||
new URL[]{jar_url.toURI().toURL()}
|
||||
);
|
||||
jarClassPath = new LoaderClassPath(urlClassLoader);
|
||||
|
||||
pool.insertClassPath(jarClassPath);
|
||||
logList.add("[#] Loading jar file: " + jarPath);
|
||||
ctClass = pool.get("com.intellij.openapi.ui.impl.DialogWrapperPeerImpl"); // 类名
|
||||
CtMethod setTitleMethod = ctClass.getDeclaredMethod("setTitle",
|
||||
new CtClass[]{pool.get("java.lang.String")}); // 方法名
|
||||
if (setTitleMethod.getMethodInfo().getCodeAttribute().getCode().length > 20) {
|
||||
ctClass.detach();
|
||||
urlClassLoader.close();
|
||||
pool.removeClassPath(jarClassPath);
|
||||
logList.add("[!] The file seems to have been cracked. EXIT");
|
||||
moveFile(bkPath, dirPath + "\\" + filename);
|
||||
throw new RuntimeException("PRODUCT HAS BEEN CRACKED!");
|
||||
}
|
||||
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(\"发现激活窗口,即将关闭\");" +
|
||||
"Exception e = new Exception(\"↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓\");\n" +
|
||||
"System.out.println(\"调用栈信息-->\");" +
|
||||
"e.printStackTrace();" +
|
||||
" }"); // 注入的代码
|
||||
logList.add("[#] Modifying class: " + ctClass.getName());
|
||||
ctClass.writeFile(middlePath);
|
||||
ctClass.detach();
|
||||
updateJarFile(jarPath, middlePath, d_jarPath);
|
||||
logList.add("[#] Exporting modified jar file: " + d_jarPath);
|
||||
moveFile(jarPath, backupPath + "\\" + filename);
|
||||
new File(d_jarPath).renameTo(new File(jarPath));
|
||||
logList.add("[#] Deleting middle folder: " + middlePath);
|
||||
|
||||
|
||||
urlClassLoader.close();
|
||||
pool.removeClassPath(jarClassPath);
|
||||
deleteDirectory(middlePath);
|
||||
logList.add("[√] Cracked ^_^");
|
||||
|
||||
}
|
||||
|
||||
public 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();
|
||||
fos.close();
|
||||
}
|
||||
|
||||
private 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
11
src/main/java/top/zunmx/MyButton.java
Normal file
11
src/main/java/top/zunmx/MyButton.java
Normal file
@ -0,0 +1,11 @@
|
||||
package top.zunmx;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
|
||||
public class MyButton extends JButton {
|
||||
public MyButton(String label)
|
||||
{
|
||||
super(label);
|
||||
}
|
||||
}
|
18
src/main/java/top/zunmx/MyList.java
Normal file
18
src/main/java/top/zunmx/MyList.java
Normal file
@ -0,0 +1,18 @@
|
||||
package top.zunmx;
|
||||
|
||||
import java.awt.*;
|
||||
|
||||
public class MyList extends List {
|
||||
public MyList() {
|
||||
super();
|
||||
this.setBackground(new Color(125,125,125));
|
||||
this.setForeground(new Color(255, 255, 255, 255));
|
||||
Font font = new Font("Monospaced", Font.PLAIN, 14);
|
||||
this.setFont(font);
|
||||
}
|
||||
@Override
|
||||
public void add(String item) {
|
||||
super.add(item);
|
||||
this.select(this.getItemCount() - 1);
|
||||
}
|
||||
}
|
15
src/main/java/top/zunmx/MyTextArea.java
Normal file
15
src/main/java/top/zunmx/MyTextArea.java
Normal file
@ -0,0 +1,15 @@
|
||||
package top.zunmx;
|
||||
|
||||
import java.awt.*;
|
||||
|
||||
public class MyTextArea extends TextArea {
|
||||
public MyTextArea(String text, int rows, int columns, int style) {
|
||||
super(text, rows, columns, style);
|
||||
this.setEditable(false);
|
||||
this.setBackground(new Color(125,125,125));
|
||||
this.setForeground(new Color(255, 251, 0, 255));
|
||||
this.setEditable(false);
|
||||
this.setFont(new Font("Monospaced", Font.BOLD, 14));
|
||||
this.setFocusable(false); // 禁止获取焦点
|
||||
}
|
||||
}
|
3
src/main/resources/META-INF/MANIFEST.MF
Normal file
3
src/main/resources/META-INF/MANIFEST.MF
Normal file
@ -0,0 +1,3 @@
|
||||
Manifest-Version: 1.0
|
||||
Main-Class: top.zunmx.Main
|
||||
|
Reference in New Issue
Block a user