Obfuscate Go code by wrapping the Go toolchain

garble

GO111MODULE=on go get mvdan.cc/garble

Obfuscate Go code by wrapping the Go toolchain. Requires Go 1.16 or later.

garble build [build flags] [packages]

The tool also supports garble test to run tests with obfuscated code, and garble reverse to de-obfuscate text such as stack traces. See garble -h for up to date usage information.

Purpose

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 modules and build caching
  • Deterministic and reproducible, given the same initial source code
  • Reversible given the original source, to de-obfuscate panic stack traces

Mechanism

The tool wraps calls to the Go compiler and linker to transform the Go build, in order to:

  • Replace as many useful identifiers as possible with short base64 hashes
  • Replace package paths with short base64 hashes
  • Remove all build and module information
  • Strip filenames and shuffle position information
  • Strip debugging information and symbol tables via -ldflags="-w -s"
  • Obfuscate literals, if the -literals flag is given
  • Remove extra information, 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 what packages to obfuscate, set GOPRIVATE, documented at go help private.

Note that commands like garble build will use the go version found in your $PATH. To use different versions of Go, you can install them and set up $PATH with them. For example, for Go 1.16.1:

$ go get golang.org/dl/go1.16.1
$ go1.16.1 download
$ PATH=$(go1.16.1 env GOROOT)/bin:${PATH} garble build

Literal obfuscation

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.

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 or 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

Most of these can improve with time and effort. The purpose of this section is 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.

  • It can be hard for garble to know what types will be used with reflection, 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:

     type Message struct {
     	Command string
     	Args    string
     }
    
     // Never obfuscate the Message type.
     var _ = reflect.TypeOf(Message{})
  • Go plugins are not currently supported; see #87.

Contributing

We welcome new contributors. If you would like to contribute, see CONTRIBUTING.md as a starting point.

Owner
Gophers working on tools to hide treasure
null
Comments
  • Error during garble build

    Error during garble build

    I'm trying to build my go app binary on MacOs, but build fails with error:

    /usr/local/Cellar/go/1.15.5/libexec/pkg/tool/darwin_amd64/link: running clang failed: exit status 1
    Undefined symbols for architecture x86_64:
      "_type.path/to/package/types.ZfUYm", referenced from:
          _z09qX.B.func3.2 in go.o
          _z09qX.D.func2.2 in go.o
      "_type.path/to/package/types.ZmSSZ", referenced from:
          _z9sT0.E in go.o
          _z09qX.B.func3.2 in go.o
          _z09qX.D.func2.2 in go.o
      "_type.path/to/package/types.Zn3Fp", referenced from:
          _z9sT0.C in go.o
          _zdZv7.ZEW_L.func1 in go.o
    ld: symbol(s) not found for architecture x86_64
    clang: error: linker command failed with exit code 1 (use -v to see invocation)
    
    exit status 2
    exit status 2
    

    I tried to build it with GOARCH=arm GOOS=linux envs, but build failed with another error:

    path/to/package is my package. Sorry, can't write it here)

    zdzCF.B: relocation target type.path/to/package/types.ZU31i not defined
    zdzCF.F: relocation target type.path/to/package/types.ZHdpV not defined
    zHIRS.ZCZ_Z.func1: relocation target type.path/to/package/types.ZHdpV not defined
    z3hTq.C.func1.2: relocation target type.path/to/package/types.Z8uvN not defined
    z3hTq.C.func1.2: relocation target type.path/to/package/types.ZU31i not defined
    z3hTq.B.func1.2: relocation target type.path/to/package/types.Z8uvN not defined
    z3hTq.B.func1.2: relocation target type.path/to/package/types.ZU31i not defined
    exit status 2
    exit status 2
    

    It is the same project as in this issue: https://github.com/burrowers/garble/issues/202

    Error in https://github.com/burrowers/garble/issues/202 issue seems like fixed, but as you can see new one appeared.

    I'm using currently lates revision: https://github.com/burrowers/garble/commit/e014f480f99974a2976166fe5252fc41676a598a

  • Strengthen literal obfuscation

    Strengthen literal obfuscation

    Some ideas:

    • add some light obfuscation to the panic literals of garbleDecrypt
    • randomize function signature of garbleDecrypt e.g. include additional parameters such as ints
    • different locations of the key, as a global variable, inside garbleDecrypt, as a parameter
    • different encodings for the key, string, base64, XOR spread across multiple variables
    • multiple decrypt functions in a single package to make finding the/ all decrypt functions not as easy as analyzing which function is called with all literals
    • have a slice/map with all literals of the package, where the decrypt function then recieves a position number or a slice element to decrypt

    Many of these will add more complexity (more to test, we maybe need additional flags to test specific combinations), some of it might not be worth the extra burden to maintain.

    Note: "random" is always pseudo-random (deterministic), expect when -random is passed then it can be true random (crypto/rand).

  • buildmode plugin issue of package not found

    buildmode plugin issue of package not found

    The files as follows:

    go.mod

    module test.com/plugin
    
    go 1.14
    

    dll/dll.go

    package dll
    
    import (
    	"fmt"
    )
    
    type DllInfo struct {
    	Name string `json:"name"`
    	Id   int32  `json:"id"`
    }
    
    func TestDll(name string, id int32) {
    	fmt.Printf("check : %v\n", &DllInfo{name, id})
    }
    

    main.go

    package main
    
    import (
    	"test.com/plugin/dll"
    )
    
    var TestDll = dll.TestDll
    
    func main() {
    	TestDll("asdasfas %v", 111)
    }
    

    Then run command:

    garble build -buildmode=plugin -o dll.so main.go

    Get the errors:

    # command-line-arguments
    main.go:7:15: undefined: dll.TestDll
    exit status 2
    exit status 2
    

    It really weird... Seems can not find the package.

  • Obfuscate literals such as strings

    Obfuscate literals such as strings

    Other projects like gobfuscate do this, and it seems like a feature that's generally useful to many users.

    For example, this is what they do:

    Strings are obfuscated by replacing them with functions. A string will be turned into an expression like the following:

    (func() string {
    	mask := []byte{33, 15, 199}
    	maskedStr := []byte{73, 106, 190}
    	res := make([]byte, 3)
    	for i, m := range mask {
    		res[i] = m ^ maskedStr[i]
    	}
    	return string(res)
    }())
    

    Reasons to do this:

    • More obfuscation takes place. The decompiled source code is less useful.
    • It's harder to locate strings in binaries via grep, or extract them easily.

    Reasons not to do this:

    • No information is lost. When one runs the program, all literals are available in memory anyway. All other kinds of obfuscation we do don't have this flaw, as they remove information entirely.
    • There could be a significant performance penalty if we replace every single literal with a function to generate it. For example, if a string is used as part of a hot loop that's executed tens of thousands of times per second.

    So far, I have only implemented the "remove information" kind of obfuscation, such as replacing variable names and file names, and removing module information.

    As much as I like not having flags, I think that any obfuscation that has a significant performance penalty should have a flag, even if it's enabled by default. I would prefer for the flag to be disabled by default, since it should be the developer who decides whether or not the tradeoff is worth it for them.

  • Error when adding hardware inspection library to existing project using garble

    Error when adding hardware inspection library to existing project using garble

    Hi All,

    Very new to garble and the docs are very sparse, so I thought I would open an issue to see if someone could help. I am currently adding hardware info collection to a tool called ToRat

    For some reason, garble is scrambling the calls being made to ghw. For example, the error below should be calling cpu.Processors. How would I go about preventing garble from changing these calls?

    Here is the branch I'm working from: https://github.com/JustinTimperio/ToRat/tree/feature-hw-collector The module I'm adding: https://github.com/jaypipes/ghw The error I get is:

    Step 17/21 : RUN cd ./cmd/client && garble -literals -tiny -seed=random build -ldflags="-extldflags=-static" -tags "osusergo,netgo,tor" -o /dist/client/client_linux && upx /dist/client/client_linux
     ---> Running in ccc44745863e
    # github.com/ghodss/yaml
    parsing archive member "_go_.o": error resolving path of objfile gopkg.in/yaml%2ev2: exit status 1
    # github.com/lu4p/ToRat/torat_client
    :28: cpu.ZvD5G undefined (type *"github.com/jaypipes/ghw/pkg/cpu".ZGVzt has no field or method ZvD5G)
    :44: cpu.ZFUUP undefined (type *"github.com/jaypipes/ghw/pkg/cpu".ZGVzt has no field or method ZFUUP)
    unexpected EOF
    exit status 2
    exit status 2
    The command '/bin/sh -c cd ./cmd/client && garble -literals -tiny -seed=random build -ldflags="-extldflags=-static" -tags "osusergo,netgo,tor" -o /dist/client/client_linux && upx /dist/client/client_linux' returned a non-zero code: 1
    
  • Strengthen literal obfuscation (Use XOR instead of AES for literal obfuscation.)

    Strengthen literal obfuscation (Use XOR instead of AES for literal obfuscation.)

    Implement a literal obfuscator interface, to allow the easy addition of new encodings.

    Add literal obfuscation for byte literals, integers, booleans.

    Choose a random obfuscator on literal obfuscation, useful when multiple obfuscators are implemented.

  • Ability to un-garble code, filename positions, and ultimately stack traces given a source package

    Ability to un-garble code, filename positions, and ultimately stack traces given a source package

    For example, right now a garbled panic looks something like:

    panic: here
    
    goroutine 1 [running]:
    main.znh2yNUH9(0x0)
    	z0.go:82 +0x47
    main.main()
    	z0.go:44 +0x22
    

    Its non-garbled version is:

    panic: here
    
    goroutine 1 [running]:
    main.main1(0x0)
    	/home/mvdan/src/garble/main.go:92 +0x47
    main.main()
    	/home/mvdan/src/garble/main.go:47 +0x22
    

    We should make this possible and automate it.

  • -ldflags=-X with quotes not working when -literals is also used

    -ldflags=-X with quotes not working when -literals is also used

    What version of Garble and Go are you using?

    $ garble version
    v0.5.1
    
    $ go version
    go version go1.17.5 linux/amd64
    

    What environment are you running Garble on?

    go env Output
    $ go env
    GO111MODULE=""
    GOARCH="amd64"
    GOBIN=""
    GOCACHE="/home/rastley/.cache/go-build"
    GOENV="/home/rastley/.config/go/env"
    GOEXE=""
    GOEXPERIMENT=""
    GOFLAGS=""
    GOHOSTARCH="amd64"
    GOHOSTOS="linux"
    GOINSECURE=""
    GOMODCACHE="/home/rastley/go/pkg/mod"
    GONOPROXY=""
    GONOSUMDB=""
    GOOS="linux"
    GOPATH="/home/rastley/go"
    GOPRIVATE=""
    GOPROXY="https://proxy.golang.org,direct"
    GOROOT="/home/rastley/sdk/go1.17.5"
    GOSUMDB="sum.golang.org"
    GOTMPDIR=""
    GOTOOLDIR="/home/rastley/sdk/go1.17.5/pkg/tool/linux_amd64"
    GOVCS=""
    GOVERSION="go1.17.5"
    GCCGO="gccgo"
    AR="ar"
    CC="gcc"
    CXX="g++"
    CGO_ENABLED="1"
    GOMOD="/tmp/merlin/Payload_Type/merlin/agent_code/go.mod"
    CGO_CFLAGS="-g -O2"
    CGO_CPPFLAGS=""
    CGO_CXXFLAGS="-g -O2"
    CGO_FFLAGS="-g -O2"
    CGO_LDFLAGS="-g -O2"
    PKG_CONFIG="pkg-config"
    GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build2615366059=/tmp/go-build -gno-record-gcc-switches"
    

    What did you do?

    I compiled Merlin using Garble with the -literals argument and attempted to set verbose variable through the go build ldflags argument. When I ran the agent, there was no output to STDOUT but there should have been if the verbose variable was set.

    rastley@ubuntu:/tmp$ garble version
    v0.5.1
    rastley@ubuntu:/tmp$ git clone https://github.com/MythicAgents/merlin
    <SNIP>
    rastley@ubuntu:/tmp$ cd merlin/Payload_Type/merlin/agent_code/
    rastley@ubuntu:/tmp/merlin/Payload_Type/merlin/agent_code$ garble -tiny -literals build -o merlin.bin -ldflags '-X "main.verbose=True"' main.go
    rastley@ubuntu:/tmp/merlin/Payload_Type/merlin/agent_code$ ./merlin.bin 
    rastley@ubuntu:/tmp/merlin/Payload_Type/merlin/agent_code$
    

    What did you expect to see?

    I expected to see verbose output to STDOUT because the verbose variable was set to True. The output would look like:

    rastley@ubuntu:/tmp/merlin/Payload_Type/merlin/agent_code$ ./merlin.bin 
    [i]Host Information:
    [i]	Agent UUID: 1e1c41d6-8511-403b-9f83-0ec9b0a4d71e
    [i]	Platform: linux
    [i]	Architecture: amd64
    [i]	User Name: rastley
    [i]	User GUID: 1000
    [i]	Integrity Level: 3
    [i]	Hostname: ubuntu
    [i]	Process: /tmp/merlin/Payload_Type/merlin/agent_code/merlin.bin
    [i]	PID: 480365
    

    What did you see instead?

    I saw no output, indicating that the verbose variable was not set.

    Misc.

    I opened main.go and added func init(){ fmt.Printf("Verbose: %s\n", verbose) } to assist with debugging:

    rastley@ubuntu:/tmp/merlin/Payload_Type/merlin/agent_code$ garble -tiny -literals build -o merlin.bin -ldflags '-X "main.verbose=True"' main.go
    rastley@ubuntu:/tmp/merlin/Payload_Type/merlin/agent_code$ ./merlin.bin 
    Verbose: false
    

    Potentially related to #323

  • Go list error

    Go list error

    Hey, first of all thanks for creating such a useful tool !

    I'm having issues with running garble inside Docker container, while it works flawless outside of container. This is the command I'm running:

    RUN --mount=type=cache,target=/go/pkg/mod \
        go get mvdan.cc/garble
    RUN --mount=type=cache,target=/go/pkg/mod \
        --mount=type=cache,target=/root/.cache/go-build \
        GIT_TERMINAL_PROMPT=1 \
        CGO_ENABLED=0 \
        GOPRIVATE=none \
        garble -tiny -literals -seed=random build -trimpath -ldflags="-s -w" -o ./bin/my-program ./cmd/my-program/main.go
    

    or

    RUN --mount=type=cache,target=/go/pkg/mod \
        go get mvdan.cc/garble
    RUN --mount=type=cache,target=/root/.cache/go-build \
        GIT_TERMINAL_PROMPT=1 \
        CGO_ENABLED=0 \
        GOPRIVATE=none \
        garble -tiny -literals -seed=random build -trimpath -ldflags="-s -w" -o ./bin/my-program ./cmd/my-program/main.go
    

    And this is error output I'm getting:

    #20 1.002 go list error: exit status 1: /go/pkg/mod/github.com/fsnotify/[email protected]/inotify.go:19:2: missing go.sum entry for module providing package golang.org/x/sys/unix; to add:
    #20 1.002 	go mod download golang.org/x/sys
    #20 1.002 /go/pkg/mod/github.com/spf13/[email protected]/util.go:28:2: missing go.sum entry for module providing package golang.org/x/text/transform; to add:
    #20 1.002 	go mod download golang.org/x/text
    #20 1.002 /go/pkg/mod/github.com/spf13/[email protected]/util.go:29:2: missing go.sum entry for module providing package golang.org/x/text/unicode/norm; to add:
    #20 1.002 	go mod download golang.org/x/text
    #20 1.002 go build golang.org/x/sys/unix: no Go files in
    #20 1.002 go build golang.org/x/text/transform: no Go files in
    #20 1.002 go build golang.org/x/text/unicode/norm: no Go files in
    

    And this is my go.mod file

    module my-program
    
    go 1.16
    
    require (
    	github.com/alecthomas/chroma v0.9.1
    	github.com/gorilla/mux v1.8.0
    	github.com/machinebox/graphql v0.2.2
    	github.com/matryer/is v1.4.0 // indirect
    	github.com/opentracing/opentracing-go v1.2.0
    	github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5
    	github.com/openzipkin/zipkin-go v0.2.5
    	github.com/pkg/errors v0.9.1
    	github.com/rs/zerolog v1.20.0
    	github.com/spf13/cobra v1.1.1
    	github.com/spf13/viper v1.7.1
    	github.com/stoewer/go-strcase v1.2.0
    	github.com/stretchr/testify v1.7.0
    	github.com/valyala/quicktemplate v1.6.3
    	gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect
    )
    

    I'm using Go 1.16.4 on Darwin, I ran go mod tidy but it didn't help to solve the issue. Issue persists only inside container. I think the issue isn't related to garble but to go list command itself

  • GOPRIVATE=* not work with staticcheck

    GOPRIVATE=* not work with staticcheck

    Command:

    git clone https://github.com/golang/tools
    cd tools
    GOPRIVATE=* garble build build ./cmd/staticcheck
    

    Output:

    # runtime/debug
    c:\go\src\runtime\debug\garbage.go:15:17: undefined: time.Time
    c:\go\src\runtime\debug\garbage.go:17:17: undefined: time.Duration
    c:\go\src\runtime\debug\garbage.go:18:19: undefined: time.Duration
    c:\go\src\runtime\debug\garbage.go:19:19: undefined: time.Time
    c:\go\src\runtime\debug\garbage.go:20:19: undefined: time.Duration
    c:\go\src\runtime\debug\garbage.go:39:24: undefined: time.Duration
    c:\go\src\runtime\debug\garbage.go:50:17: undefined: time.Unix
    c:\go\src\runtime\debug\garbage.go:57:27: undefined: time.Time
    c:\go\src\runtime\debug\garbage.go:61:43: undefined: time.Unix
    c:\go\src\runtime\debug\stubs.go:12:21: undefined: time.Duration
    c:\go\src\runtime\debug\garbage.go:61:43: too many errors
    exit status 2
    # runtime/trace
    c:\go\src\runtime\trace\annotation.go:34:19: undefined: context.Context
    c:\go\src\runtime\trace\annotation.go:39:9: undefined: context.WithValue
    c:\go\src\runtime\trace\annotation.go:61:22: undefined: context.Context
    c:\go\src\runtime\trace\annotation.go:91:14: undefined: context.Context
    c:\go\src\runtime\trace\annotation.go:97:15: undefined: context.Context
    c:\go\src\runtime\trace\annotation.go:102:25: undefined: fmt.Sprintf
    c:\go\src\runtime\trace\annotation.go:118:21: undefined: context.Context
    c:\go\src\runtime\trace\annotation.go:149:22: undefined: context.Context
    c:\go\src\runtime\trace\trace.go:120:14: undefined: io.Writer
    c:\go\src\runtime\trace\trace.go:151:2: undefined: sync.Mutex
    c:\go\src\runtime\trace\trace.go:151:2: too many errors
    exit status 2
    # net
    typecheck error: c:\go\src\net\dnsclient.go:11:2: could not import golang.org/x/net/dns/dnsmessage (path not found in listed packages: golang.org/x/net/dns/dnsmessage)
    # vendor/golang.org/x/text/unicode/norm
    typecheck error: c:\go\src\vendor\golang.org\x\text\unicode\norm\normalize.go:15:2: could not import golang.org/x/text/transform (path not found in listed packages: golang.org/x/text/transform)
    # runtime/pprof
    c:\go\src\runtime\pprof\label.go:27:21: undefined: context.Context
    c:\go\src\runtime\pprof\label.go:59:21: undefined: context.Context
    c:\go\src\runtime\pprof\label.go:93:16: undefined: context.Context
    c:\go\src\runtime\pprof\label.go:101:20: undefined: context.Context
    c:\go\src\runtime\pprof\pprof.go:135:8: undefined: sync.Mutex
    c:\go\src\runtime\pprof\pprof.go:138:13: undefined: io.Writer
    c:\go\src\runtime\pprof\pprof.go:326:29: undefined: io.Writer
    c:\go\src\runtime\pprof\pprof.go:377:31: undefined: io.Writer
    c:\go\src\runtime\pprof\pprof.go:404:26: undefined: io.Writer
    c:\go\src\runtime\pprof\pprof.go:492:25: undefined: io.Writer
    c:\go\src\runtime\pprof\pprof.go:492:25: too many errors
    exit status 2
    # vendor/golang.org/x/text/secure/bidirule
    typecheck error: c:\go\src\vendor\golang.org\x\text\secure\bidirule\bidirule.go:15:2: could not import golang.org/x/text/transform (path not found in listed packages: golang.org/x/text/transform)
    # vendor/golang.org/x/crypto/cryptobyte
    typecheck error: c:\go\src\vendor\golang.org\x\crypto\cryptobyte\asn1.go:14:2: could not import golang.org/x/crypto/cryptobyte/asn1 (path not found in listed packages: golang.org/x/crypto/cryptobyte/asn1)
    exit status 2
    

    Tested on lasted commit and 30df5e9bbd677fa31f6562d3ab7a43edd203982b

  • Using `embed` inside go program results in TOOLEXEC_IMPORTPATH not found in listed packages: embed

    Using `embed` inside go program results in TOOLEXEC_IMPORTPATH not found in listed packages: embed

    What version of Garble and Go are you using?

    $ garble version
    v0.4.0
    
    $ go version
    go version go1.16.3 darwin/amd64
    

    What environment are you running Garble on?

    go env Output
    $ go env
    GO111MODULE="auto"
    GOARCH="amd64"
    GOBIN=""
    GOCACHE="/Users/User/Library/Caches/go-build"
    GOENV="/Users/User/Library/Application Support/go/env"
    GOEXE=""
    GOFLAGS=""
    GOHOSTARCH="amd64"
    GOHOSTOS="darwin"
    GOINSECURE=""
    GOMODCACHE="/Users/User/Documents/Go/pkg/mod"
    GONOPROXY=""
    GONOSUMDB=""
    GOOS="darwin"
    GOPATH="/Users/User/Documents/Go"
    GOPRIVATE=""
    GOPROXY="https://proxy.golang.org,direct"
    GOROOT="/usr/local/Cellar/go/1.16.3/libexec"
    GOSUMDB="sum.golang.org"
    GOTMPDIR=""
    GOTOOLDIR="/usr/local/Cellar/go/1.16.3/libexec/pkg/tool/darwin_amd64"
    GOVCS=""
    GOVERSION="go1.16.3"
    GCCGO="gccgo"
    AR="ar"
    CC="clang"
    CXX="clang++"
    CGO_ENABLED="1"
    GOMOD=""
    CGO_CFLAGS="-g -O2"
    CGO_CPPFLAGS=""
    CGO_CXXFLAGS="-g -O2"
    CGO_FFLAGS="-g -O2"
    CGO_LDFLAGS="-g -O2"
    PKG_CONFIG="pkg-config"
    GOGCCFLAGS="-fPIC -arch x86_64 -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/dv/4yby4nt54ng769mywc0vqbn00000gn/T/go-build898330407=/tmp/go-build -gno-record-gcc-switches -fno-common"
    

    What did you do?

    I'm creating a program that uses the embed package to import static resources, this is done with the following lines:

    //go:embed static/*
    var static embed.FS
    

    These are then later used like so:

    func getData(dir string) ([]string, error) {
    	result := []string{}
    	files, err := static.ReadDir(dir)
    
    	if err != nil {
    		return nil, err
    	}
    
    	for _, file := range files {
    		data, _ := static.ReadFile(dir + "/" + file.Name())
    		result = append(result, string(data))
    	}
    
    	return result, nil
    }
    

    What did you expect to see?

    When I compile the program normally, all goes well, as expected.

    What did you see instead?

    $ garble -debugdir=../dist/obfuscated build -o progam.elf -s -w ./program/
    # embed
    TOOLEXEC_IMPORTPATH not found in listed packages: embed
    
  • implement unexported func name removing

    implement unexported func name removing

    Removing unexportable function names is implemented by this algorithm:

    1. Allocate 1 byte for empty string and write to runtime.funcnametab by 0 offset
    2. While iterating over functions during runtime.funcnametab creation, all non-exportable function names are forwarded to 0 offset, i.e. to correct empty string

    Stats (GOOS=linux):

    command|size :-----:|:-----: go build|1203067 garble build|782336 garble -tiny build|688128 NEW garble -tiny build|659456

  • feat: Hope GOGARBLE can support the use of ! to exclude certain package

    feat: Hope GOGARBLE can support the use of ! to exclude certain package

    What version of Garble and Go are you using?

    $ garble version
    0.8.0
    $ go version
    1.19.1
    

    What did you expect to see?

    GOGARBLE=!google.golang.org/protobuf garble build -tiny .
    

    Hope to achieve the effect of "obfuscate everything except google.golang.org/protobuf"

  • github.com/bytedance/sonic fails to obfuscate

    github.com/bytedance/sonic fails to obfuscate

    What version of Garble and Go are you using?

    $ garble version
    0.8.0
    $ go version
    1.19.4
    

    What environment are you running Garble on?

    go env Output
    $ go env
    windows
    

    What did you do?

    i build my project with garble

    What did you expect to see?

    build success

    What did you see instead?

    i got a error: panic: path not found in listed packages: github in main.replaceAsmNames(0x11132c0?, {0xc000350000?, 0xc00034a570?, 0xa?}) ……/[email protected]/main.go:736 +0x72a

  • panic: runtime listed a std package we can't find: atomic

    panic: runtime listed a std package we can't find: atomic

    What version of Garble and Go are you using?

    $ go install mvdan.cc/garble@latest
    
    [email protected] (from panic)
    
    $ go version
    go version go1.19.4 linux/amd64
    

    What environment are you running Garble on?

    go env Output
    $ go env
      GO111MODULE=""
      GOARCH="amd64"
      GOBIN=""
      GOCACHE="/home/runner/.cache/go-build"
      GOENV="/home/runner/.config/go/env"
      GOEXE=""
      GOEXPERIMENT=""
      GOFLAGS=""
      GOHOSTARCH="amd64"
      GOHOSTOS="linux"
      GOINSECURE=""
      GOMODCACHE="/home/runner/go/pkg/mod"
      GONOPROXY=""
      GONOSUMDB=""
      GOOS="linux"
      GOPATH="/home/runner/go"
      GOPRIVATE=""
      GOPROXY="https://proxy.golang.org,direct"
      GOROOT="/opt/hostedtoolcache/go/1.19.4/x64"
      GOSUMDB="sum.golang.org"
      GOTMPDIR=""
      GOTOOLDIR="/opt/hostedtoolcache/go/1.19.4/x64/pkg/tool/linux_amd64"
      GOVCS=""
      GOVERSION="go1.19.4"
      GCCGO="gccgo"
      GOAMD64="v1"
      AR="ar"
      CC="gcc"
      CXX="g++"
      CGO_ENABLED="0"
      GOMOD="/dev/null"
      GOWORK=""
      CGO_CFLAGS="-g -O2"
      CGO_CPPFLAGS=""
      CGO_CXXFLAGS="-g -O2"
      CGO_FFLAGS="-g -O2"
      CGO_LDFLAGS="-g -O2"
      PKG_CONFIG="pkg-config"
      GOGCCFLAGS="-fPIC -m64 -Wl,--no-gc-sections -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build3[18](https://github.com/klauspost/compress/actions/runs/3724454705/jobs/6316617540#step:2:19)[29](https://github.com/klauspost/compress/actions/runs/3724454705/jobs/6316617540#step:2:30)08879=/tmp/go-build -gno-record-gcc-switches"
    

    What did you do?

    Running goreleaser in CICD fails

    What did you expect to see?

    Build.

    What did you see instead?

    • building binaries
    [....]
          • building                  binary=dist/s2c_linux_ppc64le/s2c
    ⨯ release failed after 572.45s error=failed to build for linux_mips64_hardfloat: exit status 1: # runtime/internal/atomic
    panic: runtime listed a std package we can't find: atomic
    
    goroutine 1 [running]:
    main.listPackage({0xc000177[62](https://github.com/klauspost/compress/actions/runs/3724454705/jobs/6316617540#step:9:63)0, 0x6})
    	/home/runner/go/pkg/mod/mvdan.cc/[email protected]/shared.go:392 +0x[63](https://github.com/klauspost/compress/actions/runs/3724454705/jobs/6316617540#step:9:64)4
    main.replaceAsmNames(0x6916a0?, {0xc000182000?, 0xc000177400?, 0xa?})
    	/home/runner/go/pkg/mod/mvdan.cc/[email protected]/main.go:734 +0x1a7
    main.transformAsm({0xc0000b8030, 0x13, 0x13})
    	/home/runner/go/pkg/mod/mvdan.cc/[email protected]/main.go:[66](https://github.com/klauspost/compress/actions/runs/3724454705/jobs/6316617540#step:9:67)8 +0x426
    main.mainErr({0xc0000b8010, 0x15, 0x15})
    	/home/runner/go/pkg/mod/mvdan.cc/[email protected]/main.go:423 +0x7ed
    main.main1()
    	/home/runner/go/pkg/mod/mvdan.cc/[email protected]/main.go:227 +0x16e
    main.main()
    	/home/runner/go/pkg/mod/mvdan.cc/[email protected]/main.go:134 +0x19
    exit status 2
    

    Edit: Simpler repro:

    Check out https://github.com/klauspost/compress

    λ cd s2/cmd/s2c
    λ go install mvdan.cc/garble@latest
    λ set GOOS=linux
    λ set GOARCH=mips64
    λ garble build
    # runtime/internal/atomic
    panic: runtime listed a std package we can't find: atomic
    
    goroutine 1 [running]:
    main.listPackage({0xc0001e9ba0, 0x6})
            e:/gopath/pkg/mod/mvdan.cc/[email protected]/shared.go:392 +0x634
    main.replaceAsmNames(0x843200?, {0xc0001f2000?, 0xc0001e9980?, 0xa?})
            e:/gopath/pkg/mod/mvdan.cc/[email protected]/main.go:734 +0x1a7
    main.transformAsm({0xc0000ca030, 0x13, 0x1d})
            e:/gopath/pkg/mod/mvdan.cc/[email protected]/main.go:668 +0x41f
    main.mainErr({0xc0000ca010, 0x15, 0x1f})
            e:/gopath/pkg/mod/mvdan.cc/[email protected]/main.go:423 +0x75f
    main.main1()
            e:/gopath/pkg/mod/mvdan.cc/[email protected]/main.go:227 +0x16e
    main.main()
            e:/gopath/pkg/mod/mvdan.cc/[email protected]/main.go:134 +0x19
    exit status 2
    

    Compare to go build

  • Reduce the binary size bloat, especially when -literals is used

    Reduce the binary size bloat, especially when -literals is used

    What version of Garble and Go are you using?

    $ garble version
    mvdan.cc/garble v0.8.0
    
    $ go version
    go1.19.4 darwin/arm64
    

    What environment are you running Garble on?

    go env Output
    $ go env
    

    What did you do?

    Compiled my project for both macOS and windows with the latest version of garble, without changing any code since the last compile. Flags used: "-literals -tiny"

    What did you expect to see?

    macOS binary - 18.1mb windows binary - 20mb

    What did you see instead?

    macOS binary - 35.2mb windows binary - 33.9mb

  • Support obfuscating code which uses

    Support obfuscating code which uses "dot imports"

    What version of Garble and Go are you using?

    $ garble version
    0.7.2
    $ go version
    1.19
    

    What environment are you running Garble on?

    go env Output
    $ go env
    

    What did you do?

    common/common.go

    package common
    
    const (
    Version = "1.0.0"
    )
    

    cmd/main.go

    package main
    
    import (
      . "projectName/common"
    )
    
    func main() {
    fmt.Printf("Version: %s", Version)
    }
    

    What did you expect to see?

    Compilation Complete

    What did you see instead?

    Compilation failure (import but not used) GoGarble confuses string constants with string values

Secret management toolchain
Secret management toolchain

Harp TL;DR. Why harp? Use cases How does it work? Like a Data pipeline but for secret Immutable transformation What can I do? FAQ License Homebrew ins

Dec 11, 2022
SPIRE is a toolchain of APIs for establishing trust between software systems across a wide variety of hosting platforms
SPIRE is a toolchain of APIs for establishing trust between software systems across a wide variety of hosting platforms

SPIRE (the SPIFFE Runtime Environment) is a toolchain of APIs for establishing trust between software systems across a wide variety of hosting platforms

Jan 2, 2023
🔎 Help find Trojan Source vulnerability in code 👀 . Useful for code review in project with multiple collaborators

TrojanSourceFinder TrojanSourceFinder helps developers detect "Trojan Source" vulnerability in source code. Trojan Source vulnerability allows an atta

Nov 9, 2022
Go-sec-code is a project for learning Go vulnerability code.
Go-sec-code is a  project for learning Go vulnerability code.

Welcome to go-sec-code ?? Go-sec-code is a project for learning Go vulnerability code. ?? Homepage Introduction 用beego作为后端框架开发的go语言靶场,目前已经完成 commandIn

Nov 23, 2022
Lightweight static analysis for many languages. Find bug variants with patterns that look like source code.

Lightweight static analysis for many languages. Find bugs and enforce code standards. Semgrep is a fast, open-source, static analysis tool that finds

Jan 9, 2023
Ah shhgit! Find secrets in your code. Secrets detection for your GitHub, GitLab and Bitbucket repositories: www.shhgit.com
Ah shhgit! Find secrets in your code. Secrets detection for your GitHub, GitLab and Bitbucket repositories: www.shhgit.com

shhgit helps secure forward-thinking development, operations, and security teams by finding secrets across their code before it leads to a security br

Dec 23, 2022
EarlyBird is a sensitive data detection tool capable of scanning source code repositories for clear text password violations, PII, outdated cryptography methods, key files and more.
EarlyBird is a sensitive data detection tool capable of scanning source code repositories for clear text password violations, PII, outdated cryptography methods, key files and more.

EarlyBird is a sensitive data detection tool capable of scanning source code repositories for clear text password violations, PII, outdated cryptograp

Dec 10, 2022
PHP functions implementation to Golang. This package is for the Go beginners who have developed PHP code before. You can use PHP like functions in your app, module etc. when you add this module to your project.

PHP Functions for Golang - phpfuncs PHP functions implementation to Golang. This package is for the Go beginners who have developed PHP code before. Y

Dec 30, 2022
Exploitation of CVE-2018-18925 a Remote Code Execution against the Git self hosted tool: Gogs.
Exploitation of CVE-2018-18925 a Remote Code Execution against the Git self hosted tool: Gogs.

CVE-2018-18925 Exploitation of CVE-2018-18925 a Remote Code Execution against the Git self hosted tool: Gogs. Gogs is based on the Macaron framework.

Nov 9, 2022
WIP. Converts Azure Container Scan Action output to SARIF, for an easier integration with GitHub Code Scanning

container-scan-to-sarif container-scan-to-sarif converts Azure Container Scan Action output to Static Analysis Results Interchange Format (SARIF), for

Jan 25, 2022
PoC for CVE-2015-1635 / MS15-034 - HTTP.sys Allows Remote Code Execution / Check & DOS
PoC for CVE-2015-1635 / MS15-034 - HTTP.sys Allows Remote Code Execution / Check & DOS

CVE-2015-1635 PoC for CVE-2015-1635 / MS15-034 - HTTP.sys Allows Remote Code Execution / Check & DOS ./MS15-034 <URL> <RESOURCE> <FLAG [0 or 18]> Note

Nov 3, 2021
If I were a malicious actor, how would I sneak my code in?

go-error-hijack-poc This repo demonstrates a hypothetical use of sentinel errors and horizontally off-screen code as attack vectors. How to Run Run th

Jan 15, 2022
AI-Powered Code Reviews for Best Practices & Security Issues Across Languages
AI-Powered Code Reviews for Best Practices & Security Issues Across Languages

AI-CodeWise ?? AI-Powered Code Reviews for Best Practices & Security Issues Across Languages AI-CodeWise GitHub Action: Your AI-powered Code Reviewer!

May 11, 2023
A drop-in replacement for Go errors, with some added sugar! Unwrap user-friendly messages, HTTP status code, easy wrapping with multiple error types.
A drop-in replacement for Go errors, with some added sugar! Unwrap user-friendly messages, HTTP status code, easy wrapping with multiple error types.

Errors Errors package is a drop-in replacement of the built-in Go errors package with no external dependencies. It lets you create errors of 11 differ

Dec 6, 2022
Parametrized JSON logging library in Golang which lets you obfuscate sensitive data and marshal any kind of content.
Parametrized JSON logging library in Golang which lets you obfuscate sensitive data and marshal any kind of content.

Noodlog Summary Noodlog is a Golang JSON parametrized and highly configurable logging library. It allows you to: print go structs as JSON messages; pr

Oct 27, 2022
Monmind - obfuscate multiple strings & hide text from binary searching
 Monmind - obfuscate multiple strings & hide text from binary searching

Monmind - obfuscate multiple strings & hide text from binary searching Obfuscation strings in golang code INSTALL You can install monmind by running:

Nov 30, 2022
Jacket of google/wire: advanced DI approach wrapping google/wire for cloud.
Jacket of google/wire: advanced DI approach wrapping google/wire for cloud.

Wire-Jacket: IoC Container of google/wire for cloud-native Jacket of google/wire: advanced DI approach wrapping google/wire for cloud. google/wire : h

Nov 21, 2022
Wrap contains a method for wrapping one Go error with another.

Note: this code is still in alpha stage. It works but it may change subtly in the near future, depending on what comes out of golang/go#52607. Wrap.Wi

Jun 27, 2022
Go package exposing a simple interface for executing commands, enabling easy mocking and wrapping of executed commands.

go-runner Go package exposing a simple interface for executing commands, enabling easy mocking and wrapping of executed commands. The Runner interface

Oct 18, 2022