-
Автор темы
- #1
Перед прочтением основного контента ниже, пожалуйста, обратите внимание на обновление внутри секции Майна на нашем форуме. У нас появились:
- бесплатные читы для Майнкрафт — любое использование на свой страх и риск;
- маркетплейс Майнкрафт — абсолютно любая коммерция, связанная с игрой, за исключением продажи читов (аккаунты, предоставления услуг, поиск кодеров читов и так далее);
- приватные читы для Minecraft — в этом разделе только платные хаки для игры, покупайте группу "Продавец" и выставляйте на продажу свой софт;
- обсуждения и гайды — всё тот же раздел с вопросами, но теперь модернизированный: поиск нужных хаков, пати с игроками-читерами и другая полезная информация.
Спасибо!
Принцип работы ClassLoader и защита классов
ClassLoader в Java — это часть Java Runtime Environment (JRE), которая загружает классы Java в память при их первом использовании. В Java классы не встроены напрямую в исполняемый код; они загружаются по мере необходимости.
Создание и компиляция нашей .jar
В нашей .jar будет несколько классов: основной класс Main, который будет запускать остальные, и два других класса для проверки работы ClassLoader.
Main.java:
Test1.java:
Test2.java:
Чтобы скомпилировать эти файлы в .jar:
Теперь создадим класс Crypter для шифрования нашего класса:
Скомпилируйте и запустите этот класс командой
Если вы увидите сообщение
значит шифрование прошло успешно.
Загрузка и расшифровка класса
Теперь напишем загрузчик классов, который будет расшифровывать и загружать наш класс:
Скомпилируйте и запустите этот загрузчик. Если вы увидите 2 сообщения
значит загрузка и расшифровка прошли успешно
Теперь у вас есть базовое понимание работы ClassLoader и пример защиты классов с помощью шифрования. Вы можете доработать этот пример и создать более сложный загрузчик классов.
Upd: поставьте лайк , я старался писать эту тему.
ClassLoader в Java — это часть Java Runtime Environment (JRE), которая загружает классы Java в память при их первом использовании. В Java классы не встроены напрямую в исполняемый код; они загружаются по мере необходимости.
Создание и компиляция нашей .jar
В нашей .jar будет несколько классов: основной класс Main, который будет запускать остальные, и два других класса для проверки работы ClassLoader.
Main.java:
Main:
public class Main {
public static void main(String[] args) {
test2.One();
test3.Two();
}
}
test1:
public class test1 {
public static void One() {
System.out.println("был загружен 1 class");
}
}
test2:
public class test2 {
public static void Two() {
System.out.println("был загружен 2 class");
}
}
- Нажмите
Win + R
, введитеcmd
и запустите командную строку. - Перейдите в директорию, где находятся файлы
.java
. Например,C:\Users\user\Desktop
. - Введите команду
javac -d ./build *.java
. В папке build появятся несколько файлов.class
. - Перейдите в директорию build командой
cd build
и создайте .jar файл командойjar cvf test.jar *
. - Откройте созданный .jar файл через WinRAR, перейдите в папку META-INF и откройте файл MANIFEST.MF.
- Вставьте в самом низу
Main-Class: Main
, сохраните документ и выйдите.
Теперь создадим класс Crypter для шифрования нашего класса:
Crypter:
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import javax.swing.*;
import java.awt.*;
import java.awt.datatransfer.DataFlavor;
import java.awt.dnd.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.List;
public class Crypter extends JFrame {
private static final byte[] KEY_BYTES = {
(byte)0x01, (byte)0x23, (byte)0x67, (byte)0x45,
(byte)0x89, (byte)0xCD, (byte)0xAB, (byte)0xEF,
(byte)0x01, (byte)0x23, (byte)0x45, (byte)0x67,
(byte)0x89, (byte)0xAB, (byte)0xEF, (byte)0xCD
};
private JTextField inputFileField;
private JTextField outputFileField;
private JButton encryptButton;
public Crypter() {
setTitle("File Encrypter");
setSize(400, 200);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
JPanel panel = new JPanel(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.insets = new Insets(5, 5, 5, 5);
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridx = 0;
gbc.gridy = 0;
panel.add(new JLabel("Input File:"), gbc);
gbc.gridx = 1;
inputFileField = new JTextField();
panel.add(inputFileField, gbc);
gbc.gridx = 0;
gbc.gridy = 1;
panel.add(new JLabel("Output File:"), gbc);
gbc.gridx = 1;
outputFileField = new JTextField();
panel.add(outputFileField, gbc);
gbc.gridx = 1;
gbc.gridy = 2;
encryptButton = new JButton("Encrypt");
panel.add(encryptButton, gbc);
add(panel);
encryptButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
encryptFile();
}
});
new DropTarget(inputFileField, new FileDropTargetListener());
}
private void encryptFile() {
File inFile = new File(inputFileField.getText());
File outFile = new File(outputFileField.getText());
try {
SecretKey secretKey = new SecretKeySpec(KEY_BYTES, "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
FileInputStream fis = new FileInputStream(inFile);
byte[] inputBytes = new byte[(int) inFile.length()];
fis.read(inputBytes);
byte[] outputBytes = cipher.doFinal(inputBytes);
FileOutputStream fos = new FileOutputStream(outFile);
fos.write(outputBytes);
fis.close();
fos.close();
JOptionPane.showMessageDialog(this, "Encryption completed.");
} catch (Exception ex) {
ex.printStackTrace();
JOptionPane.showMessageDialog(this, "Error during encryption: " + ex.getMessage());
}
}
private class FileDropTargetListener extends DropTargetAdapter {
@Override
public void drop(DropTargetDropEvent dtde) {
try {
dtde.acceptDrop(DnDConstants.ACTION_COPY);
List<File> droppedFiles = (List<File>) dtde.getTransferable().getTransferData(DataFlavor.javaFileListFlavor);
if (!droppedFiles.isEmpty()) {
File file = droppedFiles.get(0);
inputFileField.setText(file.getAbsolutePath());
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new Crypter().setVisible(true);
}
});
}
}
java Crypter
. Если у вас открылось окно, значит вы сделали всё правильно, дальше можно просто закинуть файл. [
Пожалуйста, авторизуйтесь для просмотра ссылки.
]Если вы увидите сообщение
Encryption completed.
значит шифрование прошло успешно.
Загрузка и расшифровка класса
Теперь напишем загрузчик классов, который будет расшифровывать и загружать наш класс:
ClassLoader1:
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.nio.file.Files;
import java.security.Key;
import java.util.jar.JarEntry;
import java.util.jar.JarInputStream;
public class ClassLoader1 extends ClassLoader {
private static final byte[] KEY_BYTES = {
(byte)0x01, (byte)0x23, (byte)0x67, (byte)0x45,
(byte)0x89, (byte)0xCD, (byte)0xAB, (byte)0xEF,
(byte)0x01, (byte)0x23, (byte)0x45, (byte)0x67,
(byte)0x89, (byte)0xAB, (byte)0xEF, (byte)0xCD
};
public ClassLoader1(ClassLoader parent) {
super(parent);
}
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
try {
File encryptedJarFile = new File("C:/Users/users/Desktop/ja1r.jar");
byte[] encryptedJarBytes = Files.readAllBytes(encryptedJarFile.toPath());
Key key = new SecretKeySpec(KEY_BYTES, "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, key);
byte[] decryptedJarBytes = cipher.doFinal(encryptedJarBytes);
try (InputStream is = new ByteArrayInputStream(decryptedJarBytes);
JarInputStream jarStream = new JarInputStream(is)) {
JarEntry entry;
while ((entry = jarStream.getNextJarEntry()) != null) {
if (entry.getName().equals(name.replace('.', '/') + ".class")) {
byte[] classBytes = jarStream.readAllBytes();
return defineClass(name, classBytes, 0, classBytes.length);
}
}
}
throw new ClassNotFoundException("Class " + name + " not found in decrypted jar");
} catch (Exception e) {
throw new ClassNotFoundException("Could not load class " + name, e);
}
}
public static void main(String[] args) {
ClassLoader1 classLoader = new ClassLoader1(ClassLoader.getSystemClassLoader());
try {
Class<?> loadedClass = classLoader.findClass("Main");
System.out.println("Loaded class: " + loadedClass.getName());
Method mainMethod = loadedClass.getMethod("main", String[].class);
String[] mainArgs = new String[]{};
mainMethod.invoke(null, (Object) mainArgs);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Код:
был загружен 1 class
был загружен 2 class
Теперь у вас есть базовое понимание работы ClassLoader и пример защиты классов с помощью шифрования. Вы можете доработать этот пример и создать более сложный загрузчик классов.
Upd: поставьте лайк , я старался писать эту тему.
Последнее редактирование: