Гайд Гайд как сделать более менее нормальную крипту

  • Автор темы Автор темы dayzsk
  • Дата начала Дата начала
Начинающий
Начинающий
Статус
Оффлайн
Регистрация
5 Мар 2025
Сообщения
142
Реакции
1
Всем привет! В данном посте я солью крипту (почти полностью переписана от сертио)

добавлено:
constantPool
xor key
read method (classWriter)
minimal fix main

main:
Java:
Expand Collapse Copy
package proguard.crypta;

import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.concurrent.ConcurrentHashMap;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;

public class Main {

    private static final ConcurrentHashMap<String, byte[]> files = new ConcurrentHashMap<>();

    public static void main(String[] args) throws IOException {
        ZipFile zip = new ZipFile("C:\\Users\\youki\\OneDrive\\Рабочий стол\\Новая папка (2)\\a.jar");
        Enumeration<? extends ZipEntry> entries = zip.entries();
        while (entries.hasMoreElements()) {
            ZipEntry entry = entries.nextElement();
            try {
                files.put(entry.getName(), readAllBytes(zip.getInputStream(entry)));
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        zip.close();

        files.forEach((name, data) -> {
            if (isClassFileFormat(name, data)) {
                ClassFileWriter classWriter = new ClassFileWriter(data);
                ClassFile classFile = null;
                try {
                    classFile = new ClassFile(new ClassFileStream(data), classWriter);
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
                System.out.println("Processing " + name);

                try {
                    classFile.parse_class();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }

                byte[] buffer = classWriter.getByteArrayOutputStream().toByteArray();
                files.put(name, buffer);
            }
        });

        ZipOutputStream zos = new ZipOutputStream(new FileOutputStream("C:\\Users\\youki\\OneDrive\\Рабочий стол\\Новая папка (2)\\u.jar"));
        zos.setLevel(9);
        files.forEach((name, data) -> {
            try {
                zos.putNextEntry(new ZipEntry(name));
                zos.write(data);
                zos.closeEntry();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        });

        zos.close();
    }

    private static boolean isClassFileFormat(String name, byte[] data) {
        return data.length >= 8 && name.endsWith(".class");
    }

    private static byte[] readAllBytes(InputStream inputStream) throws IOException {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int bytesRead;
        while ((bytesRead = inputStream.read(buffer)) != -1) {
            baos.write(buffer, 0, bytesRead);
        }
        inputStream.close();
        return baos.toByteArray();
    }
}

classFileParser:

Java:
Expand Collapse Copy
package proguard.crypta;

import proguard.crypta.data.ConsPool;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Map;

import static proguard.crypta.data.ConsPool.*;

public class ClassFile {
    private ConsPool consPool;
    private Map<Integer, Object> pool;
    private ClassFileStream classStream;
    private final ClassFileWriter classWriter;
    private int superClass;
    private int flag;
    private int thisFileIndex;

    public ClassFile(ClassFileStream classStream, final ClassFileWriter classWriter) throws IOException {
        this.classStream = classStream;
        this.classWriter = classWriter;
    }

    int magic;

    public void parse_class() throws IOException {
        magic = classStream.readInt();
        System.out.println("Magic number: 0x" + Integer.toHexString(magic).toUpperCase());
        int minor = classStream.readShort();
        System.out.println("Minor version: " + minor);
        int major = classStream.readShort();
        System.out.println("Major version: " + major);

        classWriter.write(magic);
        classWriter.writeShort(minor);
        classWriter.writeShort(major);

        if (magic != JAVA_CLASSFILE_MAGIC) {
            throw new RuntimeException("Invalid magic number " + Integer.toHexString(magic).toUpperCase());
        }

        final int conspool = classStream.readUnsignedShort();
        System.out.println("Constant pool count: " + conspool);
        classWriter.writeShort(conspool);
        this.parserConstantPool(conspool);

        this.flag = classStream.readShort();
        this.thisFileIndex = classStream.readUnsignedShort();
        this.superClass = classStream.readShort();

        System.out.println("Access flags: " + flag);
        System.out.println("This class index: " + thisFileIndex);
        System.out.println("Super class index: " + superClass);

        classWriter.writeShort(this.flag);
        classWriter.writeShort(this.thisFileIndex);
        classWriter.writeShort(this.superClass);

        this.parser_interface();
        this.parser_fields();
        this.parser_method();
        this.parse_class_file_attribute();
    }

    private void parserConstantPool(final int length) throws IOException {
        for (int i = 1; i < length; ++i) {
            final int consttag = classStream.readByte();
            System.out.println("Tag at index " + i + ": " + consttag);
            classWriter.writeTag(consttag);

            switch (consttag) {
                case JVM_CONSTANT_Class:
                case JVM_CONSTANT_String:
                case JVM_CONSTANT_Module:
                case JVM_CONSTANT_Package:
                case JVM_CONSTANT_MethodType:
                    classWriter.writeShort(classStream.readShort());
                    break;
                case JVM_CONSTANT_Fieldref:
                case JVM_CONSTANT_Methodref:
                case JVM_CONSTANT_InterfaceMethodref:
                case JVM_CONSTANT_Dynamic:
                case JVM_CONSTANT_InvokeDynamic:
                case JVM_CONSTANT_NameAndType:
                    classWriter.writeShort(classStream.readShort());
                    classWriter.writeShort(classStream.readShort());
                    break;
                case JVM_CONSTANT_MethodHandle:
                    classWriter.writeByte(classStream.readByte());
                    classWriter.writeShort(classStream.readShort());
                    break;
                case JVM_CONSTANT_Integer:
                    classWriter.write(classStream.readInt());
                    break;
                case JVM_CONSTANT_Float:
                    classWriter.write(classStream.readFloat());
                    break;
                case JVM_CONSTANT_Long:
                    classWriter.write(classStream.readLong());
                    ++i;
                    break;
                case JVM_CONSTANT_Double:
                    classWriter.write(classStream.readDouble());
                    ++i;
                    break;
                case JVM_CONSTANT_Utf8:
                    try {
                        String readUTF = classStream.readUTF();
                        System.out.println("UTF-8 at index " + i + ": " + readUTF);
                        utf(readUTF);
                    } catch (IOException e) {
                        System.err.println("Failed to read UTF-8 at index " + i + ": " + e.getMessage());
                        throw e;
                    }
                    break;
                default:
                    classStream.skip(1);
                    classWriter.writeByte(0);
            }
        }
    }

    private void parser_interface() throws IOException {
        int interfacesCount = classStream.readUnsignedShort();
        classWriter.writeShort(interfacesCount);

        for (int i = 0; i < interfacesCount; i++) {
            int interfaceIndex = classStream.readUnsignedShort();
            classWriter.writeShort(interfaceIndex);
        }
    }

    private void parser_fields() throws IOException {
        int fieldsCount = classStream.readUnsignedShort();
        classWriter.writeShort(fieldsCount);

        for (int i = 0; i < fieldsCount; i++) {
            int accessFlags = classStream.readUnsignedShort();
            int nameIndex = classStream.readUnsignedShort();
            int descriptorIndex = classStream.readUnsignedShort();
            int attributesCount = classStream.readUnsignedShort();

            classWriter.writeShort(accessFlags);
            classWriter.writeShort(nameIndex);
            classWriter.writeShort(descriptorIndex);
            classWriter.writeShort(attributesCount);

            for (int j = 0; j < attributesCount; j++) {
                int attributeNameIndex = classStream.readUnsignedShort();
                int attributeLength = classStream.readInt();
                byte[] attributeData = classStream.read(attributeLength);

                classWriter.writeShort(attributeNameIndex);
                classWriter.write(attributeLength);
                classWriter.writebytes(attributeData);
            }
        }
    }

    private void parser_method() throws IOException {
        int methodsCount = classStream.readUnsignedShort();
        classWriter.writeShort(methodsCount);

        for (int i = 0; i < methodsCount; i++) {
            int accessFlags = classStream.readUnsignedShort();
            int nameIndex = classStream.readUnsignedShort();
            int descriptorIndex = classStream.readUnsignedShort();
            int attributesCount = classStream.readUnsignedShort();

            classWriter.writeShort(accessFlags);
            classWriter.writeShort(nameIndex);
            classWriter.writeShort(descriptorIndex);
            classWriter.writeShort(attributesCount);

            for (int j = 0; j < attributesCount; j++) {
                int attributeNameIndex = classStream.readUnsignedShort();
                int attributeLength = classStream.readInt();
                byte[] attributeData = classStream.read(attributeLength);

                classWriter.writeShort(attributeNameIndex);
                classWriter.write(attributeLength);
                classWriter.writebytes(attributeData);
            }
        }
    }

    private void parse_class_file_attribute() throws IOException {
        int attributesCount = classStream.readUnsignedShort();
        classWriter.writeShort(attributesCount);

        for (int i = 0; i < attributesCount; i++) {
            int attributeNameIndex = classStream.readUnsignedShort();
            int attributeLength = classStream.readInt();
            byte[] attributeData = classStream.read(attributeLength);

            classWriter.writeShort(attributeNameIndex);
            classWriter.write(attributeLength);
            classWriter.writebytes(attributeData);
        }
    }

    public String getUtf8(int index) {
        Object value = pool.get(index);
        if (value instanceof String) {
            return ((String) value);
        }
        throw new IllegalArgumentException("No UTF-8 string at index " + index);
    }


    public void utf(String string) throws IOException {
        byte[] data = string.getBytes(StandardCharsets.UTF_8);
        String zovKey = "zov 1337";
        byte[] bytes = zovKey.getBytes();
        int key1 = 0x05;
        int key2 = 0x39;
        int obfuscator = 0xAB;

        magic = (bytes[0] ^ key1) ^ obfuscator;

        if ((magic) == 0) {
            System.out.println("Magic numbers corrupted!");
            throw new SecurityException("Tampering detected");
        }
        for (int i = 0; i < data.length; i++) {
            data[i] += 5 ^ bytes.length;
        }

        this.classWriter.writeShort(data.length);
        this.classWriter.writebytes(data);
    }


}

classStream:
Java:
Expand Collapse Copy
package proguard.crypta;

import java.io.*;
import java.nio.charset.StandardCharsets;

public class ClassFileStream {
    private  ByteArrayOutputStream stream;
    private DataOutputStream writer;
    private  byte[] inputData; // Store the original input data
    private ByteArrayInputStream inputStream;
    private DataInputStream reader;

    public ClassFileStream(byte[] buf) {
        this.reader = new DataInputStream(new ByteArrayInputStream(buf));
    }

    public int readByte() throws IOException {
        return reader.read();
    }

    public int readShort() throws IOException {
        return this.reader.readShort();
    }

    public int readInt() throws IOException {
        return this.reader.readInt();
    }

    public long readLong() throws IOException {
        return this.reader.readLong();
    }

    public float readFloat() throws IOException {
        return this.reader.readFloat();
    }

    public double readDouble() throws IOException {
        return this.reader.readDouble();
    }

    public String readUTF() throws IOException {
        final byte[] array = new byte[this.reader.readUnsignedShort()];
        this.reader.readFully(array);
        return new String(array, StandardCharsets.UTF_8);
    }

    public DataInputStream getReader() {
        return reader;
    }

    public int available() throws IOException {
        return reader.available();
    }

    // Чтение заданного количества байтов в массив
    public void readFully(byte[] buffer) throws IOException {
        reader.readFully(buffer);
    }

    public void initializeConstantPool(final int init) throws IOException {
        reader.read();
    }

    public void writeByte(final int b) throws IOException {
        this.writer.write(b);
    }

    public void writeTag(int b) throws IOException {
        this.writer.writeByte(b);
    }

    public void writeShort(final int v) throws IOException {
        this.writer.writeShort(v);
    }



    public int readUnsignedShort() throws IOException {
        return reader.readUnsignedShort();
    }

    public void write(final int v) throws IOException {
        this.writer.writeInt(v);
    }

    public void write(final long v) throws IOException {
        this.writer.writeLong(v);
    }

    public void write(final float v) throws IOException {
        this.writer.writeFloat(v);
    }

    public void write(final double v) throws IOException {
        this.writer.writeDouble(v);
    }

    public void utf(String string) throws IOException {
        byte[] data = string.getBytes(StandardCharsets.UTF_8);
        int xor_key = 0x78D;

        for (int i = 0; i < data.length; i++) {
            data[i] += 5;
        }

        this.writer.writeShort(data.length);
        this.writer.write(data);
    }

    public void writeclass(ClassFileWriter classWriter) throws IOException {
        writer.write(classWriter.getByteArrayOutputStream().toByteArray());
    }

    public void writebytes(byte[] bytes) throws IOException {
        writer.write(bytes);
    }

    public void writebytes(byte[] bytes, int i, int is) throws IOException {
        writer.write(bytes, i, is);
    }

    public ByteArrayOutputStream getByteArrayOutputStream() {
        return this.stream;
    }

    public void skip(int n) throws IOException {
        reader.skip(n);
    }

    public byte[] read(int length) throws IOException {
        byte[] bytes = new byte[length];
        reader.read(bytes);
        return bytes;
    }

}

classWriteFile:

Java:
Expand Collapse Copy
package proguard.crypta;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;

public class ClassFileWriter {
    private final ByteArrayOutputStream stream;
    private final DataOutputStream writer;
    private final byte[] inputData; // Store the original input data
    private ByteArrayInputStream inputStream;
    private DataInputStream reader;

    public ClassFileWriter(byte[] inputData) {
        this.stream = new ByteArrayOutputStream();
        this.writer = new DataOutputStream(stream);
        this.inputData = inputData; // Initialize with input data
        this.inputStream = new ByteArrayInputStream(inputData);
        this.reader = new DataInputStream(inputStream);
    }

    public void writeByte(final int b) throws IOException {
        this.writer.write(b);
    }

    public void writeTag(int b) throws IOException {
        this.writer.writeByte(b);
    }

    public void writeShort(final int v) throws IOException {
        this.writer.writeShort(v);
    }

    public int readShort() throws IOException {
        return reader.readShort();
    }

    public int readInt() throws IOException {
        return reader.readInt();
    }

    public int readUnsignedShort() throws IOException {
        return reader.readUnsignedShort();
    }

    public void write(final int v) throws IOException {
        this.writer.writeInt(v);
    }

    public void write(final long v) throws IOException {
        this.writer.writeLong(v);
    }

    public void write(final float v) throws IOException {
        this.writer.writeFloat(v);
    }

    public void write(final double v) throws IOException {
        this.writer.writeDouble(v);
    }


    public void writeclass(ClassFileWriter classWriter) throws IOException {
        writer.write(classWriter.getByteArrayOutputStream().toByteArray());
    }

    public void writebytes(byte[] bytes) throws IOException {
        writer.write(bytes);
    }

    public void writebytes(byte[] bytes, int i, int is) throws IOException {
        writer.write(bytes, i, is);
    }

    public ByteArrayOutputStream getByteArrayOutputStream() {
        return this.stream;
    }

    public void skip(int n) throws IOException {
        reader.skip(n);
    }

    public byte[] read(int length) throws IOException {
        byte[] bytes = new byte[length];
        reader.read(bytes);
        return bytes;
    }



    public float readFloat() throws IOException {
        return reader.readFloat();
    }

    public double readDouble() throws IOException {
        return reader.readDouble();
    }

    public long readLong() throws IOException {
        return reader.readLong();
    }
}

прошу не пинать, как по мне это сильно улучшеная тема от сертио
 
оно защищает хоть немного, а не дамп одной длл (ik dumper сможет, не вижу прям настолько расплоднять защиты), я пробовал тот же xor без знания ключа сняли за час, и это уже не 5 мин как ориг сертио
 
оно защищает хоть немного, а не дамп одной длл (ik dumper сможет, не вижу прям настолько расплоднять защиты), я пробовал тот же xor без знания ключа сняли за час, и это уже не 5 мин как ориг сертио
Скинь Jar с этой защитой
 
оно защищает хоть немного, а не дамп одной длл (ik dumper сможет, не вижу прям настолько расплоднять защиты), я пробовал тот же xor без знания ключа сняли за час, и это уже не 5 мин как ориг сертио
разберешь мою? ds: regullar
 
оно защищает хоть немного, а не дамп одной длл (ik dumper сможет, не вижу прям настолько расплоднять защиты), я пробовал тот же xor без знания ключа сняли за час, и это уже не 5 мин как ориг сертио
Ничего что сделало бы твой класс прям вау тут нет, так же как и сертио снимается на 5 минут

А ну и да, ты б югеймовским хоть часть плюсов дал, они ж сами парсер не допишут
 
Назад
Сверху Снизу