From 5572675988dcb26062f3c63d4a9e3a91b34c5663 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Mart=C3=AD?= Date: Wed, 31 Mar 2021 21:03:02 +0100 Subject: [PATCH] README: refactor and include more useful information The sections are a bit more organized now. We add better docs for flags, a new section on build speed, and we also remove the "withgo" helper as it seems a bit over the top. Fixes #275. --- README.md | 84 +++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 54 insertions(+), 30 deletions(-) diff --git a/README.md b/README.md index 7b388eb..a346053 100644 --- a/README.md +++ b/README.md @@ -28,11 +28,9 @@ order to: * Replace package paths with short base64 hashes * Remove all [build](https://golang.org/pkg/runtime/#Version) and [module](https://golang.org/pkg/runtime/debug/#ReadBuildInfo) information * Strip filenames and shuffle position information -* Strip debugging information and symbol tables -* Obfuscate literals, if the `-literals` flag is given -* Remove [extra information](#tiny-mode) if the `-tiny` flag is given - -### Options +* Strip debugging information and symbol tables via `-ldflags="-w -s"` +* [Obfuscate literals](#obfuscate-literals), if the `-literals` flag is given +* Remove [extra information](#tiny-mode), if the `-tiny` flag is given By default, the tool obfuscates the packages under the current module. If not running in module mode, then only the main package is obfuscated. To specify @@ -49,17 +47,52 @@ $ go1.16.1 download $ PATH=$(go1.16.1 env GOROOT)/bin:${PATH} garble build ``` -You can also declare a function to make multiple uses simpler: +### Literal obfuscation -```sh -$ withgo() { - local gocmd=go${1} - shift +Using the `-literals` flag causes literal expressions such as strings to be +replaced with more complex variants, resolving to the same value at run-time. +This feature is opt-in, as it can cause slow-downs depending on the input code. - PATH=$(${gocmd} env GOROOT)/bin:${PATH} "$@" -} -$ withgo 1.16.1 garble build -``` +Literal expressions used as constants cannot be obfuscated, since they are +resolved at compile time. This includes any expressions part of a `const` +declaration. + +### Tiny mode + +When the `-tiny` flag is passed, extra information is stripped from the resulting +Go binary. This includes line numbers, filenames, and code in the runtime that +prints panics, fatal errors, and trace/debug info. All in all this can make binaries +2-5% smaller in our testing. + +Note: if `-tiny` is passed, no panics, fatal errors will ever be printed, but they can +still be handled internally with `recover` as normal. In addition, the `GODEBUG` +environmental variable will be ignored. + +### Speed + +`garble build` should take about twice as long as `go build`, as it needs to +complete two builds. The original build, to be able to load and type-check the +input code, and finally the obfuscated build. + +Go's build cache is fully supported; if a first `garble build` run is slow, a +second run should be significantly faster. This should offset the cost of the +double builds, as incremental builds in Go are fast. + +### Determinism and seeds + +Just like Go, garble builds are deterministic and reproducible if the inputs +remain the same: the version of Go, the version of Garble, and the input code. +This has significant benefits, such as caching builds or being able to use +`garble reverse` to de-obfuscate stack traces. + +However, it also means that an input package will be obfuscated in exactly the +same way if none of those inputs change. If you want two builds of your program +to be entirely different, you can use `-seed` to provide a new seed for the +entire build, which will cause a full rebuild. + +If any open source packages are being obfuscated, providing a custom seed can +also provide extra protection. It could be possible to guess the versions of Go +and garble given how a public package was obfuscated without a seed. ### Caveats @@ -69,32 +102,23 @@ to document the current shortcomings of this tool. * Exported methods are never obfuscated at the moment, since they could be required by interfaces and reflection. This area is a work in progress. -* Go plugins are not currently supported; see [#87](https://github.com/burrowers/garble/issues/87). - -* There are cases where garble is a little too agressive with obfuscation, this may lead to identifiers getting obfuscated which are needed for reflection, e.g. to parse JSON into a struct; see [#162](https://github.com/burrowers/garble/issues/162). To work around this you can pass a hint to garble, that an type is used for reflection via passing it to `reflect.TypeOf` or `reflect.ValueOf` in the same file: +* It can be hard for garble to know what types will be used with + [reflection](https://golang.org/pkg/reflect), including JSON encoding or + decoding. If your program breaks because a type's names are obfuscated when + they should not be, you can add an explicit hint: ```go - // this is used for parsing json type Message struct { Command string Args string } - // never obfuscate the Message type + // Never obfuscate the Message type. var _ = reflect.TypeOf(Message{}) ``` -### Tiny Mode - -When the `-tiny` flag is passed, extra information is stripped from the resulting -Go binary. This includes line numbers, filenames, and code in the runtime that -prints panics, fatal errors, and trace/debug info. All in all this can make binaries -2-5% smaller in our testing. - -Note: if `-tiny` is passed, no panics, fatal errors will ever be printed, but they can -still be handled internally with `recover` as normal. In addition, the `GODEBUG` -environmental variable will be ignored. +* Go plugins are not currently supported; see [#87](https://github.com/burrowers/garble/issues/87). ### Contributing -We actively seek new contributors, if you would like to contribute to garble use the +We welcome new contributors. If you would like to contribute, see [CONTRIBUTING.md](CONTRIBUTING.md) as a starting point.