Статья 'Линейные конгруэнтные последовательности максимального периода в задачах обфускации программ' - журнал 'Кибернетика и программирование' - NotaBene.ru
по
Journal Menu
> Issues > Rubrics > About journal > Authors > About the Journal > Requirements for publication > Council of Editors > Peer-review process > Policy of publication. Aims & Scope. > Article retraction > Ethics > Online First Pre-Publication > Copyright & Licensing Policy > Digital archiving policy > Open Access Policy > Article Processing Charge > Article Identification Policy > Plagiarism check policy
Journals in science databases
About the Journal

MAIN PAGE > Back to contents
Cybernetics and programming
Reference:

The linear congruent sequences of the maximum period in programs obfuscation

Borodin Andrey Viktorovich

PhD in Economics

Professor, Department of Computer Science and System Programming, Volga State University of Technology

424000, Russia, respublika Marii El, g. Ioshkar-Ola, pl. Lenina, 3

bor@mari-el.com
Other publications by this author
 

 

DOI:

10.7256/2306-4196.2016.6.18499

Received:

26-03-2016


Published:

31-10-2016


Abstract: The article is devoted to development of the system of practical methods of protection of software against refactoring for purpose of lowering probability of infringement copyright for used algorithms. As the basic method of protection offered approach, which feature is use of the linear congruent sequences as bases for morphism of an order of layout operators of programming language to the execution order of the program, required by functionality. The specific technology of an obfuscation programs written in scripting languages, in particular on Microsoft Visual Basic, is offered. Also the notation of formal understanding of a level resistance of the considered system of methods is discussed. For the formal description of concept of an obfuscation programs and a level resistance of an obfuscation used the set-theoretic formalism. Several results of the number theory is used in article for reasons for existence of the solution of the task obfuscation in the offered setting for any program. The main result of article is new practical approach to an obfuscation programs, written in scripting languages, which can be to a certain extent generalized on language systems of other nature. Also in article the paradoxical result is shown - the obfuscation code can correspond completely to a paradigm of structured programming when saving the declared level of resistance to refactoring.


Keywords:

computational complexity, source code, lexical analysis, linear congruential generator, machine code, obfuscation, code refactoring, spaghetti code, structured programming, VBA

This article written in Russian. You can find original text of the article here .
Введение

Проблема защиты интеллектуальной собственности в последние годы становится все более и более актуальной. Связано это, как с взрывным ростом количества новых идей, продуктов и технологий, так и с упрощением процедур их описания и реализации. Информационные технологии здесь оказались катализатором инновационного процесса. Они предложили гигантское множество простых для пользователя инструментов поддержки инновационной деятельности и постарались, по возможности, предложить технологии защиты интеллектуальной собственности. В то же время, очевидно, что прогресс в развитии простых и удобных в эксплуатации инструментальных средств поддержки инноваций существенно опережает создание и развитие инструментария защиты интеллектуальной собственности. В ряду инструментальных средств, для которых справедливо все выше сказанное, можно отметить продуктовую линейку Microsoft Office, многие популярные продукты компаний Corel, MindJet, CA Technologies и т. д. Эти программные средства благодаря поддержке языка программирования Visual Basic for Applications (VBA) [13] взяли на себя роль метасистем – инструментов создания инноваций в области программного обеспечения со стороны прикладных специалистов, не считавших себя ранее специалистами в области программирования. Еще ярче эта ситуация прослеживается в сфере аппаратного обеспечения. Появление и развитие таких языков описания аппаратуры как Verilog [16] и VHDL [1], с одной стороны, чрезвычайно упростило и ускорило создание множества аппаратных решений, а, с другой, сделало ряд весьма сложных, интеллектуально емких (уникальных) проектов уязвимыми к несанкционированному использованию.

Некоторым препятствием на пути утечки интеллектуальной собственности в описанном контексте являются технологии обфускации. Неформально под обфускацией понимается приведение исходного текста или исполняемого кода программы к виду, сохраняющему её функциональность, но затрудняющему анализ, понимание алгоритмов работы и модификацию после декомпиляции [14]. Таким образом, разработка новых методов обфускации с различными заданными свойствами представляет значительный интерес.

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

Формальное понимание обфускации

Формализацию понятия обфускации удобно начать с рассмотрения коммутативной диаграммы, представленной на рис. 1.

comm_diag_001

Рис. 1. Коммутативная диаграмма, иллюстрирующая понятие обфускации

На рис. 1 использованы следующие обозначения:

`P` – множество программ;

`X` – множество исходных данных для программ из множества `P` ;

`Y` – множество результатов выполнения программ из множества `P` с исходными данными из множества `X` ;

`upsilon` – отображение, реализуемое вычислителем (компьютером);

`O` – множество обфусцированных программ;

`theta` – отображение, реализуемое обфускатором (специальной программой некоторого вычислителя);

`X_1` – некоторое подмножество множества `X` , `X_1sube X` , на диаграмме это отношение представлено соответствующим удлиненным знаком синего цвета,

`Y_1` – подмножество множества `Y` , `Y_1 sube Y` , содержащее результаты выполнения обфусцированных программ из множества `O` с исходными данными из множества `X_1` ;

`D_1` – наблюдаемое атакующим субъектом множество обфусцированных программ с некоторой частью примеров их выполнения, определяемой множеством `X_1` ;

`A` – множество реконструированных атакующим субъектом программ на основе исследования элементов множества `D_1` (или `D_2` ) с использованием алгоритма реконстукции (рефакторинга), представленного на диаграмме отображением `alpha` ;

`X_2` – некоторое подмножество множества `X` , `X_2 sube X` ;

`Y_2` – подмножество множества `Y` , `Y_2 sube Y` , содержащее результаты выполнения программ из множества `P` с исходными данными из множества `X_2` ;

`D_2` – наблюдаемое атакующим субъектом множество исходных программ с некоторой частью примеров их выполнения, определяемой множеством `X_2` ;

две параллельные линии (удлиненный знак равенства) означает, что соединенные этим знаком множества – это одно и то же множество, представляемое синхронно, условно говоря, представляемое в каждый момент времени в каждой своей позиции присутствия одним и тем же своим элементом.

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

Введенная таким образом модель системы программ может быть использована для построения определения обфускации.

Определение 1. Алгоритм `theta` назовем обфускатором для класса программ `P` , если справедливы следующие три свойства.

1) Сохранение функциональности:

`AA p (p in P) quad AA x (x in X) quad [theta(p)(x)=p(x)]` .

2) Не более чем полиномиальное снижение эффективности:

`AA p (p in P) quad [|theta(p)| <= pi_s(|p|)]`

и/или

`AA p (p in P) quad AA x (x in X) quad [tau(theta(p)(x)) <= pi_t(tau(p(x)))]` ,

где `| p |` – сложность программы `p` по объему кода,

`pi_*` – некоторый полином,

`tau(p(x))` – время выполнения программы `p` с исходными данными `x` .

3) Стойкость к реконструкции:

`AA p (p in P) quad [tau(alpha|D_1, quadO={theta(p)}) " >> " tau(alpha|D_2, quad P={p})]` ,

где `tau(alpha|D_1, quad O={theta(p)})` – время исполнения сужения отображения `alpha` на множество `D_1` для случая, когда множество `O` содержит один элемент – результат обфускации программы `p` ,

`tau(alpha|D_2, quad P={p})` – время исполнения сужения отображения `alpha` на множество `D_2` для случая, когда множество `P` содержит один элемент – программу `p` .

Данное определение построено по схеме, выработанной в работах [5, 20, 25], но в терминах теории множеств. По мнению автора, предложенная нотация проще для понимания и она достаточна для постановки задачи, рассматриваемой в настоящей работе.

Заметим, что степень строгости определения 1 может быть повышена за счет уточнения смысла, вкладываемого в отношение «`">>"` », а степень специализации определения – за счет уточнения понятия отображения `alpha` и его домена. Так, например, если на рис. 1 множество исходных программ с некоторой частью примеров их выполнения `D_2` заменить на множество лишь примеров их выполнения `D_2^delta = { { (x, quad p(x)) quad : quad x in X_2} quad : quad p in P}` , а отношение «`">>"` » в третьем свойстве определения 1 понимать как отношение «`>=` », то мы приходим к определению обфускатора – «черного ящика» [20], исследование результатов работы которого предоставляет атакующему субъекту информации не больше, чем исходная программа, рассматриваемая как «черный ящик». Развитие идей, положенных в основу определения обфускатора – «черного ящика», привело к понятиям обфускатора неразличимости [20] и лучшего обфускатора [25]. Некоторые результаты в части исследования возможных практических подходов к созданию алгоритмов обфускации в названных смыслах приведены в работе [24]. Русскоязычный обзор результатов в области соответствующей теории обфускации представлен в работах [5, 7, 12]. Заметим, что во всех перечисленных публикациях в качестве нотации исследования предметной области использована теоретико-вероятностная нотация, а также язык машин Тьюринга и логических схем.

Целью настоящей работы является разработка практического метода обфускации, стойкость которого характеризуется интерпретацией отношения «`">>"` » в третьем свойстве определения 1 как простого отношения «больше». Иначе говоря, разрабатываемый метод обфускации должен усложнять полуавтоматический рефакторинг и он не претендует на строго доказанную стойкость в каком-либо смысле.

Основания разработки

Разработке и исследованию практических методов обфускации посвящено огромное количество работ. Отметим некоторые из них, важные и знаковые с точки зрения данного исследования.

Очень подробный обзор практических методов обфускации дает отчет Стефана Драпе [22]. В обзорной части этого отчета, на стр. 14-16, фактически присутствует первый шаг реализации подхода, развиваемого в данном исследовании. Речь идет о статическом отображении порядка следования операторов в программе на порядок их выполнения. Остается скрыть эту статику за «ширмой» отображений, отчужденных по месту расположения в программе от функционально значимых операторов, иначе говоря, скрыть за «ширмой» динамики, реализуемой некоторой функцией, и мы получаем то, что предлагаем.

Работы [21, 23] посвящены обсуждению проблем и методов обфускации данных и, в частности, матриц. Простейшие идеи из этих двух работ эффективно могут быть использованы при обфускации констант – вспомогательного метода, способного усилить эффект разрабатываемого в данной работе подхода.

Рассматривались практические подходы к обфускации и на страницах настоящего журнала [10, 11]. Последняя из этих работ интересна упоминанием экзотических подходов к обфускации, в частности основанных на языке сетей Петри. Идеи этого подхода позволили наметить дальнейшие пути развития предлагаемого метода в направлении совместной обфускации сразу нескольких программных модулей, интерфейсный раздел которых допускает обобщение.

Идея метода

Идея метода обфускации, предлагаемого в данной работе, заключается в том, что любой базовый блок программы на императивном языке программирования, см. левый столбец таблицы 1, можно представить в виде эквивалентной конструкции, см. правый столбец таблицы 1.

Таблица 1

Функционально эквивалентное преобразование базового блока программы

fepvba001

В таблице использованы следующие обозначения:

`g: quadNN-> NN` – биекция, которая является образующим элементом некоторой циклической группы с количеством элементов не меньше `N+1` , причем

`AA k quad (k=1, quad 2, quad ... quad, quad N+1) quad [n_i=k quad =>quad x_i=g^k(x_0)]` ,

где `g^k(x) = (@_(i=1)^k g)(x)` ;

`NN` – множество натуральных чисел;

`x_0` – некоторое начальное значение, `x_0 in NN` ;

`x_i` – значение ключа, по которому осуществляется выбор исполняемого оператора, `x_i in NN` ;

`n_i` – номер оператора, соответствующего ключу `x_i` ; `i=1, quad 2, quad ... quad, quad N+1` .

Заметим, что разные циклические образующие `g` могут порождать разные функционально эквивалентные конструкции. Дополнительное разнообразие во множество этих конструкций может внести возможность варьирования числа `x_0` . Это замечание, кстати, имеет особое значение для практики конструирования самомодифицирующихся компьютерных вирусов без сигнатур [4]. Обсуждению другой стороны этой возможности (противодействию) посвящена работа [6].

Для того, чтобы обсуждаемый подход на основе функционально эквивалентного преобразования, представленного в таблице 1, стал действительно практическим, необходимо подобрать такую биекцию `g` , которая обеспечивала бы заданный порядок порождаемой ей циклической группы и реализация которой, с одной стороны, была бы вычислительно простой, а с другой, легко бы могла быть сама подвергнута обфускации.

Хорошим кандидатом на роль такого преобразования `g` , по мнению автора, является рекуррентное соотношение, порождающее так называемые линейные конгруэнтные последовательности (ЛКП) [9]. Преобразование, порождающее ЛКП, имеет всего три параметра, соответствующий выбор которых гарантирует максимальный период последовательности, равный одному из параметров, называемому модулем, см теорему A [9, c. 29]. Поскольку период ЛКП определяет порядок циклической группы, то требование обеспечения любого заданного порядка группы выполнено. С другой стороны, ЛКП во многих случаях напоминают случайные последовательности с равномерным законом распределения элементов, что позволяет при выполнении не очень обременительных условий порождать функционально эквивалентные коды, для предположительного обнаружения экземпляра которых необходимо использовать некоторое множество сигнатур, мощность которого не меньше порядка циклической группы (периода ЛКП). Этот тезис для отрасли разработки компьютерных вирусов фактически эквивалентен следующему высказыванию: «чем больше размер кода компьютерного вируса, тем сложнее, в общем случае, делать высоко достоверный вывод о его обнаружении с использованием традиционных подходов». Проблемы, связанные с отклонением свойств ЛКП от свойств истинно случайных последовательностей, для данного приложения не вызывают проблем применимости, характерных для традиционных приложений псевдослучайных чисел, таких, как методы класса Монте-Карло и криптографические приложения [3], что также положительно характеризует наш выбор циклической образующей.

Укрупненный алгоритм метода

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

Таблица 2

Функционально эквивалентное преобразование линейного фрагмента программы с оператором GoTo

fepvba002

Таким образом, мы приходим к заключению, что если некоторая программа не содержит типовых конструкций языка структурного программирования, то есть полностью представляет из себя спагетти-код [15], то она очевидным образом может быть обфусцирована предлагаемым в этой и предыдущей главах настоящей статьи методом.

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

1) лексический разбор;

2) деструктурирование кода;

3) обфускация кода;

4) обфускация переменных;

5) обфускация констант.

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

Деструктурирование кода

В основу алгоритма деструктурирования кода положены принципы эквивалентного преобразования конструкций структурного программирования (для заданного языка программирования) в спагетти-код, см. таблицу 3.

Таблица 3

Принципы эквивалентного преобразования базовых конструкций структурного программирования языка программирования VBA

destructtabl0101

destructtabl0102

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

Для примера рассмотрим исходный код функции, реализующей расширенный алгоритм Евклида, см. листинг 1. Этот пример будет в настоящей работе сквозным для иллюстрации всех этапов обфускации.

Листинг 1

vba_ae_00

Результат деструктурирования кода, представленного на листинге1, приведен в листинге 2.

Листинг 2

vba_ae_01

В спагетти-коде, представленном на листинге 2, сохранены отступы, позволяющие проследить прошлую структурированность программы. Также в этом коде элементы, заменившие конструкции структурного программирования, предварены комментариями, содержащими исходные элементы, а все выполнимые операторы языка пронумерованы (в заоператорных комментариях) с 0 до 16. Номер 17 соответствует выходу из функции.

Обфускация кода

В программе, представленной на листинге 2, имеется 17 выполнимых операторов, пронумерованных от 0 до 16, 17-й оператор – «пустой», соответствует завершению программы. Таким образом, для обфускации программы необходима ЛКП с периодом не меньше 18. Выберем в качестве модуля линейного конгруэнтного преобразования число 18. Это означает, что преобразование `g(x)=| a x + c |_m` , где `m=18` , а `|a|_m` обозначает наименьший неотрицательный вычет числа `a` по модулю `m` , может породить ЛКП максимального периода 18, если множитель `a` и приращение `c` будут соответствовать условиям теоремы A [9, c. 29], например, `a=7` , `c=11` . В качестве начального значения `x_0` можно взять любое целое число от 0 до 17. Например, если `x_0 = 8` , то мы получаем следующий период:

`(13, quad 12, quad 5, quad 10, quad 9, quad 2, quad 7, quad 6, quad 17, quad 4, quad 3, quad 14, quad 1, quad 0, quad 11, quad 16, quad 15, quad 8) ` .

Используя эти значения и идеи преобразования кода, представленные в таблицах 1 и 2, мы можем преобразовать программный код, приведенный на листинге 2, в программный код, приведенный на листинге 3.

Листинг 3

vba_ae_02

На листинге 3 присутствуют отступы, демонстрирующие структурную организацию нового эквивалентного кода. Кроме того, добавлены строчные комментарии для «логического присутствия» меток и операторов «GoTo», а также заоператорные комментарии для номеров операторов (по порядку выполнения) и значений элементов периода, предшествующих требуемым, в соответствии с оператором «GoTo».

Как мы убедились, алгоритм преобразования оказывается очень простым.

Обфускация переменных

По мнению ряда исследователей [26] проблемы с семантикой идентификаторов при рефакторинге увеличивают время, необходимое для понимания алгоритма, в среднем в два раза по отношению к ситуации, когда поток управления зависит от множества «непрозрачных» предикатов. Еще большего эффекта можно добиться при реализации идеи повторного использования идентификаторов [26], когда семантически обусловлено разные идентификаторы, но не пересекающиеся по области использования, при совпадении типов, объединяются по обфусцированному имени.

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

1) генерация имен, состоящих из допустимых случайных (псевдослучайных) символов, длиной из заданного интервала, или имен с фиксированной длиной, когда границы интервала совпадают;

2) генерация имен, состоящих из некоторого количества повторяющихся допустимых символов, в условиях, когда множество символов задано и задан интервал длин идентификаторов;

3) смешанная стратегия с равновероятным выбором стратегий 1 и 2.

В качестве примера, результат обфускации имен переменных в коде, приведенном на листинге 3, при фиксированной длине идентификаторов, равной 8, приведен на листинге 4.

Листинг 4

vba_ae_03

На листинге 4 отступы, демонстрирующие структурную организацию программы, и все комментарии удалены.

Таблица замены идентификаторов представлена таблицей 4.

Таблица 4

Таблица замены идентификаторов

No IderOld IderNew
1 ExtEuclidObfuskat1 jfU5puyE
2 a quEvc8xr
3 b kRaZ2Ipi
4 GCD M5XX4pmi
5 r I08HujHx
6 r_pre jBsfK8YG
7 r_pre_pre swKZJf6e
8 y FQYIO5Bp
9 y_pre p7e5LjKj
10 y_pre_pre jJBgVzoy
11 xx RcmiOrCO


Обфускация констант

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

Заметим, что константы основных базовых типов языков программирования легко могут быть представлены целыми неотрицательными числами. Константа целого типа – это целое неотрицательное со знаком, вещественного типа – это целое неотрицательное со знаком для мантиссы и целое неотрицательное со знаком для порядка, константа строкового типа – это набор ординалов, соответствующих символам, иначе, набор целых неотрицательных чисел. Таким образом, задачу обфускации констант базовых типов можно свести к задаче обфускации целых неотрицательных констант.

Формализуем задачу. Пусть `C` – множество целых неотрицательных констант, используемых в обфусцируемой программе, `C sub ZZ_0^+` . Здесь `ZZ_0^+` – множество целых неотрицательных чисел. Пусть, далее, `m = max quad C quad + quad 1` , то есть `Csube ZZ_m stackrel(Def)(=) {0, quad 1, quad ... quad, quad m-1}` . Пусть `R` – множество (вспомогательных) констант, которые представлены в программе не только своими идентификаторами, но и явно записанными целыми числами без знака. Теперь можно ввести множество констант, используемых в программе и заданных явно,

`C_0(R) = C nnR` .

На первом шаге, используя данное множество констант, можно его расширить с помощью ряда линейных комбинаций:

`C_1(R, quad A_0, quad x_0)=C_0(R) quad uu quad{c: quad c in C-C_0(R), quad c=sum_(a in A_0(c)) quad x_0(c, quad a) quad a}` ,

где `A_0: quad C-C_0(R) -> 2^(C_0(R))` – некоторая функция, представляющая подмножество констант, из множества `C_0(R)` , используемых в линейной комбинации для порождения некоторых констант из множества `C-C_0(R)` на первой итерации,

`x_0: quad [C-C_0(R)] xx C_0(R) -> C_0(R)` – функция, которая при порождении некоторых констант `c` , из множества `C-C_0(R)` , сопоставляет каждому члену линейной комбинации из множества `A_0(c)` коэффициент из множества `C_0(R)` .

На последующих шагах мы можем постепенно расширять множество констант, определенных через константы предыдущих шагов:

`C_(k+1)(R, quad A_k, quad x_k) = C_k(R, quad A_(k-1), quad x_(k-1)) quad uu`

`uu quad {c: quad c in C-C_k(R, quad, A_(k-1), quad x_(k-1)), quad c=sum_(a in A_k(c)) quad x_k(c, quad a) quad a}` ,

где `A_k: quad C-C_K(R, quad A_(k-1), quad x_(k-1)) -> 2^(C_k(R, quad, A_(k-1), quad x_(k-1))` – некоторая функция, представляющая подмножество констант, из множества `C_k(R, quad A_(k-1), quad x_(k-1))` , используемых в линейной комбинации для порождения некоторых констант из множества `C-C_k(R, quad A_(k-1), quad x_(k-1))` на `(k+1)` -й итерации,

`x_k: quad [C-C_k(R, quad A_(k-1), quad x_(k-1))] xx C_k(R, quad A_(k-1), quad x_(k-1)) -> C_k(R, quad A_(k-1), quad x_(k-1))` – функция, которая при порождении некоторых констант `c` , из множества `C-C_k(R, quad A_(k-1), quad x_(k-1))` , сопоставляет каждому члену линейной комбинации из множества `A_k(c)` коэффициент из множества `C_k(R, quad A_(k-1), quad x_(k-1))` , `k=1, quad 2, quad ...` .

Очевидно, что для некоторых `R` на некоторой итерации `k'` будет достигнуто определение всех необходимых констант:

`C_(k')(R, quad A_(k'-1), quad x_(k'-1)) = C` .

Определим множество возможных параметров порождения заданного множества констант при фиксированном множестве непосредственно заданных констант:

`V(R)stackrel(Def)(=) {(k', quad (A_k, quad x_k)_(k=0)^(k=k'-1)): quad C_(k')(R, quad A_(k'-1), quad x_(k'-1))=C}` .

Теперь можно сформулировать ряд оптимизационных задач.

1) Задача минимизации количества операций при порождении заданного набора констант `C` при фиксированном множестве непосредственно определенных констант `R` :

`pi(R)stackrel(Def)(=)(k'', quad (A'_k, quad x'_k)_(k=0)^(k=k''-1))(R)=`

`="arg" quad min_(V(R)) quad sum_(k=1)^(k') quad quad sum_(c in C_k(R, quad A_(k-1), quad x_(k-1))) quad |A_k(c)|` . (1)

2) Задача минимизации количества непосредственно определенных констант среди вариантов с минимальной сложностью формул:

`R'="arg" min_(R in "Dom" quad pi) quad |R|` , (2)

где `"Dom" quad pi` – область определения функции `pi` .

Значение функции `pi(R')` можно рассматривать как оптимальную (в определенном смысле) схему обфускации констант. Следует, однако, отметить, что алгоритм точного решения задачи вычисления `pi(R')` лежит, по-видимому, в классе `"EXPSPACE"` . Поэтому на практике задача вычисления `pi(R')` решается каким-либо приближенным эмпирическим методом. Так вариант решения этой задачи для нашего сквозного примера реализован в коде, представленном на листинге 5.

Листинг 5

vba_ae_04

Код, представленный на листинге 5, является окончательным результатом обфускации исходного кода (листинг 1) в рамках предлагаемого подхода. Сравнив эти листинги, можно попытаться оценить перспективы соответствующего реверс-инжиниринга.

Перспективы развития

Предлагаемый подход к обфускации обещает целый ряд интересных перспектив использования.

1) Предположим, что некоторое количество подпрограмм имеет одинаковый интерфейс. При этом, независимо от сложности реализации, код каждой подпрограммы может быть превращен в спагетти-код на основе идеи деструктурирования. Теперь можно вычислить суммарное количество исполнимых операторов с учетом (оператора) выхода для всех подпрограмм и построить ЛКП с соответствующей длиной периода. Если объединить эти подпрограммы под одним именем, а в их стандартный интерфейс добавить признак выбора конкретной подпрограммы и, далее, используя этот признак инициализировать `x_0` значениями из периода с шагом в длину каждой из подпрограмм, то в одну обфусцирующую конструкцию возможно уложить весь набор этих подпрограмм. Для реализации этой возможности необходимо выполнение одного дополнительного не очень обременительного (ввиду редкости возникновения прецедента) требования: объединяемые подпрограммы не должны использовать одинаковые идентификаторы для статических переменных. Очевидно, что такая смесь из кодов более чем одной подпрограммы сложнее для полуавтоматического рефакторинга, чем случай рефакторинга этих подпрограмм, обфусцированных по отдельности. И если, в случае автоматического анализа кода разделение обфусцированного кода на отдельные подпрограммы может оказаться относительно простым, то с точки зрения рефакторинга алгоритмов, использующих эти подпрограммы, такое объединение совместно с утратой семантики идентификаторов подпрограмм означает значительный рост трудоемкости [26].

2) В работе [2] был предложен метод оценки совокупной стоимости владения объектно-ориентированной метасистемой в условиях заданной модели угроз. Риск реализации угрозы в этой работе было предложено подвергнуть декомпозиции в рамках некоторой логико-вероятностной модели параллельно с декомпозицией объектной модели системы. При этом вероятность реализации активной угрозы (атаки со стороны рационального злоумышленника) здесь тем выше, чем выше степень рефакторинга целевого класса (объекта). В этом смысле предложенный подход к обфускации кода может заметно снизить вероятность реализации целенаправленной атаки. Важно, что если, с одной стороны, рост объема кода увеличивает вероятность реализации атаки, то с другой, этот же рост при применении предлагаемой технологии обфускации способен снижать эту вероятность. Таким образом, в определенных случаях, обфускация может снижать совокупную стоимость владения системами, существующими в среде некоторой объектно-ориентированной метасистемы в условиях атак, как на эти системы, так и на метасистему в целом. В этой связи отметим, что в последние годы была создана алгебраическая теория риска [17], использование методов которой позволило оценивать характеристики различных случайных величин (например, совокупной стоимости владения) с высокой степенью точности на различных интервалах времени. Таким образом, сегодня имеется возможность оценки экономической эффективности использования предлагаемого подхода к обфускации программ на заданном интервале времени в рамках использования обсуждаемой технологии в любом проектируемом приложении. Для расчетов может быть использован пакет прикладных программ (ППП) «МультиМИР» [19].

3) Часто, при исследовании программных систем, используется метод целенаправленной модификации кода с последующим изучением результатов работы модифицированного кода. Для исключения такой возможности целесообразно исследовать перспективы совместного использования предложенного подхода с технологиями доверенной загрузки программ [8].

4) В некоторых случаях предлагаемый подход может существенно усложнить реализацию некоторых позитивных педагогических идей [27]. Выход здесь просматривается в сфере более пристального внимания к программному коду работ обучающихся в части объяснения семантики алгоритмов в их тесной связи с конкретной программной реализацией.

Заключение

Предложенный подход к обфускации программ был апробирован при разработке ППП «МультиМИР» версии 1.1 [18], реализованного на языке VBA, для защиты части программных модулей, содержащих элементы «know how», в связи с началом распространения данной версии ППП среди заказчиков.

В настоящее время ведутся работы по совершенствованию ряда алгоритмов предложенного метода обфускации и приведению реализации метода в состояние самостоятельного продукта.

References
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
Link to this article

You can simply select and copy link from below text field.


Other our sites:
Official Website of NOTA BENE / Aurora Group s.r.o.