Гайд Как защитить чит используя class loader

Начинающий
Статус
Оффлайн
Регистрация
8 Май 2023
Сообщения
457
Реакции[?]
5
Поинты[?]
6K

Перед прочтением основного контента ниже, пожалуйста, обратите внимание на обновление внутри секции Майна на нашем форуме. У нас появились:

  • бесплатные читы для Майнкрафт — любое использование на свой страх и риск;
  • маркетплейс Майнкрафт — абсолютно любая коммерция, связанная с игрой, за исключением продажи читов (аккаунты, предоставления услуг, поиск кодеров читов и так далее);
  • приватные читы для Minecraft — в этом разделе только платные хаки для игры, покупайте группу "Продавец" и выставляйте на продажу свой софт;
  • обсуждения и гайды — всё тот же раздел с вопросами, но теперь модернизированный: поиск нужных хаков, пати с игроками-читерами и другая полезная информация.

Спасибо!

Принцип работы ClassLoader и защита классов
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.java:

test1:
public class test1 {
    public static void One() {
        System.out.println("был загружен 1 class");
    }
}
Test2.java:

test2:
public class test2 {
    public static void Two() {
        System.out.println("был загружен 2 class");
    }
}
Чтобы скомпилировать эти файлы в .jar:
  1. Нажмите Win + R, введите cmd и запустите командную строку.
  2. Перейдите в директорию, где находятся файлы .java. Например, C:\Users\user\Desktop.
  3. Введите команду javac -d ./build *.java. В папке build появятся несколько файлов .class.
  4. Перейдите в директорию build командой cd build и создайте .jar файл командой jar cvf test.jar *.
  5. Откройте созданный .jar файл через WinRAR, перейдите в папку META-INF и откройте файл MANIFEST.MF.
  6. Вставьте в самом низу 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.
1725543814358.png
значит шифрование прошло успешно.

Загрузка и расшифровка класса
Теперь напишем загрузчик классов, который будет расшифровывать и загружать наш класс:

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();
        }
    }
}
Скомпилируйте и запустите этот загрузчик. Если вы увидите 2 сообщения
Код:
 был загружен 1 class
был загружен 2 class
значит загрузка и расшифровка прошли успешно

Теперь у вас есть базовое понимание работы ClassLoader и пример защиты классов с помощью шифрования. Вы можете доработать этот пример и создать более сложный загрузчик классов.

Upd: поставьте лайк , я старался писать эту тему.
 
Последнее редактирование:
Начинающий
Статус
Оффлайн
Регистрация
8 Май 2023
Сообщения
457
Реакции[?]
5
Поинты[?]
6K
хахаха тоже мне хакер))) класс хуяс ты хоть сам понимаешь че это все значит?)) да не смеши школоло бля)) я в твои годы уже на конвеере стоял а не за компом сидел задрот нах :tearsofjoy: :tearsofjoy: ну ты внатуре хуйней какой то занимаешься)) ну лан покеда
я учу java и просто написал свою защиту, а то что вы пишете это обидно братиш
 
че
Пользователь
Статус
Оффлайн
Регистрация
27 Фев 2021
Сообщения
505
Реакции[?]
67
Поинты[?]
25K
Последнее редактирование:
Начинающий
Статус
Оффлайн
Регистрация
4 Дек 2021
Сообщения
132
Реакции[?]
6
Поинты[?]
3K
Я бы хотел рассказать принцип работы classloader. С помощью него можно делать защиту для паст. Для начала надо понять, что такое classloader.

ClassLoader в Java — это часть Java Runtime Environment (JRE), которая загружает классы Java в память при их первом использовании. В Java классы не встроены напрямую в исполняемый код; они загружаются по мере необходимости.

Давайте для начала создадим файл, который мы будем защищать. У меня это HelloWorld.

HelloWorld:
class HelloWorld {
   public static void main(String[] var0) {
      System.out.println("Hello World!");
   }
}
Что бы его скомпилировать нажимаем win + r, пишем cmd и запускаем. Дальше нам надо открыть путь где вы создавали HelloWorld.java. У меня это "C:\Users\user\Desktop". Прописываем javac HelloWorld.java, и у нас на рабочем столе появляется HelloWorld.class. Давайте же напишем ClassEncrypter

SimpleClassEncryptor:
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.nio.file.Files;
import java.security.NoSuchAlgorithmException;

public class SimpleClassEncryptor {
    public static void main(String[] args) {
        // Путь к файлу класса
        File inFile = new File("C:/Users/user/Desktop/HelloWorld.class"); не 
        // Путь куда сохранять зашифрованный класс
        File outFile = new File("C:/Users/user/Desktop/HelloWorld.class.enc");
        try {
            // Создание ключа шифрования
            KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
            keyGenerator.init(128); // используем 128 битный AES ключ
            SecretKey secretKey = keyGenerator.generateKey();
            // Сохранить ключ в файл, потребуется для расшифровки
            Files.write(new File("C:/Users/user/Desktop/classkey").toPath(), secretKey.getEncoded());
            // Шифратор
            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();
            System.out.println("Encryption of class completed.");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
Дальше компилируем, как раннее и запускаем через java SimpleClassEncryptor. И если у вас написало "Encryption of class completed.", то это хорошо. Заходя в наш новый HelloWorld видим такую картину:Посмотреть вложение 271596
Давайте напишем загрузчик классов, чтобы его расшифровать и загрузить

CustomClassLoader:
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.io.File;
import java.nio.file.Files;
import java.security.Key;

public class CustomClassLoader extends ClassLoader {

    private final String keyPath;

    public CustomClassLoader(ClassLoader parent, String keyPath) {
        super(parent);
        this.keyPath = keyPath;
    }

    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {
        try {
            File encryptedClassFile = new File("C:/Users/user/Desktop/" + name + ".class.enc");
            // Чтение зашифрованного файла класса
            byte[] encryptedClassBytes = Files.readAllBytes(encryptedClassFile.toPath());

            // Чтение ключа из файла
            byte[] keyBytes = Files.readAllBytes(new File(keyPath).toPath());
            Key key = new SecretKeySpec(keyBytes, "AES");

            // Дешифратор
            Cipher cipher = Cipher.getInstance("AES");
            cipher.init(Cipher.DECRYPT_MODE, key);

            // Расшифровка класса
            byte[] decryptedClassBytes = cipher.doFinal(encryptedClassBytes);

            // Определение класса в рантайме
            return defineClass(name, decryptedClassBytes, 0, decryptedClassBytes.length);

        } catch (Exception e) {
            throw new ClassNotFoundException("Could not load class " + name, e);
        }
    }

    public static void main(String[] args) {
        CustomClassLoader classLoader = new CustomClassLoader(ClassLoader.getSystemClassLoader(), "C:/Users/user/Desktop/classkey");
        try {
            Class<?> helloWorldClass = classLoader.findClass("HelloWorld");
            System.out.println("Loaded class: " + helloWorldClass.getName());
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}
Ура, мы всё сделали, теперь можем компилировать и запускать classloader. Если у вас высветилось, что class загружен, то это работает. Можете это доработать, и может получится классный loader.

Upd: поставьте лайк или попкорн, я старался писать эту тему.
Прикольно, но я слишком тупой пастер что бы понять как закриптить джарку
Типо мне с софта надо каждый класс файл доставать и про кидывать через этот метод или можно просто вместо File inFile = new File("C:/Users/user/Desktop/HelloWorld.class"); написать File inFile = new File("C:/Users/user/Desktop/Client.jar"); ?
 
Начинающий
Статус
Оффлайн
Регистрация
8 Май 2023
Сообщения
457
Реакции[?]
5
Поинты[?]
6K
Прикольно, но я слишком тупой пастер что бы понять как закриптить джарку
Типо мне с софта надо каждый класс файл доставать и про кидывать через этот метод или можно просто вместо File inFile = new File("C:/Users/user/Desktop/HelloWorld.class"); написать File inFile = new File("C:/Users/user/Desktop/Client.jar"); ?
Ну я написал, что это принцип работы

Upd: я могу потом попробовать переписать что бы с запуском и не отдельно файл каждый через энкриптер прогонять
 
Начинающий
Статус
Оффлайн
Регистрация
4 Дек 2021
Сообщения
132
Реакции[?]
6
Поинты[?]
3K
Ну я написал, что это принцип работы

Upd: я могу потом попробовать переписать что бы с запуском и не отдельно файл каждый через энкриптер прогонять
гоу
 
Пользователь
Статус
Оффлайн
Регистрация
25 Окт 2023
Сообщения
76
Реакции[?]
28
Поинты[?]
25K
ППХУДЕР
Начинающий
Статус
Оффлайн
Регистрация
10 Фев 2020
Сообщения
431
Реакции[?]
24
Поинты[?]
6K
Принцип работы, это словосочетание тебе что-то говорит?
название темы «как защитить», это абсолютно бесполезная защита, сейчас даже от пастеров не спасет
 
Забаненный
Статус
Оффлайн
Регистрация
2 Фев 2024
Сообщения
849
Реакции[?]
7
Поинты[?]
4K
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Сверху Снизу