Питання: Якщо я шифрую свої файли .class і використовую користувальницький завантажувач, щоб завантажити та розшифрувати їх під час руху, чи запобіжить це декомпіляція?
Відповідь: Проблема запобігання декомпіляції байт-коду Java майже така ж стара, як і сама мова. Незважаючи на цілий ряд інструментів обфускування, доступних на ринку, початківці програмісти Java продовжують думати про нові та розумні способи захисту своєї інтелектуальної власності. У цьому розкладі Java Q&A я розвіяв деякі міфи навколо ідеї, яка часто переглядалася на дискусійних форумах.
Надзвичайна простота, за допомогою якої файли Java .class можна реконструювати в джерела Java, що дуже нагадують оригінали, має багато спільного з цілями дизайну байт-коду Java та компромісами. Крім усього іншого, байт-код Java був розроблений для компактності, незалежності платформи, мобільності мережі та простоти аналізу за допомогою інтерпретаторів байт-коду та динамічних компіляторів JIT (просто вчасно) / HotSpot. Можливо, складені файли .class виражають наміри програміста настільки чітко, що їх можна було простіше проаналізувати, ніж вихідний вихідний код.
Можна зробити кілька речей, якщо не запобігти декомпіляції повністю, принаймні, щоб зробити це складніше. Наприклад, в якості кроку після компіляції ви можете масажувати дані .class, щоб зробити байт-код важче читати при декомпіляції або важче декомпілювати у дійсний код Java (або в обох). Такі методи, як виконання перевантаженої назви екстремальних методів, добре працюють для перших, а також маніпулювання потоком управління для створення структур управління, які неможливо представити через синтаксис Java, добре працюють для останніх. Більш успішні комерційні окуфатори використовують суміш цих та інших методик.
На жаль, обидва підходи повинні насправді змінити код, який буде запущений JVM, і багато користувачів бояться (справедливо), що це перетворення може додати нових помилок у їхні програми. Крім того, перейменування методу та поля може призвести до припинення роботи роздумних дзвінків. Зміна фактичних назв класів та пакетів може порушити декілька інших API Java (JNDI (інтерфейс імені Java і імені каталогів), провайдерів URL тощо). Крім змінених імен, якщо зв'язок між зміщенням байт-коду класу та номерами вихідних рядків буде змінено, відновлення вихідних слідів стека винятків може стати складним.
Тоді є можливість обмацувати вихідний вихідний код Java. Але принципово це викликає подібний набір проблем. Шифрувати, а не придушувати?
Можливо, вищезгадане змусило вас задуматися: "Ну, що, якщо замість маніпулювання байт-кодом я шифрую всі мої класи після компіляції та розшифровую їх на льоту всередині JVM (що можна зробити за допомогою спеціального завантажувача)? Тоді JVM виконує мій оригінальний код байта, і все ж інженеру не можна декомпілювати чи реверсувати, чи не так? "
На жаль, ви помиляєтеся, як думаючи, що ви вперше придумали цю ідею, так і подумавши, що вона насправді працює. І причина не має нічого спільного з силою вашої схеми шифрування.