Ridenominazione dei simboli
Babel Obfuscator può rinominare namespace, tipi, metodi, proprietà, eventi e campi, rendendo difficile il reverse engineering. Per impostazione predefinita usa caratteri ASCII per la ridenominazione, ma puoi scegliere Unicode per ottenere simboli ancora meno leggibili.
Babel rinomina automaticamente i simboli interni, ma non quelli visibili ad altri assembly. I simboli privati e interni vengono quindi rinominati, mentre i membri pubblici e protetti restano invariati, a meno che non applichi regole personalizzate che ne impongano la ridenominazione.
Tieni presente che rinominare i simboli pubblici può compromettere l’interfaccia pubblica del componente, perché il codice esterno può dipendere dai nomi specifici di quei simboli. In genere è consigliabile non rinominare i simboli visibili all’esterno e concentrarsi invece sull’offuscamento dei dettagli interni dell’implementazione.
Se un simbolo non è destinato a essere usato dall’esterno, va dichiarato come internal: così non è visibile fuori dall’assembly e non fa parte dell’interfaccia pubblica.
Riducendo a internal la visibilità dei tipi pubblici puoi aumentare il numero complessivo di membri offuscati, preservando comunque l’interfaccia pubblica del componente.
Configurare la ridenominazione dei simboli
Puoi configurare la ridenominazione in Babel Desktop, dalla riga di comando o con il task MSBuild.
Babel Desktop
Per configurare la ridenominazione in Babel Desktop, apri o crea un progetto, seleziona l’assembly sul canvas del progetto e imposta le opzioni nel gruppo Ridenominazione del pannello delle proprietà. Il gruppo contiene le opzioni per tipi e membri (ObfuscateTypes, ObfuscateMethods, ObfuscateProperties, ObfuscateEvents, ObfuscateFields, ObfuscateParameters), l’appiattimento dei namespace (FlattenNamespaces), i nomi Unicode (UnicodeNormalization), la lunghezza e il prefisso dei nomi (NameLength, NamePrefix) e la ridenominazione con overload (OverloadedRenaming). Vedi Progetti di offuscamento per sapere come funzionano i progetti in Babel Desktop.
Riga di comando
Configurare la ridenominazione in Babel Obfuscator dall’interfaccia della riga di comando (CLI) è un modo potente e flessibile per integrare l’offuscamento nel tuo processo di build, se usi script da riga di comando.
Per configurare la ridenominazione in Babel Obfuscator, dal Prompt dei comandi su Windows o dal Terminale su macOS o Linux, spostati nella cartella del tuo progetto e inserisci:
babel myapp.exe --types --methods --properties --events --fields --parametersSostituisci myapp.exe con il nome dell’assembly compilato che vuoi offuscare. Le opzioni della CLI che seguono indicano i tipi di simboli che vuoi rinominare.
Ogni opzione (--types, --methods e così via) abilita la ridenominazione per quella specifica categoria di simboli del tuo assembly. Includendo queste opzioni indichi a Babel Obfuscator di applicare la ridenominazione a tipi, metodi, proprietà, eventi, campi e parametri. Se devi escludere una categoria dalla ridenominazione, usa il prefisso --no con il tipo di simbolo. Per esempio, per disabilitare la ridenominazione dei tipi usa --notypes. Puoi farlo per qualsiasi tipo di simbolo, per scegliere quali elementi vengono offuscati.
Per consultare la guida della riga di comando relativa a una specifica opzione di ridenominazione, inserisci il seguente comando
babel --help typesViene visualizzata la guida dettagliata dell’opzione --types.
Task Babel di MSBuild
Il task Babel di MSBuild integra Babel Obfuscator nel tuo flusso di build e ti dà un controllo dettagliato sulle preferenze di offuscamento. Puoi così indicare con precisione quali elementi del tuo codice vanno offuscati, adattando il processo di offuscamento alle tue esigenze.
<PropertyGroup>
<ObfuscateTypes>true</ObfuscateTypes>
<ObfuscateMethods>true</ObfuscateMethods>
<ObfuscateProperties>true</ObfuscateProperties>
<ObfuscateEvents>true</ObfuscateEvents>
<ObfuscateFields>true</ObfuscateFields>
<ObfuscateParameters>true</ObfuscateParameters>
</PropertyGroup>
<Babel ObfuscateTypes="$(ObfuscateTypes)" ObfuscateMethods="$(ObfuscateMethods)" ObfuscateProperties="$(ObfuscateProperties)" ObfuscateEvents="$(ObfuscateEvents)" ObfuscateFields="$(ObfuscateFields)" ObfuscateParameters="$(ObfuscateParameters)" />Prefisso dei nomi
Babel Obfuscator ti permette di applicare un prefisso a ogni nome di simbolo generato. Puoi specificare il prefisso da applicare a un particolare tipo di simbolo, come tipi, metodi, proprietà, eventi, campi o parametri. Il prefisso si specifica con l’opzione --nameprefix o --prefix seguita dalla stringa desiderata. Puoi inoltre indicare il tipo di simbolo a cui applicare il prefisso con la sintassi —prefix [kind]=[prefix]
Babel accetta il prefisso $name, che durante la ridenominazione viene sostituito con il nome originale del simbolo. Può essere utile per il debug o per individuare problemi dovuti alla ridenominazione.
Riga di comando
babel myapp.exe --prefix xy_ --prefix types=tp_ --prefix fields=m_Per saperne di più sull’opzione della riga di comando per il prefisso dei nomi, inserisci:
babel --help prefixTask Babel di MSBuild
<PropertyGroup>
<NamePrefix>xy_;types=tp_;fields=m_</NamePrefix>
</PropertyGroup>
<Babel NamePrefix="$(NamePrefix)" />Lunghezza dei nomi
In Babel Obfuscator puoi specificare la lunghezza minima dei nomi offuscati generati con l’opzione --namelength seguita dalla lunghezza desiderata. Può essere utile se vuoi che i nomi offuscati abbiano una certa lunghezza. Puoi inoltre indicare il tipo di simbolo a cui applicare la lunghezza dei nomi con la sintassi —namelength [kind]=[value]
Riga di comando
babel myapp.exe --namelength 3 --namelength types=8Per saperne di più sull’opzione della riga di comando per la lunghezza dei nomi, inserisci:
babel --help namelengthTask Babel di MSBuild
<PropertyGroup>
<NameLength>3;types=8</NameLength>
</PropertyGroup>
<Babel NameLength="$(NameLength)" />Set di caratteri Unicode
Babel ti permette di specificare il set di caratteri Unicode da usare per generare i nomi offuscati. Puoi usare valori separati da virgole che indicano caratteri Unicode o intervalli di caratteri, in forma esadecimale, decimale o come carattere.
Riga di comando
babel myapp.exe --unicode 10,13,a-z,0x4E00-0x4FFFPer disabilitare la ridenominazione Unicode, inserisci:
babel myapp.exe --nounicodeTask Babel di MSBuild
<PropertyGroup>
<UnicodeNormalization>10,13,a-z,0x4E00-0x4FFF</UnicodeNormalization>
</PropertyGroup>
<Babel UnicodeNormalization="$(UnicodeNormalization)" />Appiattimento dei namespace
Quando l’appiattimento dei namespace è abilitato, Babel rimuove dall’assembly offuscato tutte le informazioni sui namespace e sposta tutti i tipi rinominati nel namespace globale. Per un attaccante diventa così più difficile capire l’organizzazione del codice e individuare tipi o membri specifici nell’assembly.
Se vuoi, puoi specificare il nome del namespace che Babel userà come contenitore globale per tutti i tipi rinominati.
Nota che in Babel solo i tipi rinominati hanno il nome del namespace aggiornato in base alle impostazioni di appiattimento dei namespace.
Riga di comando
babel myapp.exe --flatns
babel myapp.exe --flatns glbnsPer disabilitare l’appiattimento dei namespace, inserisci:
babel myapp.exe --noflatnsTask Babel di MSBuild
<PropertyGroup>
<FlattenNamespaces>true</FlattenNamespaces>
</PropertyGroup>
<Babel FlattenNamespaces="$(FlattenNamespaces)" />Ridenominazione con overload
La ridenominazione con overload è una tecnica con cui Babel assegna lo stesso nome a metodi con firme diverse, purché le regole di progettazione di .NET Framework lo consentano. Per un attaccante diventa così più difficile capire il codice e sottoporlo a reverse engineering. Inoltre Babel rinomina gli overload anche quando differisce solo il tipo restituito dal metodo, il che rende impossibile decompilare completamente il codice in linguaggi di alto livello come C# e VB.NET, perché questi linguaggi non consentono l’overload sul tipo restituito.
Riga di comando
babel myapp.exe --overloadedPer disabilitare la ridenominazione con overload, inserisci:
babel myapp.exe --nooverloadedTask Babel di MSBuild
<PropertyGroup>
<OverloadedRenaming>true</OverloadedRenaming>
</PropertyGroup>
<Babel OverloadedRenaming="$(OverloadedRenaming)" />Funzioni virtuali
Babel può offuscare le funzioni virtuali rinominandole in modo da preservarne la natura virtuale. Il layout originale della tabella delle funzioni virtuali (vtable) viene quindi mantenuto anche dopo l’offuscamento. È importante perché il programma continui a funzionare correttamente, dato che le funzioni virtuali sono una parte essenziale di molti programmi orientati agli oggetti. Offuscando le funzioni virtuali, Babel rende più difficile per gli attaccanti capire il comportamento del programma e sfruttarne le vulnerabilità.
Riga di comando
babel myapp.exe --virtualsPer disabilitare l’offuscamento delle funzioni virtuali, inserisci:
babel myapp.exe --novirtualsTask Babel di MSBuild
<PropertyGroup>
<VirtualFunctions>true</VirtualFunctions>
</PropertyGroup>
<Babel VirtualFunctions="$(VirtualFunctions)" />Ridenominazione delle variabili locali
Nei metadati .NET i nomi delle variabili locali non sono memorizzati in modo esplicito. I decompilatori li deducono in base a vari fattori. Per esempio, quando il tipo di una variabile è specificato in modo esplicito, come nel caso di
var list1 = new List<string>();il decompilatore può determinare che il nome della variabile è “list1” in base all’istruzione di assegnazione.
In alternativa, i nomi delle variabili locali possono essere caricati dal file Program Database (PDB) dell’assembly. Il file PDB contiene informazioni di debug aggiuntive, compresi i nomi delle variabili, che i decompilatori possono usare per ricostruire i nomi originali.
Per limitare l’esposizione dei nomi delle variabili locali, Babel Obfuscator permette di abilitare la generazione del proxy dinamico per i tipi esterni.
babel myapp.exe --proxy externalQuesta funzionalità racchiude i tipi originali, come List<string>, in tipi proxy che vengono rinominati, nascondendo di fatto i tipi delle variabili.
È essenziale che il decompilatore usato non carichi il file PDB, perché potrebbe così ricostruire i nomi originali delle variabili. Disabilitando il caricamento del PDB o eliminando il file PDB, il decompilatore ha un accesso limitato alle informazioni di debug.
Per una protezione completa del codice dei metodi, è consigliabile abilitare la cifratura del codice ogni volta che è possibile. La cifratura del codice trasforma il codice dei metodi in una forma cifrata, e rende molto più difficile capirlo o modificarlo per chi pratica il reverse engineering, anche se riesce a recuperare i nomi originali delle variabili.