gelaagde versluiering: een taxonomie van software versluiering technieken voor gelaagde veiligheid

deze sectie onderzoekt de versluiering technieken voor specifieke code elementen. Deze laag behandelt de meeste publicaties in het gebied van softwareverduistering. Zoals in Fig. 4, volgens welke elementen een obfuscation techniek doelen, we verdelen deze categorie in vijf subcategorieën: obfuscating lay-outs, obfuscating controles, obfuscating dataobfuscating functies, en obfuscating klassen.

Fig. 4
figuur 4

de verduistering technieken van code-element laag

de lay-out

de lay-out verduistert de lay-out van codes of instructies terwijl de originele syntaxis intact blijft. Deze sectie bespreekt vier lay-out verduisteringsstrategieën: nietszeggende classifiers, het strippen van redundante symbolen, het scheiden van gerelateerde codes en junkcodes.

betekenisloze identifiers

deze benadering wordt ook wel lexicale verduistering genoemd, die betekenisvolle identifiers omzet in betekenisloze identifiers. Voor de meeste programmeertalen is het gebruik van betekenisvolle en uniforme naamgevingsregels (bijv. Hongaarse notatie (Simonyi 1999)) vereist als een goede programmeerpraktijk. Hoewel dergelijke namen zijn gespecificeerd in broncodes, zouden sommige in de vrijgegeven software standaard blijven. Bijvoorbeeld, de namen van globale variabelen en functies in C/C++ worden bewaard in binaries, en alle namen van Java zijn gereserveerd in bytecodes. Omdat zulke betekenisvolle namen de analyse van contradictoire programma ‘ s kunnen vergemakkelijken, moeten we ze door elkaar halen. Om de obfuscated identifiers meer verwarrend te maken, stelde Chan and Yang (2004) voor om bewust dezelfde namen te gebruiken voor objecten van verschillende typen of binnen verschillende domeinen. Dergelijke benaderingen zijn aangenomen door ProGuard (2016) als een standaard verduistering regeling voor Java-programma ‘ s.

overtollige symbolen verwijderen

deze strategie verwijdert overbodige symbolische informatie uit vrijgegeven software, zoals de debug-informatie voor de meeste propgrams (laag 1998). Behalve, er zijn andere redundante symbolen voor bepaalde formaten van programma ‘ s. ELF-bestanden bevatten bijvoorbeeld symbolentabellen die de paren van identifiers en adressen registreren. Bij het aannemen van standaard compilatieopties om C/C++ programma ‘ s te compileren, zoals het gebruik van LLVM (Lattner and Adve 2004), bevatten de gegenereerde binaries dergelijke symbooltabellen. Om dergelijke overbodige informatie te verwijderen, kunnen ontwikkelaars gebruik maken van de strip tool van Linux. Een ander voorbeeld met redundante informatie is Android smali codes. Standaard bevatten de gegenereerde smali-codes informatie waarmee is begonnen .lijn en .bron, die kan worden verwijderd voor verduistering doeleinden (Dalla Preda and Maggi 2017).

het scheiden van verwante codes

een programma is gemakkelijker te lezen als de logisch verwante codes ook fysiek dicht bij elkaar liggen (Collberg et al. 1997). Daarom kan het scheiden van verwante codes of instructies de moeilijkheden bij het lezen verhogen. Het is van toepassing op zowel broncodes (bijvoorbeeld herordeningsvariabelen (laag 1998)) als assemblagecodes (bijvoorbeeld herordeningsinstructies (Wroblewski 2002)). In de praktijk is het gebruik van onvoorwaardelijke sprongen om een programma te herschrijven een populaire aanpak om dit te bereiken. Ontwikkelaars kunnen bijvoorbeeld de assemblagecodes schudden en vervolgens Goto gebruiken om de oorspronkelijke controlestroom te reconstrueren (You and Yim 2010). Deze aanpak is populair voor assembly codes en Java bytecodes met de beschikbaarheid van Goto instructies (Dalla Preda en Maggi 2017).

Spamcodes

deze strategie voegt spaminstructies toe die niet functioneel zijn. Voor binaries kunnen we geen-bedieningsinstructies toevoegen (NOP of 0x00) (Dalla Preda and Maggi 2017; Marcelli et al. 2018). Daarnaast kunnen we ook ongewenste methoden toevoegen, zoals het toevoegen van ter ziele gegane methoden in Android smali-codes (Dalla Preda and Maggi 2017). De junk codes kunnen meestal veranderen de handtekeningen van de codes, en daarom ontsnappen statische patroonherkenning.

omdat layout obfuscation niet knoeit met de oorspronkelijke code syntaxis, is het minder gevoelig voor compatibiliteitsproblemen of bugs. Daarom zijn dergelijke technieken in de praktijk de meest favoriete. Bovendien kunnen de technieken van nietszeggende identifiers en het strippen van redundante symbolen de omvang van programma ‘ s verminderen, wat ze verder aantrekkelijk maakt (ProGuard 2016). De kracht van de lay-out verduistering is echter beperkt. Het heeft veelbelovende veerkracht om deobfuscation aanvallen omdat sommige transformaties zijn eenrichtingsverkeer, die niet kan worden teruggedraaid. Echter, sommige lay-out informatie kan nauwelijks worden gewijzigd, zoals de methode identifiers van Java SDK. Dergelijke resterende informatie is essentieel voor tegenstanders om de versluierde informatie te herstellen. Bijvoorbeeld Bichsel et al. (2016) probeerde te deobfuscated ProGuard-versluierd apps, en ze met succes hersteld rond 80% namen.

Obfuscerende besturingselementen

dit type obfuscatietechnieken transformeert de besturingselementen van codes om de complexiteit van het programma te vergroten. Het kan worden bereikt via nep controle stromen, probabilistische controle stromen, dispatcher – gebaseerde controles, en impliciete controles.

valse controlestromen

valse controlestromen verwijzen naar de controlestromen die opzettelijk aan een programma worden toegevoegd maar nooit zullen worden uitgevoerd. Het kan de complexiteit van een programma verhogen, bijv., in McCabe complexity (McCabe 1976) of Harrison metrics (Harrison and Magel 1981). Bijvoorbeeld, McCabe complexiteit (McCabe 1976) wordt berekend als het aantal randen op een control-flow grafiek minus het aantal knooppunten, en dan plus twee keer van de aangesloten componenten. Om de McCabe complexiteit te vergroten, kunnen we ofwel nieuwe randen introduceren of beide nieuwe randen en knooppunten toevoegen aan een verbonden component.

om de onbereikbaarheid van nepcontrolestromen te garanderen, Collberg et al. (1997) stelde het gebruik van ondoorzichtige predicaten voor. Zij definieerden ondoorzichtig voorspellen als het predicaat waarvan de uitkomst tijdens verduisteringstijd bekend is, maar moeilijk is af te leiden door statische programmaanalyse. In het algemeen kan een ondoorzichtig predicaat constant waar (PT), constant onwaar (PF) of contextafhankelijk (P?). Er zijn drie methoden om ondoorzichtige predicaten te maken: numerieke schema ‘s, programmeerschema’ s en contextuele schema ‘ s.

numerieke schema ’s

numerieke schema’ s vormen ondoorzichtige predicaten met wiskundige uitdrukkingen. Bijvoorbeeld, 7×2-1≠y2 is constant waar voor alle gehele getallen x en y. We kunnen dergelijke ondoorzichtige predicaten direct gebruiken om valse controlestromen te introduceren. Figuur 5a toont een voorbeeld, waarin het ondoorzichtige predicaat garandeert dat de nep controlestroom (d.w.z. de Else branch) niet zal worden uitgevoerd. Echter, aanvallers zouden hogere kansen hebben om ze te detecteren als we dezelfde ondoorzichtige predicaten vaak in een versluierd programma gebruiken. Arboit (2002) stelde daarom voor om automatisch een familie van dergelijke ondoorzichtige predicaten te genereren, zodat een obfuscator elke keer een uniek ondoorzichtig predicaat kan kiezen.

Fig. 5
figuur 5

controle-stroom verduistering met ondoorzichtige predicaten

een andere wiskundige benadering met een hogere beveiliging is het gebruik van crypto-functies, zoals hash-functie \(\mathcal {H}\) (Sharif et al. 2008), en homomorfe encryptie (Zhu and Thomborson 2005). We kunnen bijvoorbeeld een predicaat x==C vervangen door \(\mathcal {H}(x)==c_{hash}\) om de oplossing van x voor deze vergelijking te verbergen. Merk op dat een dergelijke aanpak over het algemeen wordt gebruikt door malware om dynamische programma-analyse te ontwijken. We kunnen ook crypto-functies gebruiken om vergelijkingen te versleutelen waaraan niet kan worden voldaan. Echter, dergelijke ondoorzichtige predicaten oplopen veel overhead.

om ondoorzichtige constanten samen te stellen die bestand zijn tegen statische analyse, Moser et al. (2007) stelde het gebruik van 3-SAT problemen, die NP-hard zijn. Dit is mogelijk omdat men efficiënte algoritmen kan hebben om zulke harde problemen samen te stellen (Selman et al. 1996). Tiella and Ceccato (2017) demonstreerden bijvoorbeeld hoe dergelijke ondoorzichtige predicaten met K-kliek problemen te componeren.

om ondoorzichtige constanten samen te stellen die resistent zijn voor dynamische analyse, Wang et al. (2011) voorgesteld om ondoorzichtige predicaten samen te stellen met een vorm van onopgeloste vermoedens die vele malen lus. Omdat lussen uitdagend zijn voor dynamische analyse, moet de benadering in de natuur resistent zijn tegen dynamische analyse. Voorbeelden van dergelijke vermoedens zijn het vermoeden van Collatz, het vermoeden van 5x+1, Het Vermoeden van Matthews. Figuur 5b laat zien hoe het vermoeden van Collatz kan worden gebruikt om valse controlestromen te introduceren. Het maakt niet uit hoe we x initialiseren, het programma eindigt met x=1, en originalCodes() kunnen altijd worden uitgevoerd.

Programmeerschema ’s

omdat analyse van contradictoire programma’ s een grote bedreiging vormt voor ondoorzichtige predicaten, kunnen we uitdagende programmaanalyseproblemen gebruiken om ondoorzichtige predicaten samen te stellen. Colberg et al. voorgesteld twee klassieke problemen, pointer analyse en gelijktijdige programma ‘ s.

in het algemeen heeft de pointeranalyse betrekking op het bepalen of twee pointers naar hetzelfde adres kunnen of kunnen wijzen. Sommige pointer analyse problemen kunnen NP-hard voor statische analyse of zelfs onbeslist (Landi and Ryder 1991). Een ander voordeel is dat pointer operaties zijn zeer efficiënt tijdens de uitvoering. Daarom kunnen ontwikkelaars veerkrachtige en efficiënte ondoorzichtige voorspellingen samenstellen met goed ontworpen pointer analyse problemen, zoals het onderhouden van pointers naar sommige objecten met dynamische datastructuren (Collberg et al. 1998a).

gelijktijdige programma ’s of parallelle programma’ s zijn een andere uitdaging. In het algemeen heeft een parallel gebied van n statements n! verschillende manieren van uitvoering. De uitvoering wordt niet alleen bepaald door het programma, maar ook door de runtime status van een hostcomputer. Colberg et al. (1998a) voorgesteld om gelijktijdige programma ‘ s te gebruiken om de pointer-gebaseerde aanpak te verbeteren door tegelijkertijd de pointers bij te werken. Majumdar and Thomborson (2006) stelde voor om gedistribueerde parallelle programma ‘ s te gebruiken om ondoorzichtige predicaten samen te stellen.

bovendien stellen sommige benaderingen ondoorzichtige predicaten samen met programmeertrucs, zoals het gebruik van mechanismen voor het hanteren van uitzonderingen. Dolz and Parra (2008) stelden bijvoorbeeld voor om het try-catch mechanisme te gebruiken om ondoorzichtige predicaten voor.Net en Java samen te stellen. De uitzondering gebeurtenissen omvatten deling door nul, null pointer, index buiten bereik, of zelfs bepaalde hardware uitzonderingen (Chen et al. 2009). De oorspronkelijke programma semantiek kan worden bereikt via op maat gemaakte exception handling schema ‘ s. Dergelijke ondoorzichtige predicaten hebben echter geen beveiligingsbasis en zijn kwetsbaar voor geavanceerde handgemaakte aanvallen.

contextuele schema ’s

contextuele schema’ s kunnen worden gebruikt om verschillende ondoorzichtige predicaten samen te stellen(d.w.z. {P?}). De predicaten moeten enkele deterministische eigenschappen bevatten, zodat ze kunnen worden gebruikt om programma ‘ s te verduisteren. Bijvoorbeeld, Drape En et al. (2009) voorgesteld om dergelijke ondoorzichtige predicaten samen te stellen die invariant zijn onder een contextuele beperking, bijvoorbeeld, het ondoorzichtige predicaat x mod3==1 is constant waar als x mod3:1?x++: x=x + 3. Palsberg et al. (2000) voorgestelde dynamische ondoorzichtige predicaten, die een opeenvolging van gecorreleerde predicaten bevatten. Het evaluatieresultaat van elk predicaat kan per run verschillen. Zolang de predicaten echter gecorreleerd zijn, is het gedrag van het programma deterministisch. Figuur 5c toont een voorbeeld van dynamische ondoorzichtige predicaten. Het maakt niet uit hoe we *p en *q initialiseren, het programma is gelijk aan y=x+3,x=y+3.

de weerstand van nep-controlestromen hangt voornamelijk af van de veiligheid van ondoorzichtige predicaten. Een ideale beveiliging eigenschap voor ondoorzichtige predicaten is dat ze vereisen worst-case exponentiële tijd te breken, maar alleen polynoom tijd te construeren. Merk op dat sommige ondoorzichtige predicaten zijn ontworpen met dergelijke beveiligingsproblemen, maar kunnen worden geïmplementeerd met gebreken. Bijvoorbeeld, de 3-SAT problemen voorgesteld door Ogiso et al. (2003) zijn gebaseerd op triviale probleeminstellingen die gemakkelijk kunnen worden vereenvoudigd. Als dergelijke ondoorzichtige predicaten correct worden geïmplementeerd, zouden ze veelbelovend zijn om veerkrachtig te zijn.

probabilistische controlestromen

valse controlestromen kunnen problemen veroorzaken voor statische programmaanalyse. Echter, ze zijn kwetsbaar voor dynamische programma-analyse omdat de nep controle stromen inactief zijn. Het idee van probabilistische controlestromen neemt een andere strategie aan om de dreiging aan te pakken (Pawlowski et al. 2016). Het introduceert replicaties van controlestromen met dezelfde semantiek maar verschillende syntaxis. Wanneer het programma meerdere keren dezelfde invoer ontvangt, kan het zich anders gedragen voor verschillende uitvoeringstijden. De techniek is ook nuttig voor het bestrijden van zijkanaalaanvallen (Crane et al. 2015).

merk op dat de strategie van probabilistische controlestromen vergelijkbaar is met nep controlestromen met contextuele ondoorzichtige predicaten. Maar ze zijn verschillend van aard omdat contextuele ondoorzichtige predicaten dode paden introduceren, hoewel ze geen junkcodes introduceren.

besturingselementen op basis van Dispatcher

een besturingselement op basis van dispatcher bepaalt de volgende codes die tijdens de looptijd moeten worden uitgevoerd. Dergelijke controles zijn essentieel voor controle-flow verduistering omdat ze de oorspronkelijke controlestromen kunnen verbergen tegen statische programmaanalyse.

een belangrijke op dispatcher gebaseerde verduisteringsbenadering is het afvlakken van de regelstroom, waarbij codes van diepte worden omgezet in ondiepe codes met meer complexiteit. Wang et al. (2000) in de eerste plaats de aanpak voorgesteld. Figuur 6 toont een voorbeeld uit hun papier dat een while lus transformeert in een andere vorm met switch-case. Om een dergelijke transformatie te realiseren, is de eerste stap om de code om te zetten in een gelijkwaardige representatie met if-then-goto statements zoals weergegeven in Fig. 6; dan wijzigen ze de Goto statements met switch-case statements zoals weergegeven in Fig. 6. Op deze manier wordt de oorspronkelijke programmasemantiek impliciet gerealiseerd door de datastroom van de schakelvariabele te regelen. Omdat de uitvoeringsvolgorde van codeblokken dynamisch wordt bepaald door de variabele, kan men de besturingsstromen niet kennen zonder het programma uit te voeren. Cappaert en Preneel (2010) geformaliseerde control-flow afvlakking als het gebruik van een dispatcher node (bijvoorbeeld, switch) die het volgende code blok uit te voeren; na het uitvoeren van een blok, wordt de controle terug naar de dispatcher node. Bovendien zijn er verschillende verbeteringen aan code-flow afvlakking. Bijvoorbeeld, om de weerstand tegen statische programmaanalyse op de schakelaarvariabele te verbeteren, Wang et al. (2001) voorgesteld om problemen met pointeranalyse in te voeren. Om het programma verder te compliceren, Chow et al. (2001) voorgesteld om valse codeblokken toe te voegen.

Fig. 6
figuur 6

controle-flow afvlakking aanpak voorgesteld door Wang et al. (2000)

László and Kiss (2009) stelden een control-flow afvlakking mechanisme voor om specifieke C++ syntaxis te verwerken, zoals try-catch, while-do, continue. Het mechanisme is gebaseerd op abstracte syntaxis boom en maakt gebruik van een vast patroon van lay-out. Voor elk blok code te verduisteren, het construeert een while statement in de buitenste lus en een switch-case compound binnen de lus. De switch-case compound implementeert de oorspronkelijke programmasemantiek, en de schakelvariabele wordt ook gebruikt om de buitenste lus te beëindigen. Cappaert en Preneel (2010) ontdekten dat de mechanismen kwetsbaar zouden kunnen zijn voor lokale analyse, dat wil zeggen dat de schakelvariabele onmiddellijk zodanig wordt toegewezen dat tegenstanders het volgende blok kunnen afleiden om uit te voeren door alleen in een huidig blok te kijken. Ze stelden een versterkte aanpak voor met verschillende trucs, zoals het gebruik van referentietoewijzing (bijvoorbeeld swVar = swVar+1) in plaats van directe toewijzing (bijvoorbeeld swVar=3), het vervangen van de toewijzing via if-else door een uniforme toewijzingsuitdrukking, en het gebruik van eenrichtingsfuncties bij het berekenen van de opvolger van een basisblok.

naast het afvlakken van de regelstroom zijn er verschillende andere op de dispatcher gebaseerde verduisteringsonderzoeken (bijvoorbeeld (Linn and Debray 2003; Ge et al. 2005; Zhang et al. 2010; Schrittwieser en Katzenbeisser 2011). Linn en Debray (2003) stelden voor om binaries te verduisteren met branch functies die de uitvoering begeleiden op basis van de stack informatie. Ook Zhang et al. (2010) voorgesteld om branch functies te gebruiken om object-georiënteerde programma ‘ s te verduisteren, die een uniforme methode aanroepstijl definiëren met een objectpool. Om de beveiliging van dergelijke mechanismen te verbeteren, Ge et al. (2005) voorgesteld om de controle informatie te verbergen in een ander standalone proces en gebruik maken van Inter-proces communicatie. Schrittwieser en Katzenbeisser (2011) stelden voor om gediversifieerde codeblokken te gebruiken die dezelfde semantiek implementeren.

verduistering op Dispatcher is bestand tegen statische analyse omdat het de regelstroomgrafiek van een softwareprogramma verbergt. Het is echter kwetsbaar voor dynamische programma-analyse of hybride benaderingen. Bijvoorbeeld, Udupa et al. (2005) een hybride benadering voorgesteld om de verborgen controlestromen te onthullen met zowel statische analyse als dynamische analyse.

impliciete regelaars

deze strategie zet expliciete regelinstructies om in impliciete regelinstructies. Het kan reverse engineers hinderen om de juiste besturingsstromen aan te pakken. Zo kunnen we de bedieningsinstructies van montagecodes (bijv. jmp en jne) vervangen door een combinatie van mov en andere instructies die dezelfde besturingssemantiek implementeren (Balachandran en Emmanuel 2011).

merk op dat alle bestaande controle-stroom verduisteringsbenaderingen zich richten op syntactische transformatie, terwijl de bescherming op semantisch niveau zelden is besproken. Hoewel zij enige bestendigheid tegen aanvallen kunnen aantonen, blijft hun verduisteringseffectiviteit met betrekking tot semantische bescherming onduidelijk.

versluiering van gegevens

de huidige technieken voor versluiering van gegevens zijn gericht op gemeenschappelijke gegevenstypen, zoals gehele getallen, tekenreeksen en arrays. We kunnen gegevens transformeren via splitsen, samenvoegen, procedurisatie, codering, enz.

gegevens splitsen / samenvoegen

gegevens splitsen verdeelt de informatie van een variabele in verschillende nieuwe variabelen. Bijvoorbeeld, een Booleaanse variabele kan worden opgesplitst in twee Booleaanse variabelen, en het uitvoeren van logische bewerkingen op hen kan de oorspronkelijke waarde krijgen.

gegevens die daarentegen meerdere variabelen samenvoegen tot één variabele. Colberg et al. (1998b) demonstreerde een voorbeeld dat twee 32-bits gehele getallen samenvoegt in één 64-bits geheel getal. Ertaul and Venkatesh (2005) stelden een andere methode voor die verschillende variabelen in één ruimte verpakt met discrete logaritmen.

gegevensprocedure

gegevensprocedure vervangt statische gegevens door procedureoproepen. Colberg et al. (1998b) voorgesteld om strings te vervangen door een functie die alle strings kan produceren door het specificeren van paiculaire parameterwaarden. Drape En et al. (2004) voorgesteld om numerieke gegevens te coderen met twee inverse functies f en g. Om een waarde v toe te wijzen aan een variabele i, wijzen we deze toe aan een geïnjecteerde variabele j als j=f(v). Om i te gebruiken, roepen we in plaats daarvan g(j) aan.

gegevenscodering

gegevenscodering codeert gegevens met wiskundige functies of cijfers. Ertaul and Venkatesh (2005) stelde voor om strings te coderen met affiene cijfers (bijvoorbeeld Caser cipher) en discrete logaritmen te gebruiken om woorden in te pakken. Fukushima et al. (2008) voorgesteld om de duidelijke getallen te coderen met exclusieve or-bewerkingen en vervolgens het berekeningsresultaat te decoderen voor uitvoer. Kovacheva (2013) voorgesteld om strings te versleutelen met de RC4 cipher en vervolgens decoderen tijdens runtime.

Array transformatie

Array is een meest gebruikte gegevensstructuur. Om arrays te verduisteren, Collberg et al. (1998b) besprak verschillende transformaties, zoals het splitsen van een array in verschillende subarrays, het samenvoegen van verschillende arrays in een array, het vouwen van een array om zijn dimensie te vergroten, of het afvlakken van een array om de dimensie te verminderen. Ertaul and Venkatesh (2005) stelden voor om de array-indices te transformeren met samengestelde functies. Zhu et al. (2006); Zhu (2007) stelde voor om homomorfe encryptie te gebruiken voor array-transformatie, inclusief indexverandering, vouwen en vleien. We kunnen bijvoorbeeld de elementen van een array schudden met i∗m mod n, waarbij i de oorspronkelijke index is, n de grootte van de oorspronkelijke array is, en m en n relatief priemgetal zijn.

Verduisteringsmethoden

methode inline / outline

een methode is een onafhankelijke procedure die door andere instructies van het programma kan worden aangeroepen. Methode inline vervangt de oorspronkelijke procedurele aanroep door het functielichaam zelf. Method outline werkt op de tegenovergestelde manier, die een reeks instructies extraheert en een methode abstraheert. Het zijn goede bedrijven die de oorspronkelijke abstractie van procedures kunnen verdoezelen (Collberg et al. 1997).

Method clone

als een methode zwaar wordt aangeroepen, kunnen we replicaties van de methode maken en er willekeurig een aanroepen. Om tegenstrijdige interpretatie te verwarren, moet elke versie van de replicatie op de een of andere manier uniek zijn, zoals door verschillende verduisteringstransformaties aan te nemen (Collberg et al. 1997) of verschillende handtekeningen (ertaul en Venkatesh 2004).

methode aggregatie / verstrooiing

het idee is vergelijkbaar met dataverduistering. We kunnen irrelevante methoden samenvoegen tot één methode of een methode verspreiden in verschillende methoden (Collberg et al. 1997; laag 1998).

Method proxy

deze benadering creëert proxymethoden om reverse engineering te verwarren. We kunnen de proxies bijvoorbeeld maken als openbare statische methoden met gerandomiseerde identifiers. Er kunnen verschillende proxies zijn voor dezelfde methode (Dalla Preda and Maggi 2017). De aanpak is zeer nuttig wanneer de methode handtekeningen niet kunnen worden gewijzigd (Protsenko and Muller 2013).

Obfuscating classes

Obfuscating classes deelt een aantal soortgelijke ideeën met obfuscating methoden, zoals splitsen en klonen (Collberg et al. 1998b). Omdat class echter alleen bestaat in objectgeoriënteerde programmeertalen, zoals JAVA en.net, bespreken we ze als een unieke categorie. Hieronder presenteren we de belangrijkste strategieën voor het verduisteren van klassen.

Dropping modifiers

objectgeoriënteerde programma ‘ s bevatten modifiers (bijv., publiek, privé) om de toegang tot klassen en leden van klassen te beperken. Dropping modifiers verwijdert dergelijke beperkingen en maken alle leden openbaar (Protsenko and Muller 2013). Deze aanpak kan de implementatie van andere klasse verduisteringsmethoden vergemakkelijken.

splitsing / Coalescentieklasse

het idee van samenvoegen / splitsen is om de intentie van ontwikkelaars te verdoezelen bij het ontwerpen van de klassen (Sosonkin et al. 2003). Bij het samenvoegen van klassen, kunnen we lokale variabelen of lokale instructiegroepen overbrengen naar een andere klasse (Fukushima et al. 2003).

Classhiërarchie afvlakken

Interface is een krachtig hulpmiddel voor objectgeoriënteerde programma ‘ s. Net als methode proxy, kunnen we proxy ‘ s maken voor klassen met interfaces (Sosonkin et al. 2003). Echter, een meer krachtige manier is om de oorspronkelijke overerving relatie tussen klassen met interfaces te breken. Door elk knooppunt van een subboom in de klassenhiërarchie dezelfde interface te laten implementeren, kunnen we de hiërarchie plat maken (Foket et al. 2012).

Geef een antwoord

Het e-mailadres wordt niet gepubliceerd.