
Offusca le build Go avvolgendo la toolchain Go, sostituendo identificatori, percorsi dei pacchetti e dati di posizione con hash e rimuovendo le informazioni di debug e di build.
go install mvdan.cc/garble@latest # or @master
Offusca il codice Go eseguendo il wrapping della toolchain di Go. Richiede Go 1.27 o successivo.
garble build [build flags] [packages]
Lo strumento supporta anche garble test per eseguire i test con codice offuscato,
garble run per offuscare ed eseguire programmi semplici,
garble reverse per de-offuscare testo come gli stack trace,
e garble bug per inviare una segnalazione di bug precompilata.
Esegui garble -h per vedere tutti i comandi e i flag disponibili.
Produrre un binario che funzioni bene quanto una build regolare, ma che contenga quante meno informazioni possibili sul codice sorgente originale.
Lo strumento è progettato per essere:
cmd/go, per supportare i moduli e la cache di buildLo strumento esegue il wrapping delle chiamate al compilatore e al linker di Go per trasformare la build di Go, al fine di:
-literals-tinyLo strumento offusca tutti i package supportati che vengono compilati, incluso il runtime standard.
I package non supportati runtime/cgo e crypto/internal/fips140 sono esclusi.
L'offuscamento del runtime segue i target GOOS/GOARCH supportati da Go; Garble non
mantiene una allowlist di architetture più restrittiva.
Nota che comandi come garble build useranno la versione di go trovata nel tuo
$PATH. Per usare versioni diverse di Go, puoi usare GOTOOLCHAIN.
Una domanda comune è perché serva un offuscatore di codice per Go, un linguaggio compilato. I binari Go includono una quantità sorprendente di informazioni sul sorgente originale; anche rimuovendo le informazioni di debug e le tabelle dei simboli, molti nomi e posizioni rimangono al loro posto per via di trace, reflection e debug.
Alcuni casi d'uso di Go richiedono di condividere un binario Go con l'utente finale. Se il codice sorgente del binario è privato o richiede un acquisto, il suo offuscamento può aiutare a scoraggiare il reverse engineering.
Un caso d'uso simile è una libreria Go il cui sorgente è privato o acquistato. Poiché le librerie Go non possono essere importate in forma binaria, e i plugin Go hanno i loro difetti, condividere codice sorgente offuscato diventa un'opzione. Vedi #369.
L'offuscamento può anche aiutare con aspetti del tutto estranei alle licenze.
Ad esempio, il flag -tiny può rendere i binari più piccoli del 15%,
in modo simile alla pratica comune su Android per ridurre le dimensioni delle app.
L'offuscamento ha anche aiutato alcuni sviluppatori open source a aggirare
scansioni antivirus che trattavano erroneamente i binari Go come malware.
Usare il flag -literals fa sì che espressioni letterali come le stringhe vengano
sostituite con espressioni più complesse, che si risolvono nello stesso valore a run-time.
Anche i letterali stringa iniettati tramite -ldflags=-X vengono sostituiti da questo flag.
Questa funzionalità è opt-in, poiché può causare rallentamenti a seconda del codice di input.
I letterali usati in espressioni costanti non possono essere offuscati, poiché vengono
risolti in fase di compilazione. Questo include, ad esempio, qualsiasi espressione facente parte di una
dichiarazione const.
Nota che questo processo può essere invertito con sufficiente impegno; vedi #984.
Con il flag -tiny, ancora più informazioni vengono rimosse dal binario Go.
Le informazioni di posizione vengono rimosse del tutto, invece di essere offuscate.
Il codice del runtime che stampa panic, errori fatali e informazioni di trace/debug viene rimosso.
Molti nomi di simboli vengono anche omessi dalle sezioni del binario in fase di link.
Nel complesso, questo può rendere i binari circa il 15% più piccoli.
Con questo flag, non verranno mai stampati panic o errori fatali del runtime, ma possono
comunque essere gestiti internamente con recover come al solito.
Nota che questo flag può rendere più difficile il debug dei crash, poiché un panic
terminerà semplicemente l'intero programma senza stampare uno stack trace, e le posizioni
nel codice sorgente e molti nomi vengono rimossi.
Allo stesso modo, garble reverse in genere non è utile in questa modalità.
Vedi: CONTROLFLOW.md
garble build dovrebbe richiedere circa il doppio del tempo di go build, poiché deve
completare due build. La build originale, per poter caricare ed effettuare il type-check del
codice di input, e poi la build offuscata.
Garble offusca un package alla volta, rispecchiando il modo in cui Go compila un package
alla volta. Questo permette a Garble di supportare pienamente la cache di build di Go; le chiamate
incrementali a garble build dovrebbero ricompilare e ri-offuscare solo il codice modificato.
Nota che la prima chiamata a garble build potrebbe essere relativamente lenta,
poiché deve offuscare ogni package per la prima volta. È simile a svuotare
GOCACHE con go clean -cache ed eseguire una go build da zero.
Garble utilizza anche una propria cache per riutilizzare il lavoro, in modo simile alla GOCACHE di Go.
Per impostazione predefinita usa una directory sotto la directory cache del tuo utente,
come ~/.cache/garble, e può essere collocata altrove impostando GARBLE_CACHE.
Proprio come Go, le build di garble sono deterministiche e riproducibili per natura.
Questo ha vantaggi significativi, come la cache delle build e la possibilità di usare
garble reverse per de-offuscare gli stack trace.
Per impostazione predefinita, garble offuscherà ogni package in modo univoco, che cambierà se cambia il suo input di build: la versione di garble, la versione di Go, il codice sorgente del package, o qualsiasi parametro di build come GOOS o -tags. Questo è un default ragionevole, poiché indovinare quegli input è molto difficile.
Puoi usare il flag -seed per fornire il tuo seed di casualità per l'offuscamento.
Riutilizzare lo stesso seed può aiutare a produrre lo stesso offuscamento del codice,
il che può aiutare durante il debug o la riproduzione di problemi.
Ruotare regolarmente il seed può anche aiutare contro il reverse engineering a lungo termine,
poiché altrimenti si potrebbero osservare i cambiamenti nel modo in cui la libreria standard di Go viene offuscata
per indovinare quando le versioni di Go o garble sono cambiate in una serie di build.
Per usare sempre un seed diverso per ogni build, usa -seed=random.
Nota che bisogna prestare particolare attenzione quando si usano seed personalizzati:
se un valore -seed usato in una build viene perso, garble reverse non funzionerà.
La maggior parte di queste può migliorare con il tempo e l'impegno. Lo scopo di questa sezione è documentare le attuali limitazioni di questo strumento.