Больше месяца назад автор статьи Decrypting Java Malware using ASM прислал мне оригинальный текст на русском языке для публикации в блоге, с целью донести широкому кругу лиц определенные аспекты защиты программ написанных на java от действий недоброжелателей. Автор статьи — разработчик, который долгое время занимается разработкой средств для противодействия реверс-инжирингу и взлому ПО, специалист в области информационной безопасности.
К сожалению, в связи с большой загруженностью (казалось бы лето, все должны быть в отпусках, а нет — работы только привалило), никак не мог заняться блогом и выложить эту статью.
Исправляюсь, надеюсь статья всё еще актуальна.
В настоящее время очень популярны Java Malware, использующие уязвимости в Java. Многие из них для скрытия своих действий используют шифрование строк. Как правило в них могут храниться ключи реестра, команды для запуска различных программ и т.д.
В этой статье мы рассмотрим самый распространенный метод шифрования строк в Java Malware и напишем утилиту для снятия такой защиты.
1) Небольшое введение в формат байткода class-файлов.
Для дальнейшего понимания, необходимо знать следующие вещи - все константы (строки/примитивные типы) хранятся в специальной структуре внути class-файла, которая называется Constant Pool и для получения элемента из Constant Pool используется инструкция ldc.
Посмотрим как выглядит байт код вызова метода System.out.println("HelloWorld");
Пишем простой класс
public class Hello { public static void main(String[] args) throws Exception { System.out.println("HelloWorld"); } } |
Компилируем
javac Hello.java
Декомпилируем с помощью javap
javap -c -v Hello
ConstanPool:
... const #3 = String #20; // HelloWorld const #20 = Asciz HelloWorld; 3: ldc #3; //String HelloWorld 5: invokevirtual #4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V |