env GOGARBLE=* # Note the proper domain, since the dot adds an edge case. env LDFLAGS='-X=main.unexportedVersion=v1.22.33 -X=main.replacedWithEmpty= -X=domain.test/main/imported.ExportedUnset=garble_replaced -X=domain.test/missing/path.missingVar=value' garble build -ldflags=${LDFLAGS} exec ./main cmp stdout main.stdout ! binsubstr main$exe 'domain.test/main' 'unexportedVersion' 'ExportedUnset' [short] stop # no need to verify this with -short garble -tiny -literals -seed=0002deadbeef build -ldflags=${LDFLAGS} exec ./main cmp stdout main.stdout ! binsubstr main$exe 'unexportedVersion' 'ExportedUnset' binsubstr main$exe 'v1.22.33' 'garble_replaced' # TODO: obfuscate injected strings too binsubstr main$exe 'kept_before' 'kept_after' # TODO: obfuscate strings near ldflags vars go build -ldflags=${LDFLAGS} exec ./main cmp stdout main.stdout binsubstr main$exe 'unexportedVersion' 'ExportedUnset' 'v1.22.33' 'garble_replaced' -- go.mod -- module domain.test/main go 1.17 -- main.go -- package main import ( "fmt" "domain.test/main/imported" ) var unexportedVersion = "unknown" var notReplacedBefore, replacedWithEmpty, notReplacedAfter = "kept_before", "original", "kept_after" func main() { fmt.Printf("version: %q\n", unexportedVersion) fmt.Printf("becomes empty: %q\n", replacedWithEmpty) fmt.Printf("should be kept: %q, %q\n", notReplacedBefore, notReplacedAfter) fmt.Printf("no longer unset: %q\n", imported.ExportedUnset) } -- imported/imported.go -- package imported var ( ExportedUnset, AnotherUnset string otherVar int ) -- main.stdout -- version: "v1.22.33" becomes empty: "" should be kept: "kept_before", "kept_after" no longer unset: "garble_replaced"