В разработке программного обеспечения , запутывание является преднамеренным актом создания источника или машинного кода , который трудно для людей , чтобы понять. Подобно обфускации в естественном языке , он может использовать ненужные обходные выражения для составления операторов. Программисты могут намеренно запутать код, чтобы скрыть его цель ( безопасность через неясность ) или его логику или неявные значения, встроенные в него, в первую очередь, чтобы предотвратить подделку, сдержать обратное проектирование или даже создать головоломку.или развлекательный вызов для тех, кто читает исходный код. Это можно сделать вручную или с помощью автоматизированного инструмента, последний из которых является предпочтительным методом в промышленности. [1]
Обзор [ править ]
Архитектура и характеристики некоторых языков могут облегчить их запутывание, чем другие. [2] [3] C , [4] C ++ , [5] [6] и язык программирования Perl [7] являются примерами языков, которые легко запутать. Haskell (язык программирования) также довольно запутан [8], несмотря на то, что он сильно отличается по структуре.
Свойства, которые делают язык запутываемым, не сразу очевидны.
Рекреационная обфускация [ править ]
Написание и чтение обфусцированного исходного кода может быть головоломкой . Ряд конкурсов по программированию награждают наиболее творчески запутанный код, например, Международный конкурс запутанного кода C и Конкурс запутанного Perl .
Типы обфускации включают простую замену ключевых слов, использование или неиспользование пробелов для создания художественных эффектов, а также самогенерируемые или сильно сжатые программы.
По словам Ника Монфора , техники могут включать:
- обфускация имен, которая включает бессмысленное или вводящее в заблуждение именование переменных;
- путаница в данных / коде / комментариях, которая включает в себя отображение некоторого фактического кода как комментарии или запутывание синтаксиса с данными;
- двойное кодирование, которое может отображать код в форме стихов или интересных форм. [9]
Короткие запутанные программы Perl могут использоваться в подписях программистов Perl. Это JAPH (« Еще один хакер Perl »). [10]
Примеры [ править ]
Это победившая работа Международного конкурса запутанных кодов C, написанная Яном Филлиппсом в 1988 году [11] и впоследствии реконструированная Томасом Боллом. [12]
/ * НАИМЕНЕЕ ВЕРОЯТНОСТИ ДЛЯ УСПЕШНОГО СОСТАВЛЕНИЯ: Ян Филлипс, Cambridge Consultants Ltd., Кембридж, Англия * /#include <stdio.h>main ( t , _ , a ) char * a ; { возвращение !0 < т ? т < 3 ?main ( -79 , -13 , a + main ( -87 , 1 - _ , main ( -86 , 0 , a + 1 )+ а )) :1 , t < _ ? main ( t + 1 , _ , a ) : 3 ,main ( -94 , -27 + t , a ) && t == 2 ? _ < 13 ?main ( 2 , _ + 1 , "% s% d% d \ n " ): 9 : 16 : т < 0 ? т < -72 ? main ( _ , t , "@n '+, #' / * {} w + / w # cdnr / +, {} r / * de} +, / * {* +, / w {% +, / w # q # n +, / # {l, +, / n {n +, / + # n +, / #; \ # q # n +, / + k #; * +, / 'r:' d * '3,} { w + K w'K: '+} e #'; dq # 'lq #' + d'K #! / + k #; \ q # 'r} eKK #} w'r} eKK {nl]' / # ; # q # n ') {) #} w') {) {nl] '/ + # n'; d} rw 'i; #) {nl]! / n {n #'; \ r {#w 'r nc {nl]' / # {l, + 'K {rw' iK {; [{nl] '/ w # q # \ \ n'wk nw' iwk {KK {nl]! / w {% ' l ## w # 'i;: {nl]' / * {q # 'ld; r'} {nlwb! / * de} 'c ;; \ {nl' - {} rw] '/ +,} # # '*} # nc,', # nw] '/ + kd'+ e} +; \ # 'rdq # w! nr '/')} +} {rl # '{n' ') #}' +} ## (!! / " ) : t <-50 ? _ == * а ? путчар ( 31 [ а ]) :main ( -65 , _ , a + 1 ) : main (( * a == '/' ) + t , _ , a + 1 ) :0 < т ?main ( 2 , 2 , "% s" ) : * a == '/' ||main ( 0 ,main ( -61 , * a , "! ek; dc i @ bK '(q) - [w] *% n + r3 # l, {}: \ n uwloca-O; m .vpbks, fxntdCeghiry" ), a + 1 );}
Это программа на языке C, которая при компиляции и запуске сгенерирует 12 стихов из «12 дней Рождества» . Он содержит все строки, необходимые для стихотворения, в закодированной форме внутри кода.
Этот следующий пример, не выигравший в том же году, иллюстрирует творческое использование пробелов; он генерирует лабиринты произвольной длины: [13]
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 ( "._" ); для (; ( 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 , "_." : "|" ];}
ANSI-совместимые компиляторы C не позволяют перезаписывать константные строки, чего можно избежать, изменив «* M» на «M [3]» и опустив «M =».
Следующий пример, сделанный Оскаром Толедо Гутьерресом, лучшим представителем выставки 19-го IOCCC , реализует эмулятор 8080 в комплекте с терминалом и контроллером диска, способный загружать CP / M-80 и запускать приложения CP / M: [14]
#include <stdio.h> #define n (o, p, e) = y = (z = a (e)% 16 px% 16 po, a (e) pxpo), h ( #define s 6 [o] #define pz = l [d (9)] | l [d (9) +1] << 8,1 <(9 [o] + = 2) || ++ 8 [o] #define Q a (7) #define w 254> ( 9 [o] - = 2) || --8 [o], l [d (9)] = z, l [1 + d (9)] = z >> 8 #define O)): (( # определить b (y & 1? ~ s: s) >> "\ 6 \ 0 \ 2 \ 7" [y / 2] & 1? 0 :( #define S)? (z- = #define a (f) * (( 7 & f) -6? & O [f & 7]: & l [d (5)]) #define CS 5 S 3 #define D (E) x / 8! = 16 + E & 198 + E * 8! = X? #Define B ( C) fclose ((C)) #define q (c + = 2,0 [c-2] | 1 [c-2] << 8) #define mx = 64 & x? * C ++: a (x), #define A (F) = fopen ((F), "rb +") символ без знака o [ 10 ],l [ 78114 ], * c = l , * k = l #define d (e) o [e] + 256 * o [e-1] #define h (l) s = l >> 8 & 1 | 128 & y |! (y & 255) * 64 | 16 & z | 2, y ^ = y >> 4, y ^ = y << 2, y ^ = ~ y >> 1, s | = y & 4 + 64506 ; е , V , v , u , x , y , z , Z ; main ( r , U ) char ** U ; { { { { } } } { { { } } } { { { } } } { { { } } } { { { } } } { { { } } } { { { } } } { { { } } } { { { } } } { { { } } } { { { } } } { { { } } } { { { } } } { { { } } } { { { } } } { { { } } } { { { } } } { { { } } } { { { } } } { { { } } } { { { } } } { { { } } } { { { } } } { { { } } } { { ; } } { { { } } } { { ; } } { { { } } } { { { } } } { { { } } } { { { } } } { { { } } } { { { } } } { { { } } } { { { } } } { { { } } } { { { } } } { { { } } } { { { } } } { { { } } } { { { } } } { { { } } } { { { } } } { { { } } } { { { } } } { { { } } } { { { } } } { { { } } } { { { } } } { { { } } } { { { } } } { { { } } } для ( v A (( u A (( e A (( r -2 ? 0 : ( V A ( 1 [ U ])), "C" ) ), system ( "stty raw -echo min 0" ), fread ( l , 78114 , 1 , e ), B ( e ), «B» )), «A» )); 118 - ( x = * c ++ ); ( y = x / 8 % 8 , z = ( x & 199 ) -4 S 1 S 1 S 186 S 2 S 2 S 3 S 0 , r = ( y > 5 ) * 2 + y , z = ( x & 207 ) -1 с 2 с 6 с 2 с 182 S 4 ) ? D ( 0 ) D ( 1 ) D ( 2 ) D ( 3 ) D ( 4 ) D ( 5 ) D ( 6 ) D ( 7 ) ( z = x -2 C C C C C C C C + 129 S 6 С 4 С 6 С 8 С 8 С 6 S 2 S 2 S 12 ) ? х / 64-1 ? (( 0 O a ( y ) = a ( x ) O 9 [ o ] = a ( 5 ), 8 [ o ] = a ( 4 ) O 237 == * c ++? (( Int ( * ) () ) ( 2 - * c ++? Fwrite: fread )) ( l + * k + 1 [ k ] * 256 , 128 , 1 , ( fseek ( y = 5 [ k ] -1 ? u : v , (( 3 [ k ] | 4 [ k ] << 8 ) << 7 | 2 [ k ]) << 7 , Q = 0 ), y)) : 0 O y = a ( 5 ), z = a ( 4 ), a ( 5 ) = a ( 3 ), a ( 4 ) = a ( 2 ), a ( 3 ) = y , a ( 2 ) = z O c = l + d ( 5 ) O y = l [x = d ( 9 )], z = l [ ++ x ] , x [ l ] = a ( 4 ), l [ - x ] = a ( 5 ), a ( 5 ) = y , a ( 4 ) = z O 2 - * c ? Z || читать ( 0 , & Z ,1 ), 1 & * c ++? Q = Z , Z = 0 : ( Q = !! Z ) : ( c ++ , Q = r = V ? Fgetc ( V ) : -1 , s = s & ~ 1 | r < 0 ) O ++ c , записи ( 1 , & 7 [ O ],1 ) O z = c + 2 - l , w , c = l + q O p , c = l + z O c = l + q O s ^ = 1 O Q = q [ l ] O s | = 1 O q [ l ] = Q O Q = ~ Q O a (5 ) = l [ x = q ] , a ( 4 ) = l [ ++ x ] O s | = s & 16 | 9 < Q % 16 ? Q + = 6 , 16 : 0 , z = s | = 1 & s | В > 159 ? Q + = 96 , 1 : 0, y = Q , h ( s << 8 ) O l [ x = q ] = a ( 5 ), l [ ++ x ] = a ( 4 ) O x = Q % 2 , Q = Q / 2 + s % 2 * 128 , s = s & ~ 1 | х O Q= l [ d ( 3 )] O x = Q / 128 , Q = Q * 2 + s % 2 , s = s & ~ 1 | x O l [ d ( 3 )] = Q O s = s & ~ 1 | 1 и Q , Q = Q / 2 | Q << 7 O Q = l [ d ( 1 )] O s = ~ 1 & s | Q >> 7 , Q = Q * 2 | Q >> 7 O l [ d ( 1 )] = Q O m y n ( 0 , - , 7 ) y ) O m z = 0 , y = Q | =x , h ( y ) O m z = 0 , y = Q ^ = x , h ( y ) O m z = Q * 2 | 2 * x , y = Q & = x , h ( y ) O m Q n ( s % 2 , - , 7 ) y ) O m Q n ( 0 , - , 7 ) y ) O m Q n ( s % 2 , + , 7 ) y ) O m Q n ( 0 , + , 7 ) y ) O z = r -8 ? d ( r + 1 ) : s | Q << 8 , w O p, г- 8 ? o [ r + 1 ] = z , r [ o ] = z >> 8 : ( s = ~ 40 & z | 2 , Q = z >> 8 ) O r [ o ] - || - o [ r -1 ] O a ( 5 ) = z = a ( 5 )+ r [ o ], a ( 4 ) = z = a ( 4 ) + o [ r -1 ] + z / 256 , s = ~ 1 & s | z >> 8 O ++ o [ r + 1 ] || r [ o ] ++ O o [ r + 1 ] = * c ++, r [ o ] = * c ++ O z = c - l , w , c = y * 8 + l O x = q , b z = c - l , w , c = l + x ) O x = q , b c = l + x ) O b p , c= l + z ) O a ( y ) = * c ++ O r = y , x = 0 , a ( r ) n ( 1 , - , y ) s << 8 ) O r = y , x = 0 , a ( r ) n ( 1 , + , y ) s <<8 )))); система ( "stty приготовленное эхо" ); B (( B (( V ? B ( V ) : 0 , u )), v )); }
Пример JAPH :
@P = split // , ".URRUU \ c8R" ; @d = split // , "\ nrekcah xinU / lreP rehtona tsuJ" ; sub p { @p { "r $ p" , "u $ p" } = ( P , P ); труба «р $ п» , «у $ п» ; ++ $ p ; ( $ q * = 2 ) + = $ f =! вилка ; карта { $ P = $ P [ $ f ^ord ( $ p { $ _ }) & 6 ]; $ p { $ _ } = / ^ $ P / ix ? $ P: закрыть $ _ } ключи % p } p ; p ; p ; p ; p ; карта { $ p { $ _ } = ~ /^[P.pting/ && close $ _ } % p ; ждать пока $? ; карта { / ^ r / && <$ _> } % p; $ _ = $ d [ $ q ]; спать rand ( 2 ) если / \ S / ; Распечатать
Это медленно отображает текст «Просто еще один хакер Perl / Unix», несколько символов за раз, с задержками. Объяснение можно найти здесь. [15]
Некоторые примеры Python можно найти в официальном FAQ по программированию Python и в других местах. [16] [17] [18]
Преимущества обфускации [ править ]
Более быстрое время загрузки [ править ]
Сценарии, используемые веб-страницами, должны быть отправлены по сети пользовательскому агенту, который их запускает. Чем они меньше, тем быстрее загрузка. В таких случаях минификация (относительно тривиальная форма обфускации) может дать реальные преимущества.
Уменьшено использование памяти [ править ]
В античное время выполнения интерпретируемых языков (более известный как сценарий ), как более старые версии BASIC, программы выполняются быстрее и взяли меньше памяти , если они использовали имена переменных одного письма, избегали комментариев и содержали только необходимые символы пробела (вкратце, тем короче быстрее).
Защита коммерческой тайны [ править ]
Если исходный код программы должен быть отправлен пользователю, например JavaScript на веб-странице, пользователю доступна любая коммерческая тайна, механизм лицензирования или другая интеллектуальная собственность, содержащаяся в программе. Обфускация затрудняет понимание кода и внесение в него изменений.
Настольные программы иногда включают функции, которые помогают скрыть их код. Некоторые программы могут не хранить весь свой код на диске и могут извлекать часть своего двоичного кода через Интернет во время выполнения. Они также могут использовать сжатие и / или шифрование, добавляя дополнительные шаги к процессу разборки.
Предотвращение обхода [ править ]
В таких случаях обфускация программы может затруднить пользователям обход лицензионных механизмов или получение информации, которую поставщик программы хотел скрыть. Его также можно использовать, чтобы усложнить взлом многопользовательских игр.
Предотвращение обнаружения вирусов [ править ]
Вредоносные программы могут использовать обфускацию, чтобы скрыть то, что они на самом деле делают. Большинство пользователей даже не читают такие программы; и те, у кого обычно есть доступ к программным инструментам, которые могут помочь им отменить обфускацию, поэтому эта стратегия имеет ограниченную эффективность.
Недостатки обфускации [ править ]
- Хотя обфускация может сделать чтение, запись и обратное проектирование программы трудным и трудоемким, она не обязательно сделает это невозможным. [19]
- Это добавляет времени и усложняет процесс сборки для разработчиков.
- Это может значительно затруднить отладку после того, как программное обеспечение было запутано.
- Как только код становится заброшенным и больше не поддерживается, любители могут захотеть поддерживать программу, добавлять моды или лучше понимать ее. Обфускация усложняет конечным пользователям выполнение полезных действий с кодом.
- Определенные виды обфускации (например, код, который не является просто локальным двоичным файлом и при необходимости загружает мини-двоичные файлы с веб-сервера) могут снизить производительность и / или потребовать доступа в Интернет.
Декомпиляторы [ править ]
Декомпилятор может перепроектировать исходный код из исполняемого файла или библиотеки. Декомпиляцию иногда называют атакой «злоумышленник на конце», основанной на традиционной криптографической атаке, известной как « человек посередине ». Он передает исходный код в руки пользователя, хотя этот исходный код часто трудно читать. Исходный код, вероятно, будет иметь случайные имена функций и переменных, неправильные типы переменных и использовать другую логику, чем исходный исходный код (из-за оптимизации компилятора).
Уведомление пользователей обфускации кода [ править ]
Некоторое антивирусное программное обеспечение, такое как AVG AntiVirus , [ необходима цитата ] также будет предупреждать своих пользователей, когда они попадают на веб-сайт с кодом, который вручную запутан, поскольку одной из целей обфускации может быть скрытие вредоносного кода. Однако некоторые разработчики могут использовать обфускацию кода с целью уменьшения размера файла или повышения безопасности. Среднестатистический пользователь может не ожидать, что его антивирусное программное обеспечение будет выдавать предупреждения о безвредном фрагменте кода, особенно от доверенных корпораций, поэтому такая функция может фактически удерживать пользователей от использования законного программного обеспечения.
Некоторые основные браузеры, такие как Firefox и Chrome, также запрещают расширения браузера, содержащие обфусцированный код. [20] [21]
Программное обеспечение для обфускации [ править ]
Существует множество инструментов для выполнения или помощи в обфускации кода. К ним относятся инструменты экспериментального исследования, созданные учеными, инструменты для любителей, коммерческие продукты, написанные профессионалами, и программное обеспечение с открытым исходным кодом . Также существуют инструменты деобфускации, которые пытаются выполнить обратное преобразование.
Хотя большинство коммерческих решений для обфускации работают путем преобразования либо исходного кода программы, либо независимого от платформы байт-кода, который используется в Java и .NET, есть также такие, которые работают непосредственно с скомпилированными двоичными файлами.
Лицензии на обфускацию и авторское лево [ править ]
Были споры о том, является ли незаконным обход лицензий на программное обеспечение с авторским левом путем выпуска исходного кода в обфусцированной форме, например, в случаях, когда автор менее желает сделать исходный код доступным. Проблема решена в Стандартной общественной лицензии GNU , требуя сделать доступной «предпочтительную форму для внесения изменений». [22] На веб-сайте GNU говорится: «Обфусцированный« исходный код »не является настоящим исходным кодом и не считается исходным кодом». [23]
См. Также [ править ]
- Код AARD
- Код спагетти
- Язык только для записи
- Декомпиляция
- Эзотерический язык программирования
- Куайн
- Полиморфный код
- Обфускация оборудования
- Закулисный конкурс Си
- Компилятор исходного кода
- ProGuard (Обфускатор Java)
- Dotfuscator (Обфускатор .Net)
- Управление цифровыми правами
- Обфускация неразличимости
- Украшение исходного кода
Примечания [ править ]
- ^ «Что такое обфускация (обфу)? - Определение с сайта WhatIs.com» . Поиск программного обеспеченияКачество . Проверено 1 февраля 2019 года .
- ^ Бинсток, Эндрю (6 марта 2003). «Обфускация: сокрытие кода от посторонних глаз» . Архивировано из оригинала на 20 апреля 2008 года . Проверено 25 ноября 2013 года .
- ↑ Этвуд, Джефф (15 мая 2005 г.). «Джефф Этвуд, 15 мая 2005 г.» . Codinghorror.com . Проверено 25 ноября 2013 года .
- ^ «Обфускация» . Kenter.demon.nl. Архивировано из оригинала на 4 марта 2016 года . Проверено 25 ноября 2013 года .
- ^ «Учебники по C ++ - Обфусцированный код - Простое введение» . DreamInCode.net . Проверено 25 ноября 2013 года .
- ^ «Учебники по C - Обфусцированный код в C» . 7 июля 2011 . Проверено 25 ноября 2013 года .
- ^ По состоянию на 25 ноября 2013 г., 18:22 по Гринвичу. «Pe (a) rls в линейном шуме» . Perlmonks.org . Проверено 25 ноября 2013 года .
- ^ "Обфускация - Haskell Wiki" . 16 февраля 2006 года. Архивировано 30 августа 2017 года . Проверено 3 марта 2020 года .
- ^ Монфор, Ник. «Обфусцированный код» (PDF) . Архивировано из оригинального (PDF) 24 апреля 2019 года . Проверено 24 ноября 2017 года .
- ^ "JAPH - Просто еще один Perl-хакер" . pm.org . Perl Mongers. Архивировано из оригинального 16 мая 2013 года . Проверено 27 февраля 2015 года .
- ^ "Международные победители обфусцированного кода C 1988 - Наименее вероятно успешная компиляция" . Ioccc.org. Архивировано из оригинала 9 апреля 2009 года . Проверено 25 ноября 2013 года .
- ^ " " Обратное проектирование Двенадцати дней Рождества "Томас Болл" . Research.microsoft.com. Архивировано из оригинального 13 декабря 2007 года . Проверено 25 ноября 2013 года .
- ^ Дон Либес, запутанный C и другие Таинства , John Wiley & Sons, 1993, стр 425. ISBN 0-471-57805-3
- ^ Óscar Toledo Gutiérrez: эмулятор Intel 8080. 19-й IOCCC. Лучшее шоу.
- ^ "Обфусцированная программа Perl" . Perl.plover.com . Проверено 25 ноября 2013 года .
- ^ "Обфускация" Привет, мир! "- Бен Куртович" . benkurtovic.com .
- ^ http://wiki.c2.com/?ObfuscatedPython
- ^ https://code.activestate.com/lists/python-list/16171/ «Первый годовой запутанный контент Python»
- ^ « » Можем ли мы запутать программы? «По Боаз Бараку» . Math.ias.edu. Архивировано из оригинального 23 марта 2016 года . Проверено 25 ноября 2013 года .
- ^ в 05:01, Томас Клэберн в Сан-Франциско 2 октября 2018 г. «Google принимает меры против замаскированного кода в Интернет-магазине Chrome» . www.theregister.co.uk . Проверено 12 ноября 2019 года .
- ^ Cimpanu, Каталин. «Mozilla объявляет о запрете расширений Firefox, содержащих запутанный код» . ZDNet . Проверено 12 ноября 2019 года .
- ^ "Обоснование" предпочтительной формы работы для внесения изменений в ее "язык GPL" . Lwn.net . Проверено 25 ноября 2013 года .
- ^ "Что такое свободные программы?" . gnu.net . Проверено 18 декабря 2014 года .
Ссылки [ править ]
- Сейедхамзе, Джавад, ABCME: новый механизм метаморфизма , 17-я национальная компьютерная конференция, Технологический университет Шарифа, Тегеран, Иран, 2012.
- Б. Барак, О. Гольдрайх, Р. Импальяццо, С. Рудич, А. Сахай, С. Вадхан и К. Янг. «О (Im) возможности запутывания программ» . 21-я ежегодная международная конференция по криптологии , Санта-Барбара, Калифорния, США. Springer Verlag LNCS, том 2139, 2001.
- Матеас, Майкл; Ник Монфор. «Мрачный ящик: обфускация, странные языки и эстетика кода» (PDF) . Труды 6 - го цифрового искусства и культуры конференции, IT Копенгагенский университет, 1-3 декабря 2005 . С. 144–153.
Внешние ссылки [ править ]
- Бесплатный и эффективный обфускатор для JavaScript
- обфускатор JavaScript с открытым исходным кодом для пакетного сценария
- Международный конкурс запутанного кода C
- библиотека обфускации antispy C / C ++ для всех платформ
- Защита кода Java с помощью обфускации кода , ACM Crossroads, выпуск весны 1998 г.
- Защитите свой Java-код - с помощью обфускаторов и не только , апрель 2009 г.
- Dotfuscator in - документация Visual Studio для встроенной обфускации .NET
- Инструменты обфускации для .NET, в MSDN - ресурсы по запутыванию для .NET, в Центре разработчиков Microsoft.
- Можем ли мы запутать программы?
- Юрий Лифшиц. Конспект лекций по обфускации программ (весна 2005 г.)
- Обфускаторы Java в Curlie
- Анализ 12-дневной программы
- Анализ программы создания обфусцированного лабиринта
- Обфусцированная программа Perl с объяснением
- Анализ обфускации кода javascript
- c2: BlackBoxComputation