-
Автор темы
- #1
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Всем привет!
Сегодня мы продолжим написание дерьмо защиты, и мы добавим крипту в нашу джаву. Если вы еще не читали прошлую часть то прочитайте.
1*. Для начала мы найдем метод ClassFileParser.cpp и зайдем в метод parse_constant_pool_entries и далее найдем JVM_CONSTANT_Utf8 далее мы увидем utf8_buffer нам нужно его изменить на u1* utf8_buffer = const_cast<u1*>(cfs->current()); далее после строки cfs->skip_u1_fast(utf8_length); мы пишем
но у вас нету метода custom. Сейчас мы его сделаем заходим в класс classFileStream.hpp и после строки static const bool verify; мы пишем bool custom() const; ошибка должна была пропасть. Но мы не реализовали сам метод поэтому мы переходим уже в ClassFileStream.cpp и пишем
Теперь мы в ClassFileParser.cpp ищем метод parse_stream в нем нам нужно удалить проверку на magic value ибо в будущем мы его будем изменять
2*. Далее мы билдим это дерьмо если вы сделали все правильно то должно заработать. После билда мы открываем intellij idea и создаем новый проект с 18 джавой(НЕ НАШЕЙ). И начинаем писать код Создаем 1 класс Main и туда пишем
Теперь нам нужно написать ClassWriter и ClassStream
Ну и теперь самое страшное ClassParser p.s я убил на эту залупу дохуя времени
Теперь мы находим любую джарку и тестим на ней. Запускаем Если вы сделали все правильно то у вас не будет ошибок и будет в консоле что то по типу
Processing Main.class
Сразу скажу тут будут ваши классы у меня 1 класс далее мы тестим наше дерьмо с помощью кастомной джавы поидее все должно запускаться без проблем если будут какие то ошибки проблемы (не тупые пишите в дс sertyo1337)
Сегодня мы продолжим написание дерьмо защиты, и мы добавим крипту в нашу джаву. Если вы еще не читали прошлую часть то прочитайте.
1*. Для начала мы найдем метод ClassFileParser.cpp и зайдем в метод parse_constant_pool_entries и далее найдем JVM_CONSTANT_Utf8 далее мы увидем utf8_buffer нам нужно его изменить на u1* utf8_buffer = const_cast<u1*>(cfs->current()); далее после строки cfs->skip_u1_fast(utf8_length); мы пишем
code:
if (cfs->custom()) {
for (int i = 0; i < utf8_length; i++) {
utf8_buffer[i] -= 5;
}
}
method:
bool ClassFileStream::custom() const {
return buffer()[0] != 0xCA && buffer()[1] != 0xFE && buffer()[2] != 0xBA && buffer()[4] != 0xBE;
}
delete:
guarantee_property(magic == JAVA_CLASSFILE_MAGIC,
"Incompatible magic value %u in class file %s",
magic, CHECK);
Main:
package omg.sertyo;
import java.io.FileOutputStream;
import java.io.IOException;
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("input.jar");
zip.entries().asIterator().forEachRemaining((entry) -> {
try {
files.put(entry.getName(), zip.getInputStream(entry).readAllBytes());
} catch (IOException e) {
throw new RuntimeException(e);
}
});
zip.close();
files.forEach((name, data) -> {
if (isClassFileFormat(name, data)) {
ClassWriter classWriter = new ClassWriter();
ClassParser classFile = new ClassParser(new ClassStream(data), classWriter);
System.out.println("Processing " + name);
classFile.parse_stream();
byte[] buffer = classWriter.getByteArrayOutputStream().toByteArray();
files.put(name, buffer);
}
});
ZipOutputStream zos = new ZipOutputStream(new FileOutputStream("output.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");
}
}
ClassWriter:
package omg.sertyo;
import lombok.SneakyThrows;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.nio.charset.StandardCharsets;
public final class ClassWriter
{
private final ByteArrayOutputStream stream;
private final DataOutputStream writer;
public ClassWriter() {
this.stream = new ByteArrayOutputStream();
this.writer = new DataOutputStream(stream);
}
@SneakyThrows
public void writeByte(final int b) {
this.writer.write(b);
}
@SneakyThrows
public void writeTag(int b) {
this.writer.writeByte(b);
}
@SneakyThrows
public void writeShort(final int v) {
this.writer.writeShort(v);
}
@SneakyThrows
public void write(final int v) {
this.writer.writeInt(v);
}
@SneakyThrows
public void write(final long v) {
this.writer.writeLong(v);
}
@SneakyThrows
public void write(final float v) {
this.writer.writeFloat(v);
}
@SneakyThrows
public void write(final double v) {
this.writer.writeDouble(v);
}
@SneakyThrows
public void utf(String string) {
byte[] data = string.getBytes(StandardCharsets.UTF_8);
for (int i = 0; i < data.length; i++) {
data[i] += 5;
}
this.writer.writeShort(data.length);
this.writer.write(data);
}
@SneakyThrows
public void writeclass(ClassWriter classWriter){
writer.write(classWriter.getByteArrayOutputStream().toByteArray());
}
@SneakyThrows
public void writebytes(byte[] bytes) {
writer.write(bytes);
}
public ByteArrayOutputStream getByteArrayOutputStream() {
return this.stream;
}
}
ClassStream:
package omg.sertyo;
import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
public class ClassStream {
private final DataInputStream reader;
public ClassStream(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;
}
}
ClassParser:
package omg.sertyo;
import lombok.SneakyThrows;
public class ClassParser {
private final ClassStream classStream;
private final ClassWriter classWriter;
public ClassParser(ClassStream classStream, final ClassWriter classWriter) {
this.classStream = classStream;
this.classWriter = classWriter;
}
int magic;
int magic2;
int magic3;
int magic4;
@SneakyThrows
public void parse_stream() {
//Parse magic
magic = this.classStream.readByte();
magic2 = this.classStream.readByte();
magic3 = this.classStream.readByte();
magic4 = this.classStream.readByte();
//Set custom
magic = 0xDE;
magic2 = 0xAD;
magic3 = 0xBE;
magic4 = 0xEF;
ClassWriter magicwriter = new ClassWriter();
magicwriter.writeByte(magic);
magicwriter.writeByte(magic2);
magicwriter.writeByte(magic3);
magicwriter.writeByte(magic4);
//Set magic value
classWriter.writeclass(magicwriter);
//minor and major
classWriter.writeShort(classStream.readShort());
classWriter.writeShort(classStream.readShort());
//constant pool
final int conspool = classStream.readShort();
classWriter.writeShort(conspool);
parseConstant(conspool);
//flags
classWriter.writeShort(classStream.readShort());
// class index
classWriter.writeShort(classStream.readShort());
//super class
classWriter.writeShort(classStream.readShort());
//class interface
int interfacesSize = classStream.readShort();
classWriter.writeShort(interfacesSize);
for (int i = 0; i < interfacesSize; i++) {
classWriter.writeShort(classStream.readShort());
}
//others
classWriter.writebytes(classStream.getReader().readAllBytes());
}
@SneakyThrows
void parseConstant(final int length) {
for (int i = 1; i < length; ++i) {
final int consttag = classStream.readByte();
classWriter.writeTag(consttag);
switch (consttag) {
case 7: // JVM_CONSTANT_Class
classWriter.writeShort(classStream.readShort());
break;
case 8: // JVM_CONSTANT_String
classWriter.writeShort(classStream.readShort());
break;
case 9: // JVM_CONSTANT_Fieldref
final int shortfield = classStream.readShort();
final int shortfield2 = classStream.readShort();
classWriter.writeShort(shortfield);
classWriter.writeShort(shortfield2);
break;
case 11: // JVM_CONSTANT_InterfaceMethodref
final int shortinterface = classStream.readShort();
final int shortinterface2 = classStream.readShort();
classWriter.writeShort(shortinterface);
classWriter.writeShort(shortinterface2);
break;
case 10: // JVM_CONSTANT_Methodref
final int shortmethod = classStream.readShort();
final int shortmethod2 = classStream.readShort();
classWriter.writeShort(shortmethod);
classWriter.writeShort(shortmethod2);
break;
case 12: // JVM_CONSTANT_NameAndType
final int shortname = classStream.readShort();
final int shortname2 = classStream.readShort();
classWriter.writeShort(shortname);
classWriter.writeShort(shortname2);
break;
case 15: // JVM_CONSTANT_MethodHandle
final int bytemethod = classStream.readByte();
final int shortmethodhanle = classStream.readShort();
classWriter.writeByte(bytemethod);
classWriter.writeShort(shortmethodhanle);
break;
case 16: // JVM_CONSTANT_MethodType
classWriter.writeShort(classStream.readShort());
break;
case 17: // JVM_CONSTANT_Dynamic
final int shortdynamic = classStream.readShort();
final int shortdynamic2 = classStream.readShort();
classWriter.writeShort(shortdynamic);
classWriter.writeShort(shortdynamic2);
break;
case 18: // JVM_CONSTANT_InvokeDynamic
final int shortinvoke = classStream.readShort();
final int shortinvoke2 = classStream.readShort();
classWriter.writeShort(shortinvoke);
classWriter.writeShort(shortinvoke2);
break;
case 3: // JVM_CONSTANT_Integer
classWriter.write(classStream.readInt());
break;
case 4: // JVM_CONSTANT_Float
classWriter.write(classStream.readFloat());
break;
case 5: // JVM_CONSTANT_Long
classWriter.write(classStream.readLong());
++i; // Long занимает два индекса
break;
case 6: // JVM_CONSTANT_Double
classWriter.write(classStream.readDouble());
++i; // Double занимает два индекса
break;
case 1: // JVM_CONSTANT_Utf8
String[] utf = new String[length];
String readUTF = classStream.readUTF();
utf[i] = readUTF;
classWriter.utf(readUTF);
break;
case 19: // JVM_CONSTANT_Module
classWriter.writeShort(classStream.readShort());
break;
case 20: // JVM_CONSTANT_Package
classWriter.writeShort(classStream.readShort());
break;
default:
System.out.println("Unknown constant pool tag: " + consttag);
}
}
}
}
Processing Main.class
Сразу скажу тут будут ваши классы у меня 1 класс далее мы тестим наше дерьмо с помощью кастомной джавы поидее все должно запускаться без проблем если будут какие то ошибки проблемы (не тупые пишите в дс sertyo1337)