765 Commits

Author SHA1 Message Date
Daniel Martí
33e574685b support reversing asm filenames
Which can be helpful when debugging assembly build errors
such as the one from #948.
I could not get an obfuscated binary to ever print or show its
assembly positions or filenames, so this has no test.
2025-09-09 01:57:17 +01:00
jtimperio
28f7a7ffbf refactor main into pieces
* reflect_abi_patch.go was added into reflect.go
* shared.go was renamed into cache_shared.go and package caching was moved to cache_pkg.go
* transformer methods in main.go are moved to transformer.go
2025-09-09 00:28:15 +01:00
Daniel Martí
6dab979d1c CHANGELOG: add entry for v0.15.0 v0.15.0 2025-08-31 18:15:32 +01:00
Daniel Martí
cb4cb3cfca internal/literals: modernize -fix 2025-08-31 18:05:26 +01:00
Daniel Martí
36fcc61c4e support testing/synctest when a non-test package imports "testing" too
As spotted by scripts/check-third-party.sh, it's possible to import
the testing package without using `go test`, so our previous solution
to only load testing/synctest when running `go test` was not enough.

Add a regression test via stdimporter in gogarble.txtar.
2025-08-30 21:38:24 +01:00
Daniel Martí
298a131506 update obfuscatedImportPath list of skipped packages for Go 1.25
New packages in Go's "allowAsmABIPkgs" list caused failures
in gogarble.txtar's use of `garble build std`.
2025-08-30 21:38:24 +01:00
Daniel Martí
176426755c update golang.org/x dependencies 2025-08-30 21:38:24 +01:00
Daniel Martí
193f19ab5f use x/tools/cmd/bundle via go tool
The behavior is the same, but now we track the dependency in go.mod
via `go get -tool`, which is a better approach.

While here, make a package loading error slightly clearer.
2025-08-30 21:38:24 +01:00
Daniel Martí
aed2fd2659 add support for Go 1.25 and drop support for 1.24
While strictly speaking it would be okay to leave Go 1.24 support
in place for the time being, we are behind on a few tasks at the moment
so it's best to keep the setup at master simpler for the next release.
Go 1.25 already came out two weeks ago, and it seems to have been
a fairly smooth release, so I don't suspect any end users will have
trouble upgrading to it.

Note that two changes were necessary for garble to work on Go 1.25.0.

First, we stop deduplicating runtimeAndLinknamed with runtimeAndDeps.
Otherwise, for GOOS=windows, internal/runtime/cgroup would be missing
as it is a //go:linkname target from runtime on all platforms,
but it is not transitively imported from runtime on GOOS=windows.

Second, the testing/synctest package is now part of std,
and it is a //go:linkname target from the testing package
but not a transitive import from it. Teach appendListedPackages that,
when loading all packages for a `go test` run, it should load
the new testing/synctest package too.

Fixes #968.
2025-08-30 21:38:24 +01:00
bobo liu
1b9c305df2 obey build flags in garble reverse
Fixes an unintentional regression in 6ac80db02c.
2025-08-08 00:17:22 +01:00
Daniel Martí
59eee83beb clarify why TestScript sets GONOSUMDB (#958)
And unset it in gotoolchain.txtar, as that one testscript
does fetch modules from the real proxy.golang.org.

Closes #950.
2025-06-15 19:16:51 +02:00
Paul Scheduikat
87ebebb520 format testscript files with gofmt 2025-06-15 17:25:20 +01:00
Paul Scheduikat
8d8ba00515 properly handle controlflow obfuscation in code that uses unsafe
Due to unsafe not being a real dependency, type checking during control-flow obfuscation was performed incorrectly.
This is fixed by excluding unsafe from the dependency checks.


Fixes #903
2025-06-12 14:25:09 +02:00
pagran
d47e0761eb Prevent automated plaintext extraction of literals with current tools (#930)
Some programs which could automatically reverse string literals obfuscated with `-literals` exist.

They currently work by emulating the string literal decryption functions we insert.

We prevent this naive emulation from succeeding by making the decryption functions dependent on global state.

This can still be broken with enough effort, we are curious which approach reverse-engineers come up with next, we certainly still have some ideas to make this harder.

Fixes #926
---------

Co-authored-by: Paul Scheduikat <lu4p@pm.me>
2025-06-03 02:37:51 +02:00
Daniel Martí
be4462bc23 .github: tweak template to ask for garble version
I forgot to update the original Go template away from `go version`.
Note that `go env` already tells us what we need via e.g. GOVERSION,
so we can avoid asking for `go version` separately.
2025-04-28 02:37:01 +02:00
Daniel Martí
6dca875017 remove two misguided TODOs
The way computePkgCache caches per-package results in GARBLE_CACHE,
under normal circumstances where a user isn't deleting GARBLE_CACHE
we will only load gob files for direct imports, not indirect ones.
Hence, loading a package's gob file twice is not happening normally.

And the way we use go/types, we don't need to set Config.GoVersion.
2025-04-26 16:42:54 +02:00
Daniel Martí
9cf2a6a77f properly patch the linker when GOROOT is a symlink
Some Go version managers like github.com/voidint/g use GOROOT symlinks,
which silently broke the way we patch the linker via go build -overlay.

Reproduced the original crash via the following testscript:

    env GARBLE_CACHE=${WORK}/garble-cache
    symlink goroot -> /usr/lib/go
    env GOROOT=${WORK}/goroot
    exec garble run main.go

    -- main.go --
    package main

    import "fmt"

    func main() {
        fmt.Println("hello world")
    }

We don't commit this testscript given how it's an expensive test
and for a relatively rare edge case whose fix is now well documented.
Moreover, as GOTOOLCHAIN is now available, I expect version managers
for Go to fade away with time.

While here, remove a debugging 'exec cat' from a testscript.

Fixes #915.
2025-04-26 16:42:15 +02:00
Daniel Martí
62050d8e16 .github: move to the new YAML-based github issue templates
Our ISSUE_TEMPLATE.md helpfully stopped working without any warning.
I only noticed as we started getting low-quality bug reports.

This YAML borrows a bit from Go's own bug report template,
much like we had done previously with our markdown template.
2025-04-26 12:13:21 +02:00
Daniel Martí
b9e8908d31 CI: stop testing on Go 1.23
We only support Go 1.24 at this point; I forgot to update CI.
2025-04-22 14:55:58 +02:00
Daniel Martí
aa67c654dc refuse to obfuscate bytedance/sonic/loader
Or any other package which uses a //go:linkname to the runtime names
"lastmoduledatap" or "moduledataverify1". These are used by sonic
to inject function headers to the runtime, which does not work
as garble patches the runtime as part of obfuscation.
The way it alters the magic number in function headers breaks this.

Add a summary of this as a comment too.

Fixes #898.
2025-04-22 14:55:58 +02:00
Daniel Martí
db4c8e52d5 add a testscript with the linknames that bytedance/sonic/loader has
For #898.
2025-04-22 14:55:58 +02:00
Daniel Martí
b34a7e3926 avoid patching our reflect code into _cgo_gotypes.go
When obfuscating a main package whose Go files all import "C",
the first Go file in CompiledGoFiles ends up being _cgo_gotypes.go.
We cannot add our code from reflect_abi_code.go there,
as it leads to the following error about its _trieNode type:

    typecheck error: $WORK/b001/_cgo_gotypes.go:185:10: cannot define new methods on non-local type _trieNode

Avoid patching any _cgo_*.go file with our reflect code,
as all of those files are special glue code for cgo.

While here, tweak reflectMainPrePatch to return a string
for consistency with abiNamePatch.

Fixes #916.
2025-04-21 07:41:15 +02:00
Daniel Martí
b5d90cb1bd expose cgo issue 916
Seems to happen when the main package only has Go files importing "C",
meaning that it has zero "pure Go" files.

To avoid needing two main package Go builds for cgo.txtar,
switch our main package to this scenario as it seems more interesting.

While here, add a test case for a Go callback function taking a C param
as that is relatively common and we had no coverage for it.

This only reproduces the bug; the fix is coming separately.

For #916.
2025-04-21 07:41:15 +02:00
Daniel Martí
32e1e0aa2b take advantage of some APIs added in Go 1.24
Primarily new iterator APIs in the strings and go/types packages.

While here, verify that the processImportCfg hack is stil needed
as of go1.24.2.
2025-04-13 23:10:38 +02:00
Daniel Martí
2bb1d49874 rely on go build stamping a version for local builds
Before Go 1.24, `go build` only stamped module versions for modules
resolved via GOPROXY, as the local module only had VCS information.
For that reason, we manually built a pseudo-version from the VCS
timestamp and revision stamped for local builds.

Go 1.24 started stamping the main module with a module version
derived from the local VCS information, much like we already did.
For example, comparing a clean build before this change
against a build with this uncommitted change:

    $ go install
    $ garble version
    mvdan.cc/garble v0.14.3-0.20250413182748-e97968ccae46
    [...]
    $ git stash pop
    $ go install
    $ garble version
    mvdan.cc/garble v0.14.3-0.20250413182748-e97968ccae46+dirty
    [...]

The only user-visible change is that local builds with any
uncommitted changes now get a `+dirty` suffix, but that's probably
a good thing for the majority of users, and provides a useful hint
in case a user forgot about local changes.

The test logic to inject VCS information via an env var
and see that the resulting pseudo-version is what we expect can go too,
as that was testing our own main module version logic.
We now rely on `go build` to do the right thing, so don't test that.
2025-04-13 23:10:38 +02:00
Daniel Martí
ffed9e5438 drop support for Go 1.23
A pretty small patch, given that 1.23 and 1.24 are quite similar
in terms of what garble does.
2025-04-13 23:10:38 +02:00
Daniel Martí
ad998763a2 CHANGELOG: add entry for v0.14.2 v0.14.2 2025-04-13 19:22:34 +01:00
Daniel Martí
591741b30b update golang.org/x/tools before releasing 2025-04-13 19:15:06 +01:00
Daniel Martí
a3a92356d9 refuse to delete unknown files with -debugdir
When creating a new debugdir directory, add a sentinel .garble-debugdir
file at its root so that we can later know that we created it
and the user is very unlikely to have left important data there.

When emptying an existing debugdir directory, only do so if it has
that sentinel file, for added safety.

Fixes #932.
2025-04-05 15:51:00 +01:00
Daniel Martí
8ee4c91196 make gotoolchain.txtar upgrade to the host's GOVERSION
On CI we test on go1.23.x and go1.24.x, so if we always upgrade
to the latest go1.24.x, that will cause garble to complain
when running on go1.23.x:

    garble was built with "go1.23.7" and can't be used with the newer "go1.24.1"

Moreover, the test hard-coded go1.24.1, which is currently the latest
go1.24.x but will not be for long, so this test was brittle.
2025-03-31 01:34:31 +02:00
Daniel Martí
db3003b9fa use the correct toolchain "go" tool under GOTOOLCHAIN=auto
We call `go list` to collect information about all the packages
to obfuscate and build, which is crucial to be able to perform
obfuscation of names used across packages.

However, when GOTOOLCHAIN causes a toolchain upgrade,
we must ensure that we use the upgraded Go tool;
otherwise we are mixing information from different toolchain versions.

Fixes #934.
2025-03-31 01:34:31 +02:00
Daniel Martí
7f80dfb59d rebuild cmd/link with the correct toolchain under GOTOOLCHAIN=auto
When we build the patched cmd/link binary for use by garble,
we perform this build in a temporary directory so that the Go module
from the user does not get in the way.

When the user module made us upgrade the toolchain per GOTOOLCHAIN,
leaving that module's directory stops upgrading the toolchain,
so we patch a newer toolchain and build it with an older toolchain.
This is largely harmless, but it makes the newer toolchain think
it is actually an older toolchain, which leads to those pesky
"linker object header mismatch" version errors.

Updates #934.
2025-03-31 01:34:31 +02:00
Daniel Martí
6f7af3b785 add test reproducing gotoolchain upgrade errors
While here, make link.version more readable by adding a newline
and document the assumption it makes about GOVERSION.

For #934.
2025-03-31 01:34:31 +02:00
Daniel Martí
ad47efbe72 actually collect intrinsics from Go 1.24
The diffstat for go_std_tables.go shows that we were missing
more than two dozen new intrinsic functions from Go 1.24,
which could lead to the intrinsification done by the toolchain
to no longer work and leave programs with slower generic functions.
2025-03-29 02:09:34 +01:00
Daniel Martí
ff989a15b8 regenerate tables with the latest Go versions
These will typically not cause changes, but just in case.
2025-03-06 23:39:54 +01:00
Daniel Martí
c23dd1672b use LC_ALL=C rather than LANG=en_US
LC_ALL overrides all settings rather than setting a default.
And C is the English locale that should be used for scripting.
2025-03-06 23:39:54 +01:00
Daniel Martí
96a954792d update dependencies 2025-03-06 23:39:54 +01:00
Daniel Martí
cb83c50b13 all: run gopls's modernize -fix
Except on reflect_abi_code.go, as that needs to be compatible
with older versions of Go given that we inject its code.
2025-02-22 15:05:23 +00:00
Daniel Martí
fa2e718bd1 start using go/ast.Preorder
Thanks to being able to use range-over-func, some control flow
in our code gets simplified.
2025-02-22 15:05:23 +00:00
Daniel Martí
275737aabd start using go/types.Func.Signature
Guaranteed to return a *types.Signature, so no need to type assert.
2025-02-22 15:05:23 +00:00
Daniel Martí
2e9cd84bde CHANGELOG: prepare for a bugfix release
A minor version bump seems unnecessary when we are just adding support
for a new Go version, and that support was very easy to do.
v0.14.1
2025-02-12 03:30:06 +01:00
Daniel Martí
3936ebfe5d update to Go 1.24.0 and test with it on CI as well 2025-02-12 03:30:06 +01:00
Daniel Martí
2adfc43326 bump unsupportedGo to mark Go 1.24 as supported
debugdir.txtar also needed tweaking as runtime/map.go is gone
starting in Go 1.24.

Finally, modinfo.txtar needed tweaking since Go 1.24 started stamping
Go binaries with VCS-derived module versions, so we no longer end up
with empty "(devel)" versions.
2025-02-09 21:41:54 +01:00
Daniel Martí
e8392a640a update go_std_tables.go with go1.24rc3 2025-02-09 21:41:54 +01:00
Daniel Martí
28ccfa094b internal/linker: add Go patches rebased on go1.24rc3
See https://github.com/burrowers/go-patches/pull/8.
2025-02-09 21:41:54 +01:00
Daniel Martí
561158dca9 CHANGELOG: v0.14.0 is happening today v0.14.0 2025-01-26 21:41:07 +00:00
Daniel Martí
f90cc05f6d CHANGELOG: write release notes for the upcoming release 2025-01-23 16:49:21 +01:00
Paul Scheduikat
97833204f8 skip all type parameters in recordType
We only did this for Container in the type switch, but not for Struct.
The added test case panics otherwise.
Just like in the previous case, we still don't need to recurse
into type parameters for fieldToStruct to be filled correctly.

Fixes #899
2025-01-19 14:13:55 +00:00
Daniel Martí
e6c0aeffe1 README: we require Go 1.23.5 now 2025-01-19 02:45:52 +01:00
Daniel Martí
f5dc4e784a simplify reflectInspector method signatures
A parent paramter was unused, and a cache parameter could be reached
via the receiver.
2025-01-19 02:45:52 +01:00