Uklarhed (software) - Obfuscation (software)

I softwareudvikling er tilsløring den bevidste handling med at skabe kilde- eller maskinkode, der er vanskelig for mennesker at forstå. Ligesom uklarhed i naturligt sprog kan det bruge unødvendigt rundkøringsudtryk til at sammensætte udsagn. Programmerere kan bevidst sløre kode for at skjule dens formål ( sikkerhed gennem uklarhed ) eller dens logik eller implicitte værdier, der er indlejret i den, primært for at forhindre manipulation, afskrække reverse engineering eller endda skabe et puslespil eller rekreativ udfordring for nogen, der læser kilden kode. Dette kan gøres manuelt eller ved hjælp af et automatiseret værktøj, sidstnævnte er den foretrukne teknik i industrien.

Oversigt

Nogle sprogs arkitektur og egenskaber kan gøre dem lettere at skjule end andre. C , C ++ , og Perl programmeringssprog er nogle eksempler på sprog let til obfuscate. Haskell (programmeringssprog) er også ganske uklar, på trods af at den er ganske anderledes i struktur.

De egenskaber, der gør et sprog uklart, er ikke umiddelbart indlysende.

Rekreativ obfuscation

At skrive og læse skjult kildekode kan være en hjerne -teaser . En række programmeringskonkurrencer belønner den mest kreativt skjulte kode, f.eks. International Obfuscated C Code Contest og Obfuscated Perl Contest .

Typer af obfuscations omfatter simpel substitution af søgeord, brug eller ikke-brug af whitespace til at skabe kunstneriske effekter og selvgenererende eller stærkt komprimerede programmer.

Ifølge Nick Montfort kan teknikker omfatte:

  1. navngivning af obfuscation, som omfatter navngivning af variabler på en meningsløs eller vildledende måde;
  2. data/kode/kommentar forvirring, som omfatter at få en egentlig kode til at ligne kommentarer eller forvirre syntaks med data;
  3. dobbeltkodning, som kan vise kode i poesiform eller interessante former.

Korte tilslørede Perl -programmer kan bruges i underskrifter fra Perl -programmører. Disse er JAPH'er (" Bare endnu en Perl -hacker ").

Eksempler

Dette er et vindende bidrag fra International Obfuscated C Code Contest skrevet af Ian Phillipps i 1988 og efterfølgende reverse engineering af Thomas Ball.

/*
  LEAST LIKELY TO COMPILE SUCCESSFULLY:
  Ian Phillipps, Cambridge Consultants Ltd., Cambridge, England
*/

#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);}

Det er et C -program, der, når det kompileres og køres, genererer de 12 vers af The 12 Days of Christmas . Den indeholder alle de strenge, der kræves til digtet i en kodet form inden for koden.

Et ikke-vindende bidrag fra samme år, dette næste eksempel illustrerer kreativ brug af mellemrum; det genererer labyrinter af vilkårlig længde:

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,"_.":" |"];}

ANSI-kompatible C-kompilatorer tillader ikke, at konstante strenge overskrives, hvilket kan undgås ved at ændre "*M" til "M [3]" og udelade "M =".

Følgende eksempel af Óscar Toledo Gutiérrez, Best of Show-posten i det 19. IOCCC , implementerer en 8080- emulator komplet med terminal og diskcontroller , der kan starte CP/M-80 og køre CP/M-applikationer:

#include <stdio.h>
           #define n(o,p,e)=y=(z=a(e)%16 p x%16 p o,a(e)p x p o),h(
                                #define s 6[o]
             #define p z=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 )):((
                  #define 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 C S 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 m x=64&x?*c++:a(x),
                         #define A(F)=fopen((F),"rb+")
                    unsigned char 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; e,V,v,u,x,y,z,Z; main(r,U)char**U;{

     { { { } } }       { { { } } }       { { { } } }       { { { } } }
    { { {   } } }     { { {   } } }     { { {   } } }     { { {   } } }
   { { {     } } }   { { {     } } }   { { {     } } }   { { {     } } }
   { { {     } } }   { { {     } } }   { { {     } } }   { { {     } } }
   { { {     } } }   { { {     } } }   { { {     } } }   { { {     } } }
    { { {   } } }    { { {     } } }    { { {   } } }    { { {     } } }
      { { ; } }      { { {     } } }      { { ; } }      { { {     } } }
    { { {   } } }    { { {     } } }    { { {   } } }    { { {     } } }
   { { {     } } }   { { {     } } }   { { {     } } }   { { {     } } }
   { { {     } } }   { { {     } } }   { { {     } } }   { { {     } } }
   { { {     } } }   { { {     } } }   { { {     } } }   { { {     } } }
    { { {   } } }     { { {   } } }     { { {   } } }     { { {   } } }
     { { { } } }       { { { } } }       { { { } } }       { { { } } }

                                   for(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 S 2 S 6 S 2 S 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 S 4 S 6 S 8 S 8 S 6 S 2 S 2 S 12)?x/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||read(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,write(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|Q>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|x 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,r-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))));
system("stty cooked echo"); B((B((V?B(V):0,u)),v)); }

//print("Hello world")

Et eksempel på en JAPH :

@P=split//,".URRUU\c8R";@d=split//,"\nrekcah xinU / lreP rehtona tsuJ";sub p{
@p{"r$p","u$p"}=(P,P);pipe"r$p","u$p";++$p;($q*=2)+=$f=!fork;map{$P=$P[$f^ord
($p{$_})&6];$p{$_}=/ ^$P/ix?$P:close$_}keys%p}p;p;p;p;p;map{$p{$_}=~/^[P.]/&&
close$_}%p;wait until$?;map{/^r/&&<$_>}%p;$_=$d[$q];sleep rand(2)if/\S/;print

Dette viser langsomt teksten "Bare endnu en Perl / Unix -hacker", flere tegn ad gangen, med forsinkelser.

Nogle Python -eksempler findes i den officielle FAQ om programmering af Python og andre steder.

Fordele ved tilsløring

Hurtigere indlæsningstid

De scripts, der bruges af websider, skal sendes over netværket til den brugeragent, der vil køre dem. Jo mindre de er, jo hurtigere downloades. I sådanne brugstilfælde kan minificering (en relativt triviel form for tilsløring) give reelle fordele.

Reduceret hukommelsesforbrug

I antikke fortolkede sprog i løbetid (mere almindeligt kendt som script ), som ældre versioner af BASIC, eksekverede programmer hurtigere og tog mindre RAM, hvis de brugte navne på enkelt bogstaver, undgik kommentarer og indeholdt kun nødvendige tomme tegn (kort sagt, jo kortere jo hurtigere).

Beskyttelse af forretningshemmeligheder

Hvor kildekoden for et program skal sendes til brugeren, f.eks. JavaScript på en webside, er enhver forretningshemmelighed, licensmekanisme eller anden intellektuel ejendomsret indeholdt i programmet tilgængelig for brugeren. Forvirring gør det sværere at forstå koden og foretage ændringer af den.

Desktop -programmer indeholder undertiden funktioner, der hjælper med at skjule deres kode. Nogle programmer gemmer muligvis ikke hele koden på disken og trækker muligvis en del af deres binære kode via internettet ved runtime. De kan også bruge komprimering og/eller kryptering og tilføje yderligere trin til demonteringsprocessen.

Forebyggelse af omgåelse

At skjule programmet kan i sådanne tilfælde gøre det sværere for brugerne at omgå licensmekanismer eller indhente oplysninger, programmets leverandør ønskede at skjule. Det kan også bruges til at gøre det sværere at hacke multiplayer -spil.

Forebyggelse af virussøgning

Ondsindede programmer kan bruge tilsløring til at skjule, hvad de virkelig gør. De fleste brugere læser ikke engang sådanne programmer; og dem, der typisk har adgang til softwareværktøjer, der kan hjælpe dem med at fortryde tilsløret, så denne strategi har begrænset effekt.

Ulemper ved tilsløring

  • Selvom tilsløring kan gøre læsning, skrivning og reverse-engineering et program svært og tidskrævende, vil det ikke nødvendigvis gøre det umuligt.
  • Det tilføjer tid og kompleksitet til byggeprocessen for udviklerne.
  • Det kan gøre fejlfindingsproblemer, efter at softwaren er blevet tilsløret ekstremt vanskelig.
  • Når koden bliver abandonware og ikke længere vedligeholdes, vil hobbyister måske beholde programmet, tilføje mods eller forstå det bedre. Obfuscation gør det svært for slutbrugere at gøre nyttige ting med koden.
  • Visse former for tilsløring (dvs. kode, der ikke bare er en lokal binær og downloader mini -binære filer fra en webserver efter behov) kan forringe ydeevnen og/eller kræve internet.

Dekompilatorer

En decompiler kan reverse-manipulere kildekoden fra en eksekverbar eller et bibliotek. Dekompilering kaldes undertiden et menneske-ved-slut-angreb, baseret på det traditionelle kryptografiske angreb kendt som " mand-i-midten ". Det lægger kildekoden i brugerens hænder, selvom denne kildekode ofte er vanskelig at læse. Kildekoden har sandsynligvis tilfældige funktioner og variabelnavne, forkerte variabeltyper og bruger anden logik end den originale kildekode (på grund af kompilatoroptimeringer).

Kryptografisk tilsløring

For nylig har kryptografer udforsket ideen om at skjule kode, så koden er omvendt manipuleret kryptografisk . Dette er formaliseret i de mange forslag til uoverskuelighed , en kryptografisk primitiv, der, hvis det er muligt at bygge sikkert, ville give en mulighed for at konstruere mange andre former for kryptografi, herunder helt nye typer, som ingen ved, hvordan man laver. (En stærkere forestilling, black-box obfuscation , blev vist umulig i 2001, da forskere konstruerede programmer, der ikke kan sløres i denne forestilling.)

Underretter brugere om skjult kode

Nogle antivirusprogrammer, f.eks. AVG AntiVirus , vil også advare deres brugere, når de lander på et websted med kode, der er skjult manuelt, da et af formålene med tilsløring kan være at skjule ondsindet kode. Nogle udviklere anvender dog muligvis kodeklumpning med det formål at reducere filstørrelse eller øge sikkerheden. Den gennemsnitlige bruger forventer muligvis ikke, at deres antivirussoftware giver advarsler om et ellers harmløst stykke kode, især fra betroede virksomheder, så en sådan funktion kan faktisk afskrække brugere fra at bruge legitim software.

Visse større browsere som Firefox og Chrome tillader også browserudvidelser, der indeholder tilsløret kode.

Skjulte software

Der findes en række forskellige værktøjer til at udføre eller hjælpe med kodelægning. Disse inkluderer eksperimentelle forskningsværktøjer skabt af akademikere, hobbyværktøjer, kommercielle produkter skrevet af fagfolk og open source-software . Deobfuscation -værktøjer findes også, der forsøger at udføre den omvendte transformation.

Selvom størstedelen af ​​kommercielle obfuscation-løsninger fungerer ved at transformere enten programkildekode eller platformuafhængig bytecode som brugt af Java og .NET, er der også nogle, der fungerer direkte på kompilerede binære filer.

Obfuscation og copyleft licenser

Der har været debat om, hvorvidt det er ulovligt at lukke copyleft -softwarelicenser ved at frigive kildekode i uklar form, f.eks. I tilfælde, hvor forfatteren er mindre villig til at stille kildekoden til rådighed. Problemet behandles i GNU General Public License ved at stille den "foretrukne formular til ændring" til rådighed. GNU -webstedet siger, at "Skjult 'kildekode' ikke er en egentlig kildekode og tæller ikke som kildekode."

Se også

Noter

Referencer

eksterne links