env GOGARBLE=test/main,big.chungus/meme garble build exec ./main cmp stderr main.stderr ! binsubstr main$exe 'obfuscatedFunc' 'ObfuscatedFunc' [short] stop # no need to verify this with -short go build exec ./main cmp stderr main.stderr -- go.mod -- module test/main go 1.17 replace big.chungus/meme => ./big.chungus/meme require ( big.chungus/meme v0.0.0 ) -- a.go -- package main // Call a function which is linknamed to another symbol. // What's special here is that we obfuscate this call before the function declaration. // If we decide not to obfuscate the name in the function declaration, // we shouldn't obfuscate the name here either. func linknameCalledInPkg() { println(obfuscatedFunc()) } -- main.go -- package main import ( _ "os/exec" _ "strings" _ "unsafe" _ "big.chungus/meme" "test/main/imported" ) // A linkname to an external non-obfuscated func. //go:linkname byteIndex strings.IndexByte func byteIndex(s string, c byte) int // A linkname to an external non-obfuscated non-exported func. //go:linkname interfaceEqual os/exec.interfaceEqual func interfaceEqual(a, b interface{}) bool // A linkname to an external obfuscated func. //go:linkname obfuscatedFunc test/main/imported.ObfuscatedFuncImpl func obfuscatedFunc() string // A linkname to an entirely made up name, implemented elsewhere. //go:linkname renamedFunc madeup.newName func renamedFunc() string // A linkname to an external non-obfuscated func in another // module whose package path has a dot in it. //go:linkname tagline big.chungus/meme.chungify func tagline() string func main() { println(byteIndex("01234", '3')) println(interfaceEqual("Sephiroth", 7)) println(obfuscatedFunc()) println(renamedFunc()) println(tagline()) println(imported.ByteIndex("01234", '3')) linknameCalledInPkg() } -- imported/imported.go -- package imported import ( _ "unsafe" ) func ObfuscatedFuncImpl() string { return "obfuscated func" } //go:linkname renamedFunc madeup.newName func renamedFunc() string { return "renamed func" } // A linkname to an external non-obfuscated func. // Different from byteIndex, as we call this from an importer package. //go:linkname ByteIndex strings.IndexByte func ByteIndex(s string, c byte) int -- big.chungus/meme/go.mod -- module test/main go 1.17 -- big.chungus/meme/dante.go -- package meme func chungify() string { return "featuring Dante from the Devil May Cry series" } -- main.stderr -- 3 false obfuscated func renamed func featuring Dante from the Devil May Cry series 3 obfuscated func