C # non dovrebbe essere necessariamente evitato. Lavoro per PreEmptive Solutions nel loro team Dotfuscator , sebbene questa sia una risposta imparziale. (senza una singola spina :))
C # è intrinsecamente più facile da decompilare nel codice sorgente perché contiene metadati e la maggior parte del codice C # deve rispettare un insieme di regole chiamate "codice verificabile". I decompilatori sfruttano l'aderenza a queste regole insieme ai metadati allegati per rendere la decompilazione molto migliore degli equivalenti decompilatori C ++. È difficile entrare in una conoscenza approfondita dell'IL, ma in pratica ogni classe del tuo codice finirà con l'avere i metadati. È come .Net ti impedisce di spedire i file di intestazione o di simboli affinché qualcuno usi un assembly / API che scrivi. E per il bit di codice verificabile, in pratica significa che è possibile utilizzare solo il codice che il runtime .Net può verificare è "sicuro". Il runtime è limitato nelle sue capacità di analisi statica, quindi c'è un sacco di codice che può essere verificato sia "sicuro e corretto", ma non sarà verificabile dal runtime. I decompilatori approfittano di questo insieme di regole.
Se stai spedendo un prodotto in C # e hai IP che vuoi proteggere, in pratica devi usare un prodotto di offuscamento. È lo stesso in linguaggi / runtime simili come Java. I prodotti di offuscamento per .Net fanno una varietà di cose:
- Obfuscate il flusso di controllo (trasformate le istruzioni in cicli con
goto
e riordinate tutto)
- Inietta le istruzioni inutili per la spazzatura per "nascondere" il codice reale
- Rinominare i metadati, quindi non è di grande aiuto. (trasformando i nomi delle classi come
FooBar
in a
)
- Cambia il modo in cui le classi sono strutturate (spostando 5 metodi in un unico metodo prendendo tutti gli argomenti dai 5 metodi)
- Inietti codice o metadati non verificabili (anche se questo di solito è facilmente sconfitto dagli deobfuscator)
- Cripta le stringhe in modo che non siano solo testo
- Cifra risorse come file di configurazione allegati, pagine XAML, ecc.
- Aggiungi protezione antisabotaggio (rilevamento che l'applicazione è stata modificata)
A seconda di quale offuscatore usi, questi metodi possono renderlo tale per tutti gli effetti e il codice è un'enorme "scatola nera" senza immergersi nell'IL e defondellarlo (molto tempo)
C ++ ha il vantaggio che l'offuscamento non è altrettanto importante. Non ci sono metadati quindi i decompilatori hanno un tempo molto più difficile. Tuttavia, ci sono ancora una grande quantità di hacker in grado di leggere l'assembly x86. E le applicazioni C ++ molto spesso vengono violate. (buono) Gli offuscatori C ++ sono anche molto più difficili da trovare. Questo perché sono tanto difficili da offuscare quanto da decompilare. .Net ha una serie di regole che gli offuscatori usano sia per leggere il tuo codice, sia per offuscarlo. C ++ non ha queste regole.
Quindi, in sintesi
- C # richiede fondamentalmente l'offuscamento
- C ++ è molto più difficile da decompilare, ma manca il supporto per l'offuscamento
- Indipendentemente da quale scegli, è sempre possibile crack . Tutto quello che puoi fare è rallentarlo o renderlo indesiderabile da rompere a causa della quantità di tempo richiesta
Inoltre, come una nota in più. Gli obfuscator di C # che producono codice verificabile forniscono fondamentalmente un'applicazione che verrà eseguita ovunque, purché disponga di una versione abbastanza nuova di .Net. Gli offuscatori C # che non producono codice verificabile di solito funzionano ovunque, ma non sono garantiti . È possibile che Microsoft esca con qualche ottimizzazione JIT nella prossima versione di .Net che infrangerà il tuo codice non verificabile e offuscato. Il codice C ++ di solito non viene eseguito "ovunque", ma di solito lo fa. Il codice C ++ offuscato funzionerà probabilmente ovunque tu intenda farlo, ma non è garantito. Scrivere un C ++ corretto e sicuro per i thread è abbastanza difficile, e molto meno preoccupante per un obfuscator che lo infastidisce.