first commit

This commit is contained in:
2024-06-22 01:36:29 +08:00
commit 292551fbc7
15 changed files with 940 additions and 0 deletions

View 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();
}
}

View 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();
}
}

View 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();
}
}
}
}

View 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);
}
}

View 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);
}
}

View 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); // 禁止获取焦点
}
}

View File

@ -0,0 +1,3 @@
Manifest-Version: 1.0
Main-Class: top.zunmx.Main