Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
инт.среды.docx
Скачиваний:
97
Добавлен:
10.06.2015
Размер:
180.16 Кб
Скачать

5.2.4.7. Усложнители декомпиляции (шифраторы, обфускаторы)

Практические успехи в области декомпиляции языков программирования (и особенно языка Java) оказались столь велики, что в последнее время были проведены значительные исследования в области защиты программ от декомпиляции (http://www.cs.washington.edu/homes/douglas/publish/). Существует специальный класс программ (шифраторов, обфускаторов), усложняющих декомпиляцию. Такие программы используют два основных подхода.

  • Общее (универсальное) усложнение.

  • Целенаправленное усложнение (направленное против конкретного декомпилятора).

Основная идея усложнителей заключается в ухудшении кода. Усложненный код после декомпиляции должен быть непонятен и нечитаем программистом.

5.2.4.8. Системы управления компиляцией и построением программ

Системы управления компиляцией и построением программ в той или иной форме присутствуют во многих инструментальных системах, а также могут использоваться как явные утилиты, работающие с файлами проекта. Фактически эти системы являются генераторами команд, т. е., используя файл описаний, они создают последовательность команд для обработки командным интерпретатором. Примеры таких систем:

  • make (компании Sun Microsystems Inc. (http://www.sun.com/)) входит в состав операционной системы Solaris;

  • GNU Make (организации Free Software Foundations (http://www.gnu.org/software/raake/make.html));

  • Jmk - Make in Java (общинная разработка (http://sourceforge.net/projects/NO).

Основной алгоритм перечисленных систем (далее будем называть их make) таков. На основе совокупности инструкций, согласно которым должна производиться сборка и построение проекта, они проверяют временные метки и, при необходимости, перекомпилируют файл. В результате существенно экономится время сборки проекта.

Файл с инструкциями имеет свой синтаксис.

  • Строка комментариев начинается с символа диез #.

  • Пустые строки игнорируются.

  • Любая строка, оканчивающаяся символом обратная наклонная черта \, продолжается на следующую строку. Все символы пробела и табуляции вокруг наклонной черты сжимаются в один символ пробела.

  • Если строка выглядит следующим образом <цель>: [<зависимости>], то это означает, что цель определяется зависимостями и соответственно для того, чтобы добиться выполнения целей, необходимо выполнить зависимости.

  • Строка, идущая за строкой с указанием цели, должна иметь вид <пробел_или_табуляция> <команда>. Указанная команда будет передана командному интерпретатору в случае, если цель нуждается в обновлении.

  • Команда [<пробел_или_табуляция>] <имя> = <значение> позволяет изменнять значение переменной. Любая строка, содержащая знак равенства, является макроопределением. Такая строка связывает строку <значение> с именем <имя>.

  • Любое слово в файле описаний, начинающееся с символа $, является использованием макроопределения. Включенное в любом месте файла описание $ (<имя>) будет заменено на его существующее макроопределение. Если <имя> является одиночным символом, то разрешено использование макроопределения в упрощенном виде $<имя>.

  • Некоторые макроопределения являются предопределенными. Они могут использоваться только в правой части строки правила, в других макроопределениях и в строках команд. Приведем примеры предопределенных макроопределений:

    • $@ - означает полное имя текущей цели;

    • $* - имя текущей цели с отброшенным типом файла (суффиксом);

    • $? - список зависимостей, которые обновились с момента предыдущего получения цели;

    • $< - полное имя исходного файла, к которому применяется правило трансформации.

  • Обычно существует некоторая база предопределенных правил суффиксов и динамических макроопределений. Они являются правилами по умолчанию для стандартного получения результирующих файлов по исходным файлам. Все они сведены в специальный файл. Например, правило трансформации .cc.о определяется как $(COMPILE.cc) $(OUTPUT_OPTION) $<. Это означает, что для того, чтобы получить файл .о (если есть .сc), надо выполнить указанную команду. Динамическое макроопределение $ (COMPILE.сс) определяется в той же базе как $(ссс) $(CCFLAGS) $ (CPPFLAGS) -с.

Пример файла с инструкциями приведен в листинге 5.1. Именование каталогов дано в стиле операционной системы Unix.

Листинг 5.1. Пример файла с инструкциями для утилиты make

BASE_DIR = /usr

BIN_DIR = $(BASE_DIR)/bin

LIB_DIR = $(BASE_DIR)/lib

# В результате такого описания получится, что значение # переменной BIN_DIR стало равным /usr/bin, a LIB_DIR - /usr/lib.

OBJS = main.о classa.o classb.o

LIBS = libCstd.a libCrun.a

main: clean $(OBJS)

   $(CCC) -o $@ $(OBJS) -L $(LIB_DIR) $(LIBS)

# Разыменование переменной ССС, которая у нас не присутствует, # но может присутствовать в окружении. # Использование $@ после параметра -о приводит к тому, что результирующий файл будет # называться тоже main.

clean:

   rm -f *.o main core

# Удаление всех объектных файлов и core-файла, который может быть # создан в результате некорректного завершения предыдущей компиляции.

classa.o: classa.h

# Указывает зависимость - т. е. когда будет изменен файл classa.h, # файл classa.o потребует перекомпиляции.

Система make может работать в нескольких режимах, задаваемых при старте системы, следующими параметрами:

  • -n - только печатать команды, не исполняя их. То есть если make примет решение на исполнение команд, то система, не передавая их интерпретатору команд, напечатает их на экране;

  • -p - напечатать все макроопределения. То есть после разбора файла определений (makefile) напечатать все найденные там определения макросов и продолжить работу;

  • -s - не печатать команды. Без указания этой опции make при передаче команд интерпретатору команд печатает их на экран;

  • -m - обновить только цель. С этой опцией make, произведя разбор файла определений, выполняет только команды, необходимые для обновления главной цели, и никаких других команд в интерпретатор команд более не передает. Причем команды для обновления главной цели выполняются обязательно, вне зависимости от необходимости.

Также при старте make может получить в качестве параметров имя файла определений и имя главной цели его работы. Если имя файла определений не указано, то в текущем каталоге ищется файл с именем makefile, а если он не находится, то make прекращает работу с сообщением об ошибке. Если не указано имя главной цели, то make по умолчанию берет в качестве главной цели первую цель, найденную ею в файле определений.

Существуют расширения стандартной системы make. Например, одно из них оценивает файл описаний с точки зрения его параллельной обработки и параллельного исполнения команд, необходимых для обновления главной цели. Команды могут быть выполнены параллельно только, если они требуются для обновления абсолютно независимых целей. Иначе они будут по-прежнему исполняться последовательно.