Маскирање кода

Из Википедије, слободне енциклопедије

Маскирање кода је модификовање програмског кода у циљу смањења читљивости, без губитка функционалности. Примарни циљ маскирања кода је заштита од бесправног копирања и коришћења њега или његових дијелова.

Технике маскирања[уреди]

Уклањање бјелина[уреди]

Тривијалан начин маскирања је уклањање свих уклоњивих бјелина из програмског кода. То укључује све табове, знакове за нови ред и размаке. Тако, на примјер, сљедећи програмски код у програмском језику C:

#include <stdio.h>
 
int main()
{
    int i;
    for (i = 0; i < 10; i++ )
        printf("Zdravo!\n" );
}

добија сљедећи изглед:

#include <stdio.h>
int main(){int i;for(i=0;i<10;i++)printf("Zdravo!\n");}

Мора се примијетити да на одређеним мјестима бјелине нису смјеле бити уклоњене, као између кључне ријечи int и имена промјенљиве i. Због тога је потребно имати нешто сложенији систем уклањања бјелина, напримјер користећи регуларне изразе тако да се уклоне само бјелине које бар са једне стране имају неалфанумеричке знакове (знакове интерпункције, заграде итд.).

Главна мана ове технике маскирања је што се лако отклања, користећи уређиваче програмског кода који имају подршку за аутоматско поравнање текста, или користећи посебне програме за те намјене, на примјер јуниксов програм indent. На тај начин се замаскирани код врло брзо и лако враћа у читљив облик.

Замјена имена промјенљивих[уреди]

Најчешћи начин маскирања се заснива на једноставној замјени имена промјенљивих кратким и неразумљивим именима, тако да је без одговарајуће документације практично немогуће открити алгоритам нетривијалних програма. При овој врсти маскирања је важно бити досљедан у замјени истих имена промјенљивих истим новим именима, као и пазити да се не замјене кључне ријечи датог програмског језика или идентификатори који припадају некој спољној библиотеци која није обухваћена маскирањем. На примјер, сљедећи програмски код, написан у језику Јаваскрипт:

function getAverage(arr )
{
    var sum = 0;
    var i;
    for (i = 0; i < arr.length; i++ )
        sum += arr[i];
    var result = sum/arr.length;
    return result;
}

може добити сљедећи изглед:

function ab(ac )
{
    var ad = 0;
    var ae;
    for (ae = 0; ae < ac.length; ae++ )
        ad += ac[ae];
    var af = ad/ac.length;
    return af;
}

Иако је дати примјер врло једноставан, види се да је читљивост маскираног кода знатно мања. Ово нарочито долази до изражаја код програмских кодова веће дужине.

Један од начина остваривања ове технике маскирања је приказан у наредних неколико корака:

  • прављење таблице свих ријечи у програму
  • уклањање ријечи из таблице које не смију бити замијењене (нпр. кључне ријечи (for, while) и идентификатори спољних библиотека (printf, cout, alert итд. у зависности од коришћеног програмског језика)
  • придруживање нових, генеричких, ријечи (попут ab, ac, итд.) табличним ријечима
  • замјена постојећих ријечи у програмском коду новопридруженим генеричким ријечима

Генеричке ријечи се могу формирати на различите начине:

  • пермутацијама слова и цифара дужине 2, 3, итд. (нпр. aa, ab, ac, ... zz, aab, aac, ... zzz, ...)
  • користећи мали број различитих дозвољених знакова, чиме расте дужина кода али се додатно смањује читљивост (нпр. aa, a_, _a, __, aaa, aa_, a_a, a__, _aa, _a_, _a_, ___, aaaa, aaa_ итд.)
  • случајним избором различитих ријечи које саме по себи имају смисао, али није везан за дати алгоритам (нпр. sum, index, i, j, left, right итд. при чему се ниједна од њих не додијели промјенљивој која има тај смисао него случајним избором)

Поред наведених техника, маскирање се постиже спајањем цјелокупног кода у једну датотеку, па чак и измјеном самог алгоритма у циљу мање разумљивости. Најчешће се користи комбинација свих расположивих техника у циљу што квалитетнијег маскирања.

Слиједи чувени примјер замаскираног програма написаног у програмског језику C:

#include <stdio.h>
main(t,_,a)char *a;{return!0<t?t<3?main(-79,-13,a+main(-87,1-_,
main(-86,0,a+1)+a)):1,t<_?main(t+1,_,a):3,main(-94,-27+t,a)&&t==2?_<13?
main(2,_+1,"%s %d %d\n"):9:16:t<0?t<-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#'l \
q#'+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?_==*a?putchar(31[a]):main(-65,_,a+1):main((*a=='/')+t,_,a+1)
  :0<t?main(2,2,"%s"):*a=='/'||main(0,main(-61,*a,
"!ek;dc i@bK'(q)-[w]*%n+r3#l,{}:\nuwloca-O;m .vpbks,fxntdCeghiry"),a+1);}

Овај код, када се преведе и покрене, производи дванаест строфа пјесме која описује дванаест мјесеци у години. Стихови се ваде из велике ниске која представља главнину кода. Маскирање се овде обавило користећи више техника — замјеном имена промјенљивих неразумљивим именима, уклањањем бјелина и коришћењем рекурзивних позива функције main.

Веб програмирање[уреди]

Маскирању кода се у 21. вијеку често прибјегава у веб програмирању, када је дошло до бујања Интернета и када се у већини случајева код мора пренијети клијенту да би се извршио (HTML, Јаваскрипт, CSS, итд.). Тада маскирање кода има вишеструку добробит:

  • дужина програмског кода се смањује чиме се смањује вријеме преноса преко Интернета (што корисници доживљавају као повећање брзине апликације)
  • читљивост се смањује чиме се смањује могућност незаконитог коришћења кода и злонамјерног приступа серверској апликацији ради злоупотребе њених рањивости

Уопштено, то се највише односи на Јаваскрипт, али се може односити и на PHP и друге серверске програмске језике, јер су у већини случајева у питању интерпретерски програмски језици те се скраћењем кода може убрзати интерпретирање кода.

Спољашње везе[уреди]

  • ioccc, Међународно такмичење за најбоље маскиран C кôд