Алгоритмы процесса обфускации — КиберПедия 

Организация стока поверхностных вод: Наибольшее количество влаги на земном шаре испаряется с поверхности морей и океанов (88‰)...

Автоматическое растормаживание колес: Тормозные устройства колес предназначены для уменьше­ния длины пробега и улучшения маневрирования ВС при...

Алгоритмы процесса обфускации

2017-06-11 802
Алгоритмы процесса обфускации 0.00 из 5.00 0 оценок
Заказать работу

Алгоритм обфускации в большинстве случаев рассматривается как алгоритм, которого должен придерживаться обфускатор (независимая программа, которая осуществляет процесс обфускации над переданным ей кодом).

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

5.3.1 Алгоритм Колберга ("Collberg`s algorithm").

 

Данный алгоритм оперирует следующими входными значениями:

- программа "А" состоящая из исходных или объектных (двоичных) файлов "{С1,С2}".

- стандартные библиотеки, используемые программой "{L1,L2}".

- набор трансформирующих процессов "Т{Т1,Т2}".

- определенный фрагмент кода "S", который извлекается из программы "А", и который непосредственно будет подвержен трансформации.

- набор функций "Е{Е1,Е2}" которые будут определять эффективность применения определенных трансформирующих процессов "{Т1,Т2}" к фрагменту кода "S".

- набор функций "I{I1,I2}" которые будут определять важность фрагмента кода "S", и в зависимости от этого будут задавать определенное значение переменной "RequireObfuscation" (чем "S" важнее тем эта переменная будет хранить большее значение).

- две числовые переменные "AcceptCost" > 0, "RequireObfuscation" > 0, где первое хранит информацию о доступном максимальном увеличении системных ресурсов по требующихся программе "А" после того как она подвергнется обфускации, а вторая переменная будет хранить значение требуемого уровня осуществления обфускации (чем важнее фрагмент кода "S", тем это значение должно быть больше).

 

Алгоритм Колберга имеет такую последовательность операций:

1. Загрузка элементов "{С1,С2}" программы "А".

2. Загрузка библиотек "{L1,L2}".

3. Осуществление обфускации над программой "А", путем выделения фрагмента кода "S" и определения наиболее эффективного процесса трансформации для него. Этот этап повторяется до тех пор, пока не будет, достигнут требуемый уровень обфускации "RequireObfuscation" или допустимое увеличение ресурсов "AcceptCost".

4. Генерация трансформируемой программы "А`".

 

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

 

5.3.2 Chenxi Wang`s алгоритм.

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

1. создание графа потока управления этой процедуры (граф задаётся множеством блоков и множеством связей соединяющих их), после чего граф разбивается, путем замены циклических конструкций в нем на конструкции типа "if (условие) goto", (Рисунок 4).

2. нумерация всех блоков в графе, и добавление в код процедуры переменной (например "swVar") хранящей номер следующего выполняемого блока

3. приведение графа к однородному ("плоскому") виду (Рисунок 5)

 

Рисунок 4. Пример разбитого графа потока управления.

Рисунок 5. Вид графа, приведенного к плоскому виду.

Выше описанный вариант алгоритма обфускации ("Chenxi Wang`s algorithm") является не сильно устойчивым, так как определить следующий выполняемый блок, нетрудно (он в нашем случае будет храниться в переменной "swVar"). Поэтому для повышения его устойчивости вводят массив (например "@gg"), содержащий помимо номеров блоков, не нужную информацию, в результате запись "$swVar = S6", можно заменить на нечто подобное "$swVar = $gg[$gg[1] + $gg[3]]".

 

Виды обфускации

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

 

Лексическая обфускация

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

Обфускация такого вида включает в себя:

- удаление всех комментариев в коде программы, или изменение их на дезинформирующие

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

- замену имен идентификаторов (имен переменных, массивов, структур, хешей, функций, процедур и т.д.), на произвольные длинные наборы символов, которые трудно воспринимать человеку

- добавление различных лишних (мусорных) операций

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

Изменение глобальных имён идентификаторов следует производить в каждой единице трансляции (один файл исходного кода), так чтобы они имели одинаковые имена (в противном случае защищаемая программа может стать не функциональной). Также следует учитывать специфические идентификаторы, принятые в том языке программирования, на котором написана защищаемая программа, имена таких идентификаторов, лучше не изменять, например, в PERL-е к таким идентификаторам можно отнести "@ARGV", "$_", "$^O" и т.д.

 

Обфускация данных

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

 

1. Обфускация хранения. Заключается в трансформации хранилищ данных, а также самих типов данных (например, создание и использование необычных типов данных, изменение представления существующих и т.д.). Основные методы:

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

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

- преобразование статических (неменяющихся) данных в процедурные. Большинство программ, в процессе работы, выводят различную информацию, которая чаще всего в коде программы представляется в виде статических данных таких как строки, которые позволяют визуально ориентироваться в ее коде и определять выполняемые операции. Такие строки также желательно предать обфускации, это можно сделать, просто записывая каждый символ строки, используя его ASCII код, например символ "A" можно записать как 16-ричное число "0х41", но такой метод банален. Наиболее эффективный метод, это когда в код программы в процессе осуществления обфусации добавляется функция, генерирующая требуемую строку в соответствии с переданными ей аргументами, после этого строки в этом коде удаляются, и на их место записывается вызов этой функции с соответствующими аргументами.

- разделение переменных. Переменные фиксированного диапазона могут быть разделены на две и более переменных. Для этого переменную "V" имеющую тип "x" разделяют на "k" переменных "v1,...,vk" типа "y" то есть "V == v1,...,vk". Потом создается набор функций позволяющих извлекать переменную типа "x" из переменных типа "y" и записывать переменную типа "x" в переменные типа "y".

 

 

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

- объединение переменных. Две или более переменных "v1,...,vk" могут быть объединены в одну переменную "V", если их общий размер ("v1,...,vk") не превышает размер переменной "V". Например, рассмотрим простой пример объединения двух коротких целочисленных переменных "X","Y" (размером 16 бит) в одну целочисленную переменную "Z" (размером 32 бита).

- реструктурирование массивов, заключается в запутывании структуры массивов, путем разделения одного массива на несколько подмассивов, объединения нескольких массивов в один, сворачивания массива (увеличивая его размерность) и наоборот, разворачивая (уменьшая его размерность).

- изменение иерархий наследования классов, осуществляется путем усложнения иерархии наследования при помощи создания дополнительных классов или использования ложного разделения классов.

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

 

Обфускация управления

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

Большинство ее реализаций основывается на использовании непрозрачных предикат, в качестве, которых выступают, последовательности операций, результат работы которых сложно определить (само понятие "предикат" выражает свойство одного объекта (аргумента), или отношения между несколькими объектами).

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

 


Поделиться с друзьями:

Общие условия выбора системы дренажа: Система дренажа выбирается в зависимости от характера защищаемого...

Археология об основании Рима: Новые раскопки проясняют и такой острый дискуссионный вопрос, как дата самого возникновения Рима...

Индивидуальные очистные сооружения: К классу индивидуальных очистных сооружений относят сооружения, пропускная способность которых...

Механическое удерживание земляных масс: Механическое удерживание земляных масс на склоне обеспечивают контрфорсными сооружениями различных конструкций...



© cyberpedia.su 2017-2024 - Не является автором материалов. Исключительное право сохранено за автором текста.
Если вы не хотите, чтобы данный материал был у нас на сайте, перейдите по ссылке: Нарушение авторских прав. Мы поможем в написании вашей работы!

0.018 с.