Beskytt Flash-filer fra decompilers ved hjelp Encryption

Protect Din Flash-filer fra decompilers ved hjelp av kryptering
4
Del
10
Del

Denne Cyber ​​Monday Envato Tuts + kurs vil bli redusert til bare $ 3. Ikke gå glipp av.

To ganger i måneden, vi besøker noen av våre lesere favoritt innlegg fra hele historien Activetuts +. Denne opplæringen ble første gang publisert i februar 2010.


I denne opplæringen vil jeg vise en teknikk jeg bruker for å beskytte koden og eiendeler fra tyveri.


decompilers er en reell bekymring for folk som lager Flash-innhold. Du kan legge mye arbeid i å lage det beste spillet der ute, så noen kan stjele den, må du bytte logo og satte den på sitt nettsted uten å spørre deg. Hvordan? Ved hjelp av en Flash Decom. Med mindre du legger litt beskyttelse over din SWF det kan decompiled med et trykk på en knapp og decom vil produksjonen lesbar kildekode.



Før vi begynner

Jeg brukte et lite prosjekt av meg å demonstrere hvor sårbare SWF skal dekompilering. Du kan laste det ned og teste deg selv via link kilde ovenfor. Jeg brukte Sothink SWF Decom 5 til dekompilere SWF og se under panseret sitt. Koden er ganske lesbar og du kan forstå og bruke det ganske enkelt.



Hva kan vi gjøre med det?

Jeg kom opp med en teknikk for å beskytte SWF fra decompilers og jeg 'm kommer til å vise det i denne opplæringen. Vi bør være i stand til å produsere dette:

Den koden som decompiled faktisk er koden for å dekryptere innholdet og har ingenting å gjøre med din viktigste koden. I tillegg navnene er ulovlig, så det ikke vil kompilere tilbake. Prøv å dekompilere det selv.

Før vi kommer i gang, ønsker jeg å påpeke at denne opplæringen er ikke egnet for nybegynnere, og du bør ha solid kunnskap om AS3 hvis du ønsker å følge med. Denne opplæringen er også om lavt nivå programmering som involverer bytes, ByteArrays og manipulere SWF-filer med en hex editor

Her er hva vi trenger.

  • En SWF å beskytte. Føl deg fri til å laste ned SWF jeg skal jobbe på.
  • Flex SDK. Vi skal bruke den til å legge inn innhold ved hjelp av Embed koden. Du kan laste det ned fra opensource.adobe.com.
  • En hex editor. Jeg skal bruke en gratis editor heter Hex-Ed. Du kan laste det ned fra nielshorn.net eller du kan bruke en redaktør av ditt valg.
  • En decompiler. Mens det er ikke nødvendig, det ville være fint å sjekke om vår beskyttelse faktisk fungerer. Du kan hente en prøveversjon av Sothink SWF Decom fra sothink.com


    Trinn 1: Legg SWF på Runtime

    Åpne en ny Actionscript 3.0-prosjektet, og sette den til å kompilere med Flex SDK (jeg bruker FlashDevelop å skrive kode). Velg en SWF du ønsker å beskytte og legge det som binære data ved hjelp av Embed koden: product: [Embed (kilde = "VerletCloth.swf", mimetype = "application /octet-stream")] //kilde = banen til swf du vil protectprivate Var innhold: Klasse;

    Nå SWF er innebygd som en ByteArray
    inn i loader SWF og det kan legges gjennom Loader.loadBytes ()
    <. br> Var loader: Loader = new Loader (); addChild (loader); loader.loadBytes (nytt innhold (), ny LoaderContext (falsk, ny ApplicationDomain ()));

    Til slutt skal vi ha denne koden:
    pakke {import flash.display.Loader; import flash.display.Sprite; import flash.system.ApplicationDomain; import flash.system.LoaderContext; [SWF (width = 640, height = 423)] //dimensjonene bør være samme som lastet swf offentlige class Hoved strekker Sprite {[Bygg (kilde = "VerletCloth.swf", mimetype = "application /octet-stream") ] //source = bane til swf du ønsker å beskytte private Var innhold: Klasse; offentlig funksjon main (): void {var loader: Loader = new Loader (); addChild (loader); loader.loadBytes (nytt innhold (), ny LoaderContext (falsk, ny ApplicationDomain ())); }}}

    Utarbeide og se om det fungerer (det skal). Fra nå av vil jeg kalle den innebygde SWF den "beskyttet SWF", og SWF vi bare kompilert "loading SWF"



    Trinn 2:. Analyser resultatet

    La oss prøve å dekompilere og se om det fungerer.

    Yey! Eiendelene og den opprinnelige koden er borte! Hva er det vist nå er koden som laster beskyttet SWF og ikke innholdet. Dette vil trolig stoppe mesteparten av førstegangs angripere som ikke er så kjent med Flash, men det er fortsatt ikke god nok til å beskytte ditt arbeid fra dyktige angripere fordi beskyttet SWF venter på dem urørt inne i laste SWF.



    Trinn 3: dekomprimere SWF

    La oss åpne laste SWF med en hex-editor:

    Det skal se ut som tilfeldige binære data fordi det er komprimert, og det bør begynne med ASCII "CWS ". Vi trenger å dekomprimere den! (Hvis SWF begynner med "FWS" og du ser menings strenger i SWF det er sannsynlig at det ikke blir komprimert. Du må aktivere komprimering for å følge med).

    Først det kan høres vanskelig, men det er ikke. SWF-formatet er et åpent format, og det er et dokument som beskriver det. Last den ned fra adobe.com og bla ned til side 25 i dokumentet. Det er en beskrivelse av header og hvordan SWF er komprimert, slik at vi kan pakke det enkelt.

    Hva er skrevet der er at de første 3 bytes en signatur (CWS eller FWS), er neste byte Flash-versjonen, de neste 4 byte er størrelsen på SWF. De resterende er komprimert hvis signaturen er CWS eller ukomprimert hvis signaturen er FWS. La oss skrive en enkel funksjon for å dekomprimere en SWF:
    privat funksjon dekomprimere (data: ByteArray): ByteArray {var overskriften: ByteArray = new ByteArray (); Var komprimert: ByteArray = new ByteArray (); Var dekomprimert: ByteArray = new ByteArray (); header.writeBytes (data, 3, 5); //lese ukomprimert header eksklusiv signatur compressed.writeBytes (data, 8); //lese resten, komprimert compressed.uncompress (); decompressed.writeMultiByte ("FWS", "oss-ascii"); //mark som ukomprimerte decompressed.writeBytes (header); //skrive overskriften tilbake decompressed.writeBytes (komprimert); //skriver nå ukomprimert innhold retur dekomprimert;}

    Funksjonen gjør et par ting:.


      Den leser den ukomprimerte header (de første 8 bytes) uten signaturen og husker det

      Den leser resten av dataene og uncompresses det.

      Det skriver tilbake header (med "FWS" signatur) og ukomprimerte data, skape en ny, ukomprimert SWF.



      Trinn 4: Opprette et Utility

      Neste vi vil skape et praktisk verktøy i Flash for å komprimere og dekomprimere SWF-filer. I et nytt AS3 prosjekt, kompilere følgende klassen som et dokument klasse:
      pakke {import flash.display.Sprite; import flash.events.Event; import flash.net.FileFilter; import flash.net.FileReference; import flash.utils.ByteArray; public class Kompressor strekker Sprite {private Var ref: FileReference; offentlig funksjon Kompressor () {ref = new FileReference (); ref.addEventListener (Event.SELECT, last); ref.browse ([new Filefilter ("SWF-filer", "* .swf")]); } Private funksjon belastning (e: Hendelses): void {ref.addEventListener (Event.COMPLETE, processSWF); ref.load (); } Private funksjon processSWF (e: Hendelses): void {var swf: ByteArray; bryteren (ref.data.readMultiByte (3, "us-ascii")) {case "CWS": swf = dekomprimere (ref.data); gå i stykker; case "FWS": swf = komprimere (ref.data); gå i stykker; Standard: kaste Feil ("Not SWF ..."); gå i stykker; } Ny FileReference () spare (SWF).; } Private funksjon komprimere (data: ByteArray): ByteArray {var overskriften: ByteArray = new ByteArray (); Var dekomprimert: ByteArray = new ByteArray (); Var komprimert: ByteArray = new ByteArray (); header.writeBytes (data, 3, 5); //leser overskriften, eksklusive signatur decompressed.writeBytes (data, 8); //leser resten decompressed.compress (); compressed.writeMultiByte ("CWS", "oss-ascii"); //mark som komprimerte compressed.writeBytes (header); compressed.writeBytes (dekomprimert); returnere komprimert; } Private funksjon dekomprimere (data: ByteArray): ByteArray {var overskriften: ByteArray = new ByteArray (); Var komprimert: ByteArray = new ByteArray (); Var dekomprimert: ByteArray = new ByteArray (); header.writeBytes (data, 3, 5); //lese ukomprimert header eksklusiv signatur compressed.writeBytes (data, 8); //lese resten, komprimert compressed.uncompress (); decompressed.writeMultiByte ("FWS", "oss-ascii"); //mark som ukomprimerte decompressed.writeBytes (header); //skrive overskriften tilbake decompressed.writeBytes (komprimert); //skriver nå ukomprimert innhold retur dekomprimert; }}}

      Som du sikkert lagt merke til har jeg lagt til 2 ting:. Fil lasting og komprimere funksjon

      komprimere funksjonen er identisk med den dekomprimere funksjon, men i revers. Filen lasting er gjort ved hjelp FileReference (FP10 nødvendig) og lastet filen er enten komprimert eller ukomprimert. Merk at du må kjøre SWF lokalt fra en frittstående spiller, som FileReference.browse ()
      må påberopes av brukermedvirkning (men den lokale frittstående spiller gjør det mulig å kjøre den uten).



      Trinn 5: Pakke laste SWF

      For å teste verktøyet, fyre den opp, velg lasting SWF og velge hvor du vil lagre det. Deretter åpner det opp med en hex editor og kratt gjennom. Du skal se ascii strenger inne som dette:



      Trinn 6: Analyser Igjen

      La oss gå tilbake til trinn 2. Mens decom viste ingen nyttig info om beskyttede SWF , er det ganske lett å få SWF fra nå ukomprimert loader; bare søk etter signaturen "CWS" (hvis den beskyttede SWF er ukomprimert søk etter "FWS") og se resultatene:

      Det vi har funnet er en DefineBinaryData tag som inneholder beskyttet SWF, og trekke det derfra er en bit av kaken. Vi er i ferd med å legge et lag av beskyttelse over laste SWF. Encryption



      Trinn 7: Kryptering

      For å gjøre det beskyttede SWF mindre "tilgjengelig" vi vil legge til noen form for kryptering. Jeg valgte å bruke as3crypto og du kan laste den ned fra code.google.com. Du kan bruke alle bibliotek du ønsker i stedet (eller din egen gjennomføring, enda bedre), er det eneste kravet at det bør være i stand til å kryptere og dekryptere binære data ved hjelp av en nøkkel



      Trinn 8:. Kryptering data

      Det første vi vil gjøre er å skrive et verktøy for å kryptere beskyttet SWF før vi legger det inn. Det krever svært grunnleggende kunnskap om as3crypto biblioteket, og det er ganske grei. Legg biblioteket inn i biblioteket ditt banen og la oss begynne ved å skrive følgende:
      Var aes: AESKey = new AESKey (binKey); Var bytesToEncrypt: int = (data.length & ~ 15); //sørge for at det kan deles med 16, null de siste fire bytesfor (var i: int = 0; i < bytesToEncrypt, jeg + = 16) aes.encrypt (data, i);

      Hva skjer her? Vi bruker en klasse fra as3crypto kalt AESKey å kryptere innholdet. Klassen krypterer 16 bytes i en tid (128-bit), og vi må for-loop over dataene til å kryptere alt. Legg merke til den andre linjen: data.length & ~ 15. Det gjør at antall byte kryptert kan deles med 16 og vi ikke går tom for data når du ringer aes.encrypt ()

      Merk:. Det er viktig å forstå poenget med kryptering i dette tilfellet. Det er egentlig ikke kryptering, men heller tåkelegging siden vi har nøkkelen inne i SWF. Hensikten er å slå data i binær søppel, og koden ovenfor gjør den jobben, selv om det kan la opp til 15 ukrypterte byte (som ikke betyr noe i vårt tilfelle). Jeg er ikke en kodeknekkeren, og jeg er ganske sikker på at koden ovenfor kunne se halt og svake fra en kodeknekk perspektiv, men som jeg sa det er ganske irrelevant som vi inkluderer nøkkelen inne i SWF.


      < h2> Trinn 9: Kryptering Utility

      Tid for å skape en annen verktøy som vil hjelpe oss å kryptere SWF-filer. Det er nesten det samme som kompressoren vi opprettet tidligere, så jeg vil ikke snakke så mye om det. Kompilere den i et nytt prosjekt som et dokument klasse:
      pakke {import com.hurlant.crypto.symmetric.AESKey; import flash.display.Sprite; import flash.events.Event; import flash.net.FileReference; import flash.utils.ByteArray; public class Encryptor strekker Sprite {private Var nøkkel: String = "activetuts"; //Jeg hardkodet nøkkelen private Var ref: FileReference; offentlig funksjon Encryptor () {ref = new FileReference (); ref.addEventListener (Event.SELECT, last); ref.browse (); } Private funksjon belastning (e: Hendelses): void {ref.addEventListener (Event.COMPLETE, kryptere); ref.load (); } Private funksjon kryptere (e: Hendelses): void {var data: ByteArray = ref.data; Var binKey: ByteArray = new ByteArray (); binKey.writeUTF (nøkkel); //AESKey krever binære nøkkelen Var aes: AESKey = new AESKey (binKey); Var bytesToEncrypt: int = (data.length & ~ 15); //sørge for at det kan deles med 16, null de siste 4 byte for (var i: int = 0; i < bytesToEncrypt; i + = 16) aes.encrypt (data, i); . ny FileReference () lagrer (data); }}}

      Nå kjører den, og lage en kryptert kopi av den beskyttede SWF ved å velge den første og deretter lagre den under et annet navn



      Trinn 10:. Endre Loader

      Gå tilbake til laste SWF prosjektet. Fordi innholdet er nå kryptert må vi endre lasting SWF og legge dekryptering kode inn i den. Ikke glem å endre src i Embed koden til å peke på den krypterte SWF
      pakke {import com.hurlant.crypto.symmetric.AESKey.; import flash.display.Loader; import flash.display.Sprite; import flash.system.ApplicationDomain; import flash.system.LoaderContext; import flash.utils.ByteArray; [SWF (width = 640, height = 423)] //dimensjonene bør være samme som lastet swf offentlige class Hoved strekker Sprite {[Bygg (kilde = "VerletClothEn.swf", mimetype = "application /octet-stream") ] //source = bane til swf du ønsker å beskytte private Var innhold: Klasse; private Var nøkkel: String = "activetuts"; offentlig funksjon main (): void {var data: ByteArray = nytt innhold (); Var binKey: ByteArray = new ByteArray (); binKey.writeUTF (nøkkel); //AESKey krever binære nøkkelen Var aes: AESKey = new AESKey (binKey); Var bytesToDecrypt: int = (data.length & ~ 15); //sørge for at det kan deles med 16, null de siste 4 byte for (var i: int = 0; i < bytesToDecrypt; i + = 16) aes.decrypt (data, i); Var loader: Loader = new Loader (); addChild (loader); loader.loadBytes (data, ny LoaderContext (falsk, ny ApplicationDomain ())); }}}

      Dette er det samme som før, bortsett fra med dekryptering kode fast i midten. Nå kompilere lasting SWF og teste om det fungerer. Hvis du har fulgt nøye opp til nå, det beskyttede SWF bør laste og vise uten feil



      Trinn 11:. Look Inside Ved hjelp av en Decom

      Åpne den nye laste SWF med en decompiler og ta en titt.

      Den inneholder over tusen linjer med tøff jakt krypteringskode, og det er trolig vanskeligere å få den beskyttede SWF ut av det. Vi har lagt til noen flere trinn angriperen må påta seg.


        Han (eller hun) har til å finne den DefineBinaryData som holder kryptert innhold og pakke det

        Han må skape et verktøy for å dekryptere den.

        Problemet er at det å skape et verktøy er så enkelt som kopi-lime fra decom inn koden redaktør og tilpasse koden litt. Jeg prøvde å bryte min beskyttelse meg selv, og det var ganske enkelt - jeg klarte å gjøre det i ca 5 minutter. Så vi er nødt til å ta noen målinger mot det



        Trinn 12:. String Obfuscation

        Først vil vi sette beskyttet SWF inn i laste SWF, så krypteres det , og nå vil vi sette siste hånd til laste SWF. Vi vil endre navn på klasser, funksjoner og variabler til ulovlige navn

        Ved å si ulovlige navn
        jeg mener navn som,;.!@@, # ^ Og (^ _ ^). Det kule er at dette er viktig for kompilatoren, men ikke til Flash Player. Når kompilatoren møter ulovlige tegn inne identifikatorer, mislykkes det å analysere dem og dermed prosjektet ikke klarer å kompilere. På den annen side, gjør spilleren ikke har noen problemer med disse ulovlige navn. Vi kan kompilere SWF med juridiske identifikatorer, dekomprimere den og gi dem nytt navn til en haug med meningsløse ulovlige symboler. Den decom vilje utgang ulovlig kode og angriperen blir nødt til å gå over de hundrevis av linjer med kode manuelt, fjerner ulovlige identifikatorer før han kan kompilere den. Han fortjener det

        Dette er hvordan det ser ut før noen streng tåkelegging:

        La oss starte! Dekomprimere lasting SWF bruke verktøyet vi laget før og fyre opp en hex editor



        Trinn 13:. Din første Obfuscation

        La oss prøve å endre navn på dokumentet klassen. Antar du har forlatt det opprinnelige navnet (Main), la oss søke etter den i ukomprimert loader SWF med en hex-editor:

        Gi nytt navn " Hoved
        " til ;;;;
        . Nå søke etter andre "hoved" s og gi dem nytt navn til ;;;;
        også.

        Når døpe være sikker på at du ikke endre navn på unødvendige strenger eller SWF vil ikke kjøre.

        Lagre og kjøre SWF. Det fungerer! Og se hva decom sier:

        Victory !! :)



        Trinn 14: Gi nytt navn til resten av klassene

        Hold døpe resten av klassene. Velg en klasse navn og søk etter den, erstatte den med ulovlige tegn til du kommer til slutten av filen. Som jeg sa, er det viktigste her å bruke sunn fornuft, sørg for at du ikke rotet ditt SWF opp. Etter døpe klassene kan du begynne å endre navnet pakkene. Merk at når døpe en pakke, kan du slette perioder også, og gjøre det en lang ulovlig pakkenavn. Se hva jeg har gjort:

        Når du er ferdig døpe klassene og pakkene, kan du begynne å endre navnet funksjoner og variabler. De er enda enklere å endre navn som de vanligvis vises bare en gang, i en stor sky. Igjen, sørg for at du endre navn bare "dine" metoder og ikke den innebygde blitsen metoder. Pass på at du ikke tørke ut nøkkelen ("activetuts" i vårt tilfelle)



        Trinn 15:. Komprimer SWF

        Når du er ferdig døpe ville du sannsynligvis ønsker å komprimere SWF så det vil være mindre i størrelse. Ikke noe problem, kan vi bruke komprimering verktøyet vi laget før, og det vil gjøre jobben. Kjøre verktøyet, velger SWF og lagre det under et annet navn



        Konklusjon:. Ha en siste titt

        Åpne den en siste gang og ta en titt. Klassene, variablene og metodenavn er uklar og det beskyttede SWF er et sted inne, kryptert. Denne teknikken kan være treg til å bruke i starten, men etter et par ganger det tar bare noen få minutter.

        For en stund siden jeg laget en automatisk verktøyet til å injisere den beskyttede SWF for meg inn i laste SWF, og det fungerte fint. Det eneste problemet er at hvis det kan injiseres ved hjelp av en automatisk verktøyet, kan det dekrypteres ved hjelp av et annet verktøy, så hvis angriperen gjør et verktøy for at han vil få all din SWF lett. På grunn av dette har jeg foretrekker å beskytte SWF manuelt hver gang, og legger til en liten endring slik at det ville være vanskeligere å automatisere.

        En annen fin anvendelse av teknikken er Domain låsing
        . I stedet for å dekryptere SWF med en konstant streng kan du dekryptere den med domenet SWF kjører på. Så i stedet for å ha en hvis setningen å sjekke domenet, kan du innføre en mer effektiv måte å beskytte SWF fra emisjonen på andre nettsteder.

        Siste ting, kan det være lurt å bytte ut krypteringskoden med din egen implementering . Hvorfor? Vi investerte innsats i å gjøre krypteringskoden ulovlig, men koden vi bruker er fra en populær åpen kildekode bibliotek og angriperen kunne gjenkjenne det som sådan. Han vil laste ned en ren kopi, og alle tåkelegging arbeidet er gjengitt unødvendig. På den annen side vil bruke din egen implementering krever ham til å fikse alle de ulovlige navnene før han kan fortsette.



        Andre Beskyttelse Metoder

        Fordi SWF tyveri er et stort problem i Flash verden, finnes det andre muligheter for å beskytte SWF. Det finnes mange programmer der ute for å obfuscate AS på Bytecode nivå (som Kindisoft sin secureSWF). De rotet opp den kompilerte bytecode og når Decomforsøk til utgangskode det vil mislykkes, og med krasje noen ganger. Selvfølgelig er dette beskyttelse er bedre når det gjelder sikkerhet, men det koster $$$, så før du velger hvordan du beskytter SWF vurdere hvor mye sikkerheten som trengs. Hvis det handler om å beskytte en proprietær algoritme din 50-ansatt Flash studio har utviklet for de siste to år, kan du vurdere noe bedre da døpe variablene. På den annen side hvis du ønsker å hindre at ungene fra å sende inn falske rekordene du kan vurdere å bruke denne teknikken.

        Det jeg liker med denne teknikken er at det beskyttede SWF blir stående urørt når løp. AS obfuscation tukler med bytekode, og det kan muligens skade SWF og forårsake feil (selv om jeg ikke har møtt noen selv).

        Det er alt for i dag, håper du likte den opplæringen og lært noe nytt! Hvis du har noen spørsmål du gjerne slippe en kommentar.