Skip to content
Obfuscate Go builds
Branch: master
Clone or download
mvdan don't panic with struct pointer anonymous fields
While at it, make the "object of type" code shared and more robust.
Latest commit 5ccf566 Dec 15, 2019
Type Name Latest commit message Commit time
Failed to load latest commit information.
.github make the tool work on Windows, enable tests Dec 9, 2019
testdata/scripts don't panic with struct pointer anonymous fields Dec 15, 2019
.gitattributes start testing on GitHub Actions Dec 9, 2019
.gitignore error if the user forgot -trimpath Dec 8, 2019
LICENSE initial commit Dec 8, 2019 README: mention filenames, and the difficulty with methods Dec 11, 2019
go.mod support type switches with symbolic vars Dec 8, 2019
main.go don't panic with struct pointer anonymous fields Dec 15, 2019
main_test.go make the tool work on Windows, enable tests Dec 9, 2019


GO111MODULE=on go get

Obfuscate a Go build. Requires Go 1.13 or later.

garble build [build flags] [packages]

which is equivalent to the longer:

go build -a -trimpath -toolexec=garble [build flags] [packages]


Produce a binary that works as well as a regular build, but that has as little information about the original source code as possible.

The tool is designed to be:

  • Coupled with cmd/go, to support both GOPATH and modules with ease
  • Deterministic and reproducible, given the same initial source code
  • Reversible given the original source, to un-garble panic stack traces


The tool wraps calls to the Go compiler to transform the Go source code, in order to:

  • Replace as many useful identifiers as possible with short base64 hashes
  • Remove module build information
  • Strip filenames and unnecessary lines, to make position info less useful

It also wraps calls to the linker in order to:

  • Enforce the -s flag, to not include the symbol table
  • Enforce the -w flag, to not include DWARF debugging data

Finally, the tool requires the use of the -trimpath build flag, to ensure the binary doesn't include paths from the current filesystem.


  • The -a flag for go build is required, since -toolexec doesn't work well with the build cache; see #27628.

  • Since no caching at all can take place right now (see the link above), builds will be slower than go build - especially for large projects.

  • The standard library is never garbled when compiled, since the source is always publicly available.

  • Deciding what method names to garble is always going to be difficult, due to interfaces that could be implemented up or down the package import tree.

  • Some uses of the reflect package may break, such as accessing a struct's field, whose name has been garbled.

You can’t perform that action at this time.