
Ofusca compilaciones de Go envolviendo la cadena de herramientas de Go, reemplazando identificadores, rutas de paquetes y datos de posición con hashes y eliminando la información de depuración y compilación.
go install mvdan.cc/garble@latest # or @master
Ofusca el código Go envolviendo la cadena de herramientas de Go. Requiere Go 1.27 o posterior.
garble build [build flags] [packages]
La herramienta también admite garble test para ejecutar pruebas con código ofuscado,
garble run para ofuscar y ejecutar programas simples,
garble reverse para desofuscar texto como trazas de pila,
y garble bug para presentar un informe de error pre-rellenado.
Ejecuta garble -h para ver todos los comandos y flags disponibles.
Producir un binario que funcione tan bien como una compilación normal, pero que tenga la menor información posible sobre el código fuente original.
La herramienta está diseñada para ser:
cmd/go, para admitir módulos y caché de compilaciónLa herramienta envuelve las llamadas al compilador y enlazador de Go para transformar la compilación de Go, con el fin de:
-literals-tinyLa herramienta ofusca todos los paquetes compatibles que se compilan, incluido el runtime estándar.
Los paquetes no compatibles runtime/cgo y crypto/internal/fips140 quedan excluidos.
La ofuscación del runtime sigue los objetivos GOOS/GOARCH compatibles con Go; Garble no
mantiene una lista de arquitecturas permitidas más restrictiva.
Ten en cuenta que comandos como garble build usarán la versión de go encontrada en tu
$PATH. Para usar diferentes versiones de Go, puedes usar GOTOOLCHAIN.
Una pregunta común es por qué se necesita un ofuscador de código para Go, un lenguaje compilado. Los binarios de Go incluyen una cantidad sorprendente de información sobre el código fuente original; incluso con la información de depuración y las tablas de símbolos eliminadas, muchos nombres y posiciones permanecen en su lugar por el bien de las trazas, la reflexión y la depuración.
Algunos casos de uso de Go requieren compartir un binario de Go con el usuario final. Si el código fuente del binario es privado o requiere una compra, su ofuscación puede ayudar a disuadir la ingeniería inversa.
Un caso de uso similar es una biblioteca de Go cuyo código fuente es privado o comprado. Dado que las bibliotecas de Go no se pueden importar en forma binaria, y los plugins de Go tienen sus deficiencias, compartir código fuente ofuscado se convierte en una opción. Consulta #369.
La ofuscación también puede ayudar con aspectos totalmente ajenos a las licencias.
Por ejemplo, el flag -tiny puede hacer que los binarios sean un 15% más pequeños,
similar a la práctica común en Android para reducir el tamaño de las aplicaciones.
La ofuscación también ha ayudado a algunos desarrolladores de código abierto a sortear
análisis antivirus que tratan incorrectamente los binarios de Go como malware.
Usar el flag -literals hace que las expresiones literales, como las cadenas, se
reemplacen con expresiones más complejas, que se resuelven al mismo valor en tiempo de ejecución.
Los literales de cadena inyectados mediante -ldflags=-X también se reemplazan con este flag.
Esta característica es opcional, ya que puede provocar ralentizaciones según el código de entrada.
Los literales usados en expresiones constantes no se pueden ofuscar, ya que se
resuelven en tiempo de compilación. Esto incluye cualquier expresión que forme parte de una
declaración const, por ejemplo.
Ten en cuenta que este proceso se puede revertir con suficiente esfuerzo; consulta #984.
Con el flag -tiny, se elimina aún más información del binario de Go.
La información de posición se elimina por completo, en lugar de ofuscarse.
Se elimina el código del runtime que imprime pánicos, errores fatales e información de traza/depuración.
Muchos nombres de símbolos también se omiten de las secciones del binario en tiempo de enlazado.
En conjunto, esto puede hacer que los binarios sean aproximadamente un 15% más pequeños.
Con este flag, nunca se imprimirán pánicos ni errores fatales del runtime, pero
aún se pueden manejar internamente con recover de forma normal.
Ten en cuenta que este flag puede dificultar la depuración de fallos, ya que un pánico simplemente
saldrá de todo el programa sin imprimir una traza de pila, y se eliminan las posiciones del código
fuente y muchos nombres.
De manera similar, garble reverse generalmente no es útil en este modo.
Consulta: CONTROLFLOW.md
garble build debería tardar aproximadamente el doble que go build, ya que necesita
completar dos compilaciones. La compilación original, para poder cargar y verificar tipos del
código de entrada, y luego la compilación ofuscada.
Garble ofusca un paquete a la vez, reflejando cómo Go compila un paquete
a la vez. Esto permite que Garble admita completamente la caché de compilación de Go; las llamadas
incrementales a garble build solo deberían recompilar y reofuscar el código modificado.
Ten en cuenta que la primera llamada a garble build puede ser comparativamente lenta,
ya que tiene que ofuscar cada paquete por primera vez. Esto es similar a limpiar
GOCACHE con go clean -cache y ejecutar un go build desde cero.
Garble también hace uso de su propia caché para reutilizar trabajo, de forma similar a GOCACHE de Go.
Por defecto usa un directorio dentro del directorio de caché de tu usuario,
como ~/.cache/garble, y se puede ubicar en otro lugar estableciendo GARBLE_CACHE.
Al igual que Go, las compilaciones de garble son deterministas y reproducibles por naturaleza.
Esto tiene beneficios significativos, como poder cachear compilaciones y poder usar
garble reverse para desofuscar trazas de pila.
Por defecto, garble ofuscará cada paquete de una manera única, que cambiará si cambia su entrada de compilación: la versión de garble, la versión de Go, el código fuente del paquete, o cualquier parámetro de compilación como GOOS o -tags. Esto es un valor predeterminado razonable, ya que adivinar esas entradas es muy difícil.
Puedes usar el flag -seed para proporcionar tu propia semilla de aleatoriedad de ofuscación.
Reutilizar la misma semilla puede ayudar a producir la misma ofuscación de código,
lo que puede ayudar al depurar o reproducir problemas.
Rotar regularmente la semilla también puede ayudar contra la ingeniería inversa a largo plazo,
ya que de lo contrario uno puede observar cambios en cómo se ofusca la biblioteca estándar de Go
para adivinar cuándo se cambiaron las versiones de Go o garble a lo largo de una serie de compilaciones.
Para usar siempre una semilla diferente en cada compilación, usa -seed=random.
Ten en cuenta que se debe tener especial cuidado al usar semillas personalizadas:
si se pierde un valor -seed usado en una compilación, garble reverse no funcionará.
La mayoría de estas pueden mejorar con el tiempo y el esfuerzo. El propósito de esta sección es documentar las deficiencias actuales de esta herramienta.