|
ЗАЩИТА JAVA-АППЛЕТОВ Андрей Каролик Xakep, номер #053, стр. 053-066-4 СТАВИМ ЗАЩИТУ Запускается KlassMaster с помощью команды java -Xmx256m -jar ZKM.jar. Далее согласно подсказкам пошагового помощника. Общая последовательность действий такова: - открывается незащищенный байт-код (File -> Open) - из кода выметается лишний мусор (Tools -> Trim) - делается обфускация с выбранными параметрами (Tools -> Obfuscate) - результат сохраняется (File -> Save all) Выставляй оба параметра обфускации в aggressive, и поехали. В результате получилось два класса: a.class и b.class (вместо Fade.class и Thoughts.class). До обфускации их размер был 4,9 Кб и 4,1 Кб, теперь они весят 3,6 Кб и 3,0 Кб соответственно. Оптимизация налицо. Осталось посмотреть, что KlassMaster натворил внутри. Для этого запускай NMI's Java Code Viewer, открывай полученные классы и через меню выбери Process -> Decompile. Чтобы было с чем сравнивать, аналогично декомпилируй и исходные классы (Fade.class и Thoughts.class). ПОСЛЕ ДЕКОМПИЛЯЦИИ Разница между тем, что было, и тем, что стало, видна невооруженным глазом. Все имена классов, методов и переменных заменены однобуквенными символами. Литералы и строковые переменные зашифрованы. Появилось множество левых меток и не менее левых переходов на них. Если описывать в двух словах, то получилась настоящая каша. И самое главное - при запуске апплет работает без сбоев. Привожу наиболее интересную часть полученного кода a.class после декомпиляции Fade.class: // Processed by NMI's Java Code Viewer 5.0 (c) 1997-2001 B. Lemaire // Source File Name: a.java <- skipped -> public boolean mouseEnter(Event event, int i, int j) { showStatus(b("p7\007\b\031\\7\025\f\027T/C*^C%\006\035GSv$\bYX7\021\002")); return true; } public void run() { while(b != null) { int i = a.e(); repaint(); try { a = this; Thread.sleep(25 * i); } catch(InterruptedException interruptedexception) { } } } public String getAppletInfo() { return b("p7\007\b\027T/C*^C%\006\035GSv$\bYX7\021\002"); } public void a(a a1) { boolean flag = false; for(int i = 1; !flag; i++) { String s = String.valueOf(i); String s1 = b("P9\r\031").concat(String.valueOf(String.valueOf(s))); String s3 = b("B3\033\031").concat(String.valueOf(String.valueOf(s))); String s4 = b("C$\017").concat(String.valueOf(String.valueOf(s))); String s5 = super.getParameter(s1); String s2; <- skipped -> _L49: i += 15; if(j == 0) goto _L30; else goto _L50 _L50: i + Integer.valueOf(s.substring(1)).intValue(); _L48: i; _L30: i; if(c) b.v = ++j; return; } private static String b(String s) { char ac[]; int i; int j; ac = s.toCharArray(); i = ac.length; |