Обфускация (программное обеспечение): различия между версиями

Материал из Википедии — свободной энциклопедии
Перейти к навигации Перейти к поиску
[непроверенная версия][непроверенная версия]
Содержимое удалено Содержимое добавлено
оформление
 
(не показано 30 промежуточных версий 20 участников)
Строка 1: Строка 1:
{{Значения|Обфускация}}
'''Обфуска́ция''' (от {{lang-la|obfuscare}} — затенять, затемнять; и {{lang-en|obfuscate}} — делать неочевидным, запутанным, сбивать с толку) или '''запутывание кода''' — приведение [[Исходный код|исходного текста]] или исполняемого кода программы к виду, сохраняющему её функциональность, но затрудняющему анализ, понимание алгоритмов работы и модификацию при [[Декомпилятор|декомпиляции]].
'''Обфуска́ция''' (от {{lang-la|obfuscare}} — затенять, затемнять; и {{lang-en|obfuscate}} — делать неочевидным, запутанным, сбивать с толку) или '''запутывание кода''' — приведение [[Исходный код|исходного кода]] или исполняемого кода программы к виду, сохраняющему её функциональность, но затрудняющему анализ, понимание алгоритмов работы и модификацию при [[Декомпилятор|декомпиляции]].


«Запутывание» кода может осуществляться на уровне [[алгоритм]]а, [[Исходный код|исходного текста]] и/или [[ассемблер]]ного текста. Для создания запутанного ассемблерного текста могут использоваться специализированные [[компилятор]]ы, использующие неочевидные или [[недокументированные возможности]] [[Среда выполнения|среды исполнения]] программы. Существуют также специальные программы, производящие обфускацию, называемые '''обфускаторами''' ({{lang-en|obfuscator}}).
«Запутывание» кода может осуществляться как на уровне наименований компонентов программы, так и на уровне [[алгоритм|алгоритмов]] программы. Для создания запутанного ассемблерного текста могут использоваться специализированные [[компилятор]]ы, использующие неочевидные или [[недокументированные возможности]] [[Среда выполнения|среды исполнения]] программы. Существуют также специальные программы, производящие обфускацию, называемые '''обфускаторами''' ({{lang-en|obfuscator}}).


== Цели обфускации ==
== Цели обфускации ==
* Затруднение [[Декомпиляция|декомпиляции]]/[[Отладка программы|отладки]] и изучения [[Компьютерная программа|программ]] с целью обнаружения функциональности.
* Затруднение [[Декомпиляция|декомпиляции]]/[[Отладка программы|отладки]] и изучения [[Компьютерная программа|программ]] с целью обнаружения функциональности;

* Затруднение декомпиляции [[Проприетарное ПО|проприетарных]] программ с целью предотвращения [[Обратная разработка|обратной разработки]] или обхода [[Технические средства защиты авторских прав|DRM и систем проверки лицензий]].
* Затруднение декомпиляции [[Проприетарное ПО|проприетарных]] программ с целью предотвращения [[Обратная разработка|обратной разработки]] или обхода [[Технические средства защиты авторских прав|DRM и систем проверки лицензий]];
* [[Оптимизация (информатика)|Оптимизация]] программы с целью уменьшения размера работающего [[Программный код|кода]] и (если используется [[Компилируемый язык программирования|некомпилируемый]] язык) ускорения работы.

* Затруднение [[Взлом программного обеспечения|взлома программного обеспечения]];

* [[Оптимизация (информатика)|Оптимизация]] программы с целью уменьшения размера работающего [[Программный код|кода]] и (если используется [[Компилируемый язык программирования|некомпилируемый]] язык) ускорения работы;

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


Строка 12: Строка 18:


=== На уровне исходных текстов ===
=== На уровне исходных текстов ===
{{см. также|Минификация (программирование)}}
На [[JavaScript]], [[VBScript]] и подобных [[скрипт]]-языках пользователю доступен [[исходный текст]] программы. В этом случае форматированием текста и заменой имён можно сделать текст менее читаемым.
На [[JavaScript]], [[VBScript]] и подобных [[скрипт]]-языках пользователю доступен [[исходный текст]] программы. В этом случае форматированием текста и заменой имён можно сделать текст менее читаемым.


Исходный текст:
Исходный текст на языке [[Си (язык программирования)|C]]:
<source lang="C">

'''int''' COUNT = 100;
int COUNT = 100;
'''float''' TAX_RATE = 0.2;
float TAX_RATE = 0.2;
'''for''' ('''int''' i=0; i<COUNT; i++)
for (int i=0; i<COUNT; i++)
{
{
tax[i] = orig_price[i] * TAX_RATE;
tax[i] = orig_price[i] * TAX_RATE;
price[i] = orig_price[i] + tax[i];
price[i] = orig_price[i] + tax[i];
}
}
</source>


Код после обфускации<ref>В данном случае это можно назвать [[Минификация (программирование)|минификацией]]</ref>:
Код после обфускации:
<source lang="C">

'''for'''('''int''' a=0;a<100;a++){b[a]=c[a]*0.2;d[a]=c[a]+b[a];}
for(int a=0;a<100;a++){b[a]=c[a]*0.2;d[a]=c[a]+b[a];}
</source>
Более сложный пример:
<source lang="C">
char*M,A,Z,E=40,J[40],T[40];main(C){for(*J=A=scanf(M="%d",&C);
-- E; J[ E] =T
[E ]= E) printf("._"); for(;(A-=Z=!Z) || (printf("\n|"
) , A = 39 ,C --
) ; Z || printf (M ))M[Z]=Z[A-(E =A[J-Z])&&!C
& A == T[ A]
|6<<27<rand()||!C&!Z?J[T[E]=T[A]]=E,J[T[A]=A-Z]=A,"_.":" |"];}
</source>


=== На уровне машинного кода ===
=== На уровне машинного кода ===
{{main|Машинный код}}
{{main|Машинный код}}
Как правило, обфускация на уровне машинного кода уменьшает скорость [[Выполнение программы|выполнения]] и соответственно увеличивает время выполнения программы. Поэтому она применяется в критичных к [[Информационная безопасность|безопасности]], но не критичных к скорости местах программы, таких как проверка регистрационного кода<ref>{{Cite web|accessdate = 2016-02-02|title = 10.2. Методы проверки регистрационных кодов|url = http://www.rfcmd.ru/+book_08/h10_2|publisher = www.rfcmd.ru}}</ref>.
Как правило, обфускация на уровне машинного кода увеличивает время [[Выполнение программы|выполнения]] программы. Поэтому она применяется в критичных к [[Информационная безопасность|безопасности]], но не критичных к скорости местах программы, таких как проверка регистрационного кода<ref>{{Cite web|accessdate = 2016-02-02|title = 10.2. Методы проверки регистрационных кодов|url = http://www.rfcmd.ru/+book_08/h10_2|publisher = www.rfcmd.ru|archive-date = 2016-12-12|archive-url = https://web.archive.org/web/20161212181835/http://www.rfcmd.ru/+book_08/h10_2|deadlink = no}}</ref>.


Простейший способ обфускации [[Машинный код|машинного кода]] — вставка в него недействующих конструкций (таких как <code>or ax, ax</code>)
Простейший способ обфускации [[Машинный код|машинного кода]] — вставка в него недействующих конструкций (таких как <code>or ax, ax</code>).


=== На уровне промежуточного кода ===
=== На уровне промежуточного кода ===
{{main|Байт-код}}
{{main|Байт-код}}
В отличие от обычных языков программирования, таких как [[C++]] или [[Паскаль (язык программирования)|Паскаль]], компилирующихся в [[машинный код]], язык [[Java]], [[NetP]] и языки платформы [[.NET Framework|.NET]] компилируют исходный код в [[промежуточный код]] ([[байт-код]]), который содержит достаточно информации для адекватного восстановления исходного кода. По этой причине для этих языков применяется обфускация промежуточного кода.
В отличие от обычных языков программирования, таких как [[C++]] или [[Паскаль (язык программирования)|Паскаль]], компилирующихся в [[машинный код]], язык [[Java]], [[NetP]] и языки платформы [[.NET Framework|.NET]] компилируют исходный код в [[промежуточный код]] ([[байт-код]]), который содержит достаточно информации для адекватного [[Декомпиляция|восстановления]] исходного кода. По этой причине для этих языков применяется обфускация промежуточного кода.


== Назначение ==
== Назначение ==


=== Усложнение исследования кода ===
=== Усложнение исследования кода ===
Как было сказано выше, [[декомпиляция]] программ Java и .NET достаточно проста. В этом случае обфускатор оказывает неоценимую помощь тем, кто хочет скрыть свой код от посторонних глаз. Зачастую после обфускации декомпилированный код повторно не компилируется.
Обфускатор оказывает неоценимую помощь тем, кто хочет скрыть свой код от посторонних глаз. Зачастую после обфускации декомпилированный код повторно не компилируется.


Обфускация [[HTML]] помогает [[спам]]ерам: на [[Почтовый клиент|почтовом клиенте]], который способен отображать HTML, текст читается, но [[Спам-фильтр|антиспам-фильтр]], который имеет дело с исходным HTML-файлом, пропускает нежелательное сообщение, не распознавая в нём запретной строки.
Обфускация [[HTML]] помогает [[спам]]ерам: на [[Почтовый клиент|почтовом клиенте]], который способен отображать HTML, текст читается, но [[Спам-фильтр|антиспам-фильтр]], который имеет дело с исходным HTML-файлом, пропускает нежелательное сообщение, не распознавая в нём запретной строки.


Простейший пример обфусцированного HTML:
Простейший пример обфусцированного HTML:
<source lang="HTML">

<nowiki><b>Маш</b><b>ина</b></nowiki>
<b>Маш</b><b>ина</b>
</source>


При просмотре пользователь увидит слово «'''Машина'''», в то время как в исходном коде оно расчленено и воспринимается как два раздельных слова.
При просмотре пользователь увидит слово «'''Машина'''», в то время как в исходном коде оно расчленено и воспринимается как два раздельных слова.
Строка 54: Строка 74:
В [[интерпретатор|интерпретируемых]] языках обфусцированный код занимает меньше места, чем исходный, и зачастую выполняется быстрее, чем исходный. Современные обфускаторы также заменяют константы числами, оптимизируют код инициализации [[индексный массив|массивов]], и выполняют другую оптимизацию, которую на уровне исходного текста провести проблематично или невозможно.
В [[интерпретатор|интерпретируемых]] языках обфусцированный код занимает меньше места, чем исходный, и зачастую выполняется быстрее, чем исходный. Современные обфускаторы также заменяют константы числами, оптимизируют код инициализации [[индексный массив|массивов]], и выполняют другую оптимизацию, которую на уровне исходного текста провести проблематично или невозможно.


Проблема уменьшения размера важна, например, при программировании для [[сотовый телефон|сотовых телефонов]] на [[J2ME]], где размер программы серьёзно ограничен. Обфускация JavaScript уменьшает размер [[HTML]]-файлов и, соответственно, ускоряет загрузку.
Проблема уменьшения размера была важна, например, при программировании для [[сотовый телефон|сотовых телефонов]] на [[J2ME]], где размер программы серьёзно ограничен. Обфускация JavaScript уменьшает размер [[HTML]]-файлов и, соответственно, ускоряет загрузку.

=== Защита проприетарного программного обеспечения ===
Защита исходного кода от редактирования в целях получения выгоды.


== Недостатки ==
== Недостатки ==
Строка 62: Строка 85:


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


=== Недостаточная безопасность ===
=== Недостаточная безопасность ===
Строка 68: Строка 91:


=== Ошибки в обфускаторах ===
=== Ошибки в обфускаторах ===
Современный обфускатор — сложный программный комплекс. Зачастую в обфускаторы, несмотря на тщательное [[проектирование программного обеспечения|проектирование]] и [[Тестирование программного обеспечения|тестирование]], вкрадываются ошибки. Так что есть ненулевая вероятность, что прошедший через обфускатор код вообще не будет работать или быдет работать не так , или так что лучше бы не работал. И чем сложнее разрабатываемая программа, тем больше эта вероятность.
Современный обфускатор — сложный программный комплекс. Зачастую в обфускаторы, несмотря на тщательное [[проектирование программного обеспечения|проектирование]] и [[Тестирование программного обеспечения|тестирование]], вкрадываются ошибки. Так что есть ненулевая вероятность, что прошедший через обфускатор код вообще не будет работать. И чем сложнее разрабатываемая программа, тем больше эта вероятность.


=== Вызов класса по имени ===
=== Вызов класса по имени ===
Большинство языков с промежуточным кодом могут создавать или вызывать [[Объект (программирование)|объекты]] по именам их [[Класс (программирование)|классов]]. Современные обфускаторы позволяют сохранить указанные классы от переименования, однако подобные ограничения сокращают гибкость программ.
Большинство языков с промежуточным кодом может создавать или вызывать [[Объект (программирование)|объекты]] по именам их [[Класс (программирование)|классов]]. Современные обфускаторы позволяют сохранить указанные классы от переименования, однако подобные ограничения сокращают гибкость программ.


== См. также ==
== См. также ==
Строка 79: Строка 102:
* [[Спагетти-код]]
* [[Спагетти-код]]
* [[Самомодифицирующийся код]]
* [[Самомодифицирующийся код]]
* [[IOCCC]]
* {{iw|Dotfuscator}}
* {{iw|Dotfuscator}}


Строка 91: Строка 115:
* [https://xakep.ru/2007/04/10/37614/ Декоративная обфускация PERL-кода: JAPH] Журнал «Хакер», 10 апреля 2007 года
* [https://xakep.ru/2007/04/10/37614/ Декоративная обфускация PERL-кода: JAPH] Журнал «Хакер», 10 апреля 2007 года
* [http://www.cise.ufl.edu/research/ParallelPatterns/PatternLanguage/Background/Psychology/CognitiveModel.htm Tim Mattson, A Cognitive Model for Programming, UF CISE]
* [http://www.cise.ufl.edu/research/ParallelPatterns/PatternLanguage/Background/Psychology/CognitiveModel.htm Tim Mattson, A Cognitive Model for Programming, UF CISE]
* [https://dl.acm.org/doi/10.1145/2160158.2160159 On the (im)possibility of obfuscating programs] Журнал «ACM», май 2012 года


[[Категория:Исследование программ]]
[[Категория:Исследование программ]]

Текущая версия от 16:32, 22 декабря 2024

Обфуска́ция (от лат. obfuscare — затенять, затемнять; и англ. obfuscate — делать неочевидным, запутанным, сбивать с толку) или запутывание кода — приведение исходного кода или исполняемого кода программы к виду, сохраняющему её функциональность, но затрудняющему анализ, понимание алгоритмов работы и модификацию при декомпиляции.

«Запутывание» кода может осуществляться как на уровне наименований компонентов программы, так и на уровне алгоритмов программы. Для создания запутанного ассемблерного текста могут использоваться специализированные компиляторы, использующие неочевидные или недокументированные возможности среды исполнения программы. Существуют также специальные программы, производящие обфускацию, называемые обфускаторами (англ. obfuscator).

Цели обфускации

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

Технологии

[править | править код]

На уровне исходных текстов

[править | править код]

На JavaScript, VBScript и подобных скрипт-языках пользователю доступен исходный текст программы. В этом случае форматированием текста и заменой имён можно сделать текст менее читаемым.

Исходный текст на языке C:

  int COUNT = 100;
  float TAX_RATE = 0.2;
  for (int i=0; i<COUNT; i++)
  {
    tax[i] = orig_price[i] * TAX_RATE;
    price[i] = orig_price[i] + tax[i];
  }

Код после обфускации[1]:

  for(int a=0;a<100;a++){b[a]=c[a]*0.2;d[a]=c[a]+b[a];}

Более сложный пример:

char*M,A,Z,E=40,J[40],T[40];main(C){for(*J=A=scanf(M="%d",&C);
--            E;             J[              E]             =T
[E   ]=  E)   printf("._");  for(;(A-=Z=!Z)  ||  (printf("\n|"
)    ,   A    =              39              ,C             --
)    ;   Z    ||    printf   (M   ))M[Z]=Z[A-(E   =A[J-Z])&&!C
&    A   ==             T[                                  A]
|6<<27<rand()||!C&!Z?J[T[E]=T[A]]=E,J[T[A]=A-Z]=A,"_.":" |"];}

На уровне машинного кода

[править | править код]

Как правило, обфускация на уровне машинного кода увеличивает время выполнения программы. Поэтому она применяется в критичных к безопасности, но не критичных к скорости местах программы, таких как проверка регистрационного кода[2].

Простейший способ обфускации машинного кода — вставка в него недействующих конструкций (таких как or ax, ax).

На уровне промежуточного кода

[править | править код]

В отличие от обычных языков программирования, таких как C++ или Паскаль, компилирующихся в машинный код, язык Java, NetP и языки платформы .NET компилируют исходный код в промежуточный код (байт-код), который содержит достаточно информации для адекватного восстановления исходного кода. По этой причине для этих языков применяется обфускация промежуточного кода.

Назначение

[править | править код]

Усложнение исследования кода

[править | править код]

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

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

Простейший пример обфусцированного HTML:

<b>Маш</b><b>ина</b>

При просмотре пользователь увидит слово «Машина», в то время как в исходном коде оно расчленено и воспринимается как два раздельных слова.

Оптимизация

[править | править код]

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

Проблема уменьшения размера была важна, например, при программировании для сотовых телефонов на J2ME, где размер программы серьёзно ограничен. Обфускация JavaScript уменьшает размер HTML-файлов и, соответственно, ускоряет загрузку.

Защита проприетарного программного обеспечения

[править | править код]

Защита исходного кода от редактирования в целях получения выгоды.

Недостатки

[править | править код]

Потеря гибкости кода

[править | править код]

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

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

Недостаточная безопасность

[править | править код]

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

Ошибки в обфускаторах

[править | править код]

Современный обфускатор — сложный программный комплекс. Зачастую в обфускаторы, несмотря на тщательное проектирование и тестирование, вкрадываются ошибки. Так что есть ненулевая вероятность, что прошедший через обфускатор код вообще не будет работать. И чем сложнее разрабатываемая программа, тем больше эта вероятность.

Вызов класса по имени

[править | править код]

Большинство языков с промежуточным кодом может создавать или вызывать объекты по именам их классов. Современные обфускаторы позволяют сохранить указанные классы от переименования, однако подобные ограничения сокращают гибкость программ.

Примечания

[править | править код]
  1. В данном случае это можно назвать минификацией
  2. 10.2. Методы проверки регистрационных кодов. www.rfcmd.ru. Дата обращения: 2 февраля 2016. Архивировано 12 декабря 2016 года.

Литература

[править | править код]
  • Бойцев О. М. Защити свой компьютер на 100% от вирусов и хакеров. — Питер, 2008. — ISBN 9785388003478.