Подписывайтесь на наш Telegram и не пропускайте важные новости! Перейти

Вопрос Защита Java кода

Начинающий
Начинающий
Статус
Оффлайн
Регистрация
10 Фев 2024
Сообщения
23
Реакции
0
Хочу узнать какие техники юзают что бы адекватно защитить java код, как именно и куда пихают авторизацию и как именно ее реализуют (булеан как будто хуйня, не?), типо нативку и тд все это знаю, но это как будто анти пастер протект и не более, не прям сильно шарю но изучить тему хочу, особенно интересно про загрузку классов и авторизацию
 
Хочу узнать какие техники юзают что бы адекватно защитить java код, как именно и куда пихают авторизацию и как именно ее реализуют (булеан как будто хуйня, не?), типо нативку и тд все это знаю, но это как будто анти пастер протект и не более, не прям сильно шарю но изучить тему хочу, особенно интересно про загрузку классов и авторизацию
Класс-файл парсер (ClassFileParser)
Суть: Чтобы усложнить анализ твоего говна .jar/.class.
Изменить структуру .class-файлов (например, поменять порядок констант в пуле).
Добавить мусорные байты, чтобы декомпиляторы (например, CFR, FernFlower) ломались.

Пример как поднасрать пастерам:

Java:

<span>// Вместо нормального класса:</span><br><span>public</span> <span>class</span> <span>Main</span> <span>{</span><br> <span>public</span> <span>static</span> <span>void</span> <span>enable</span><span>(</span><span>)</span> <span>{</span> <span>.</span><span>.</span><span>.</span> <span>}</span><br><span>}</span><br><br><span>// Создаёшь битый class-файл с лишними байтами:</span><br>CA FE BA BE <span>00</span> <span>00</span> <span>00</span> <span>34</span> ← стандартный заголовок <br><span>00</span> <span>00</span> <span>00</span> FF FF FF FF ← мусорные данные <span>(</span>декомпилятор ломается<span>)</span>

2. Класс-файл стрим (ClassFileStream)
Суть: Чтобы затруднить загрузку всякой хуйни в память JVM (если кто-то попытается проанализировать в runtime).
Шифровать .class-файлы и расшифровывать их только перед загрузкой.
Использовать кастомный ClassLoader, который проверяет хеш перед загрузкой.

Пример:
Java:

<span>public</span> <span>class</span> <span>CustomClassLoader</span> <span>extends</span> <span>ClassLoader</span> <span>{</span><br> <span>@Override</span><br> <span>protected</span> <span>Class</span><span><span>&lt;</span><span>?</span><span>&gt;</span></span> <span>findClass</span><span>(</span><span>String</span> name<span>)</span> <span>{</span><br> <span>byte</span><span>[</span><span>]</span> encrypted <span>=</span> <span>loadEncryptedClass</span><span>(</span>name<span>)</span><span>;</span><br> <span>byte</span><span>[</span><span>]</span> decrypted <span>=</span> <span>decrypt</span><span>(</span>encrypted<span>,</span> SECRET_KEY<span>)</span><span>;</span><br> <span>return</span> <span>defineClass</span><span>(</span>name<span>,</span> decrypted<span>,</span> <span>0</span><span>,</span> decrypted<span>.</span>length<span>)</span><span>;</span><br> <span>}</span><br><span>}</span>


3. Вырезать jvmti (JVM Tool Interface)
Чтобы запретить отладку (читеры не смогут подключиться к JVM через jdb, JVMTI или ASM).
Собрать кастомную JVM без поддержки jvmti.dll.
Патчить libjvm.so, чтобы он игнорировал запросы отладчика.

Эффект:

jstack, jmap не смогут получить дампы памяти.

Код сложнее анализировать в runtime.

4. Менять сдвиги таблицы JNI (Java Native Interface)
Суть: Чтобы замести следы нативных вызовов (если твой чит использует JNI).
Перемешать JNIEnv-таблицу (чтобы реверсеры не могли найти CallStaticVoidMethod и т.д.).
Динамически вычислять оффсеты функций (а не страдать хуйней).

Пример:
Java:

<span>// Вместо:</span><br><span>(</span><span>*</span>env<span>)</span><span>-&gt;</span><span>CallStaticVoidMethod</span><span>(</span>env<span>,</span> cls<span>,</span> mid<span>)</span><span>;</span><br><br><span>// Делаешь:</span><br><span>void</span><span>*</span> jniFunc <span>=</span> <span>(</span><span>void</span><span>*</span><span>)</span><span>(</span><span>(</span>uintptr_t<span>)</span>env <span>+</span> RANDOM_OFFSET<span>)</span><span>;</span><br><span>(</span><span>(</span>JNICALL<span>)</span>jniFunc<span>)</span><span>(</span>env<span>,</span> cls<span>,</span> mid<span>)</span><span>;</span> <span>// Обычный пастер не поймет что это вызов.</span>



5. Скриптить константы отдельно
Суть: Чтобы запутать сигнатуры (строки, числа, хеши), которые реверсеры ищут в бинарнике.


Разбивать строки:

Java:

<span>// Вместо:</span><br><span>String</span> key <span>=</span> <span>"SECRET_CHEAT_KEY"</span><span>;</span><br><br><span>// Делаешь:</span><br><span>String</span> key <span>=</span> <span>"SEC"</span> <span>+</span> <span>"RET"</span> <span>+</span> <span>"_CH"</span> <span>+</span> <span>"EAT"</span> <span>+</span> <span>"_KE"</span> <span>+</span> <span>"Y"</span><span>;</span><br>Динамически генерировать важные значения <span>(</span>например<span>,</span> XOR<span>-</span>шифрование строк<span>)</span><span>.</span>


6. Сменить структуру InstanceClass
Суть: Чтобы нассать в памяти и сломать декомпиляторы (например, jd gui).
Патчить HotSpot JVM, чтобы она меняла порядок полей в рантайме.
Добавлять fake-поля в классы.

Эффект:

Dump памяти будет выглядеть как мусор.

Рефлексия (getDeclaredFields) вернёт бессмысленные данные.

7. Нативная защита
Суть: Усложнить реверс (анализировать нативный код сложнее, чем Java).
Скрыть критическую логику (например, критически важных классов чтобы не вьебали как дусю ебаную).
Обфусцировать нативный код (OLLVM, Tigress).

Анти-отладка:

Детект Cheat Engine / x64dbg например по хешу иконок.

8. Крипта (кфс/кфп)

кфс (Key-Flow Crypt)
Суть: Динамическое шифрование кода так, чтобы:
В памяти всегда лежала только расшифрованная часть, которая сейчас выполняется.
Остальное — зашифрованный мусор, который расшифровывается только перед исполнением.

Как делается:

Делим код на куски (например, по методам).
Каждый кусок шифруем AES-256 + свой ключ.
Перед вызовом метода — расшифровываем, выполняем, сразу затираем.

Java:

<span>// Пример псевдокода для кфс</span><br><span>void</span> <span>encryptedMethod</span><span>(</span><span>)</span> <span>{</span><br> <span>byte</span><span>[</span><span>]</span> encryptedCode <span>=</span> <span>loadFromFile</span><span>(</span><span>"method1.enc"</span><span>)</span><span>;</span> <br> <span>byte</span><span>[</span><span>]</span> code <span>=</span> <span>decrypt</span><span>(</span>encryptedCode<span>,</span> dynamicKey<span>)</span><span>;</span> <br> <span>executeInMemory</span><span>(</span>code<span>)</span><span>;</span> <span>// выполнить </span><br> <span>Arrays</span><span>.</span><span>fill</span><span>(</span>code<span>,</span> <span>0</span><span>)</span><span>;</span> <span>// затереть </span><br><span>}</span>

Ключи генерируются в рантайме (например, из хеша системного времени).
Можно зашифровать даже строки (String → byte[] → XOR → мусор в декомпиляторе).

кфп (Key-Flow Packer)
Суть: Упаковка .class-файлов так, чтобы:
Dump памяти был бесполезен.
Декомпиляторы (JD-GUI, FernFlower) падали с ошибками.

Как делается:

Ломаем структуру .class-файла:
Меняем magic bytes (CA FE BA BE → DE AD BE EF).
Добавляем фейковые секции в константный пул.

Динамическая реконструкция:

При загрузке исправляем битый .class в памяти перед передачей в ClassLoader.

Java:

<span>// Пример: подмена magic bytes </span><br><span>byte</span><span>[</span><span>]</span> brokenClass <span>=</span> <span>Files</span><span>.</span><span>readAllBytes</span><span>(</span><span>"Main.class"</span><span>)</span><span>;</span> <br>brokenClass<span>[</span><span>0</span><span>]</span> <span>=</span> <span>0xDE</span><span>;</span> <span>// CA → DE </span><br>brokenClass<span>[</span><span>1</span><span>]</span> <span>=</span> <span>0xAD</span><span>;</span> <span>// FE → AD</span>

CFR и другие декомпиляторы не понимают битые файлы.
Reflection тоже ломается — getDeclaredMethods() вернёт хуйню.

Шифровать .class-файлы (AES + кастомный загрузчик).
Динамическая расшифровка кода перед выполнением.

Если сделать кфс + кфп + нативку, реверсеру проще написать чит с нуля, чем разбирать этот фаршированный пиздец.
 
Класс-файл парсер (ClassFileParser)
Суть: Чтобы усложнить анализ твоего говна .jar/.class.
Изменить структуру .class-файлов (например, поменять порядок констант в пуле).
Добавить мусорные байты, чтобы декомпиляторы (например, CFR, FernFlower) ломались.

Пример как поднасрать пастерам:

Java:

<span>// Вместо нормального класса:</span><br><span>public</span> <span>class</span> <span>Main</span> <span>{</span><br> <span>public</span> <span>static</span> <span>void</span> <span>enable</span><span>(</span><span>)</span> <span>{</span> <span>.</span><span>.</span><span>.</span> <span>}</span><br><span>}</span><br><br><span>// Создаёшь битый class-файл с лишними байтами:</span><br>CA FE BA BE <span>00</span> <span>00</span> <span>00</span> <span>34</span> ← стандартный заголовок <br><span>00</span> <span>00</span> <span>00</span> FF FF FF FF ← мусорные данные <span>(</span>декомпилятор ломается<span>)</span>

2. Класс-файл стрим (ClassFileStream)
Суть: Чтобы затруднить загрузку всякой хуйни в память JVM (если кто-то попытается проанализировать в runtime).
Шифровать .class-файлы и расшифровывать их только перед загрузкой.
Использовать кастомный ClassLoader, который проверяет хеш перед загрузкой.

Пример:
Java:

<span>public</span> <span>class</span> <span>CustomClassLoader</span> <span>extends</span> <span>ClassLoader</span> <span>{</span><br> <span>@Override</span><br> <span>protected</span> <span>Class</span><span><span>&lt;</span><span>?</span><span>&gt;</span></span> <span>findClass</span><span>(</span><span>String</span> name<span>)</span> <span>{</span><br> <span>byte</span><span>[</span><span>]</span> encrypted <span>=</span> <span>loadEncryptedClass</span><span>(</span>name<span>)</span><span>;</span><br> <span>byte</span><span>[</span><span>]</span> decrypted <span>=</span> <span>decrypt</span><span>(</span>encrypted<span>,</span> SECRET_KEY<span>)</span><span>;</span><br> <span>return</span> <span>defineClass</span><span>(</span>name<span>,</span> decrypted<span>,</span> <span>0</span><span>,</span> decrypted<span>.</span>length<span>)</span><span>;</span><br> <span>}</span><br><span>}</span>


3. Вырезать jvmti (JVM Tool Interface)
Чтобы запретить отладку (читеры не смогут подключиться к JVM через jdb, JVMTI или ASM).
Собрать кастомную JVM без поддержки jvmti.dll.
Патчить libjvm.so, чтобы он игнорировал запросы отладчика.

Эффект:

jstack, jmap не смогут получить дампы памяти.

Код сложнее анализировать в runtime.

4. Менять сдвиги таблицы JNI (Java Native Interface)
Суть: Чтобы замести следы нативных вызовов (если твой чит использует JNI).
Перемешать JNIEnv-таблицу (чтобы реверсеры не могли найти CallStaticVoidMethod и т.д.).
Динамически вычислять оффсеты функций (а не страдать хуйней).

Пример:
Java:

<span>// Вместо:</span><br><span>(</span><span>*</span>env<span>)</span><span>-&gt;</span><span>CallStaticVoidMethod</span><span>(</span>env<span>,</span> cls<span>,</span> mid<span>)</span><span>;</span><br><br><span>// Делаешь:</span><br><span>void</span><span>*</span> jniFunc <span>=</span> <span>(</span><span>void</span><span>*</span><span>)</span><span>(</span><span>(</span>uintptr_t<span>)</span>env <span>+</span> RANDOM_OFFSET<span>)</span><span>;</span><br><span>(</span><span>(</span>JNICALL<span>)</span>jniFunc<span>)</span><span>(</span>env<span>,</span> cls<span>,</span> mid<span>)</span><span>;</span> <span>// Обычный пастер не поймет что это вызов.</span>



5. Скриптить константы отдельно
Суть: Чтобы запутать сигнатуры (строки, числа, хеши), которые реверсеры ищут в бинарнике.


Разбивать строки:

Java:

<span>// Вместо:</span><br><span>String</span> key <span>=</span> <span>"SECRET_CHEAT_KEY"</span><span>;</span><br><br><span>// Делаешь:</span><br><span>String</span> key <span>=</span> <span>"SEC"</span> <span>+</span> <span>"RET"</span> <span>+</span> <span>"_CH"</span> <span>+</span> <span>"EAT"</span> <span>+</span> <span>"_KE"</span> <span>+</span> <span>"Y"</span><span>;</span><br>Динамически генерировать важные значения <span>(</span>например<span>,</span> XOR<span>-</span>шифрование строк<span>)</span><span>.</span>


6. Сменить структуру InstanceClass
Суть: Чтобы нассать в памяти и сломать декомпиляторы (например, jd gui).
Патчить HotSpot JVM, чтобы она меняла порядок полей в рантайме.
Добавлять fake-поля в классы.

Эффект:

Dump памяти будет выглядеть как мусор.

Рефлексия (getDeclaredFields) вернёт бессмысленные данные.

7. Нативная защита
Суть: Усложнить реверс (анализировать нативный код сложнее, чем Java).
Скрыть критическую логику (например, критически важных классов чтобы не вьебали как дусю ебаную).
Обфусцировать нативный код (OLLVM, Tigress).

Анти-отладка:

Детект Cheat Engine / x64dbg например по хешу иконок.

8. Крипта (кфс/кфп)

кфс (Key-Flow Crypt)
Суть: Динамическое шифрование кода так, чтобы:
В памяти всегда лежала только расшифрованная часть, которая сейчас выполняется.
Остальное — зашифрованный мусор, который расшифровывается только перед исполнением.

Как делается:

Делим код на куски (например, по методам).
Каждый кусок шифруем AES-256 + свой ключ.
Перед вызовом метода — расшифровываем, выполняем, сразу затираем.

Java:

<span>// Пример псевдокода для кфс</span><br><span>void</span> <span>encryptedMethod</span><span>(</span><span>)</span> <span>{</span><br> <span>byte</span><span>[</span><span>]</span> encryptedCode <span>=</span> <span>loadFromFile</span><span>(</span><span>"method1.enc"</span><span>)</span><span>;</span> <br> <span>byte</span><span>[</span><span>]</span> code <span>=</span> <span>decrypt</span><span>(</span>encryptedCode<span>,</span> dynamicKey<span>)</span><span>;</span> <br> <span>executeInMemory</span><span>(</span>code<span>)</span><span>;</span> <span>// выполнить </span><br> <span>Arrays</span><span>.</span><span>fill</span><span>(</span>code<span>,</span> <span>0</span><span>)</span><span>;</span> <span>// затереть </span><br><span>}</span>

Ключи генерируются в рантайме (например, из хеша системного времени).
Можно зашифровать даже строки (String → byte[] → XOR → мусор в декомпиляторе).

кфп (Key-Flow Packer)
Суть: Упаковка .class-файлов так, чтобы:
Dump памяти был бесполезен.
Декомпиляторы (JD-GUI, FernFlower) падали с ошибками.

Как делается:

Ломаем структуру .class-файла:
Меняем magic bytes (CA FE BA BE → DE AD BE EF).
Добавляем фейковые секции в константный пул.

Динамическая реконструкция:

При загрузке исправляем битый .class в памяти перед передачей в ClassLoader.

Java:

<span>// Пример: подмена magic bytes </span><br><span>byte</span><span>[</span><span>]</span> brokenClass <span>=</span> <span>Files</span><span>.</span><span>readAllBytes</span><span>(</span><span>"Main.class"</span><span>)</span><span>;</span> <br>brokenClass<span>[</span><span>0</span><span>]</span> <span>=</span> <span>0xDE</span><span>;</span> <span>// CA → DE </span><br>brokenClass<span>[</span><span>1</span><span>]</span> <span>=</span> <span>0xAD</span><span>;</span> <span>// FE → AD</span>

CFR и другие декомпиляторы не понимают битые файлы.
Reflection тоже ломается — getDeclaredMethods() вернёт хуйню.

Шифровать .class-файлы (AES + кастомный загрузчик).
Динамическая расшифровка кода перед выполнением.

Если сделать кфс + кфп + нативку, реверсеру проще написать чит с нуля, чем разбирать этот фаршированный пиздец.
Аутентификацию просто в этом пиздец замешать или как ее реализовать лучше?
 
Аутентификацию просто в этом пиздец замешать или как ее реализовать лучше?
Во первых:
Ты сам ответил на свой вопрос отлично

Во вторых:
Тут вопрос стоит, делаешь ли ты свою проту, или надо просто чит заобфить, что бы обходы не спиздили.

Если ты продаешь чит, то не еби мозг и иши нормального протера.

Если ты ради интереса пытаешься чит защитить свой, то если он не бесплатен смысла особого не будет, потому что сдампят скорее всего на раз два.
 
Во первых:
Ты сам ответил на свой вопрос отлично

Во вторых:
Тут вопрос стоит, делаешь ли ты свою проту, или надо просто чит заобфить, что бы обходы не спиздили.

Если ты продаешь чит, то не еби мозг и иши нормального протера.

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