Commit Graph

72 Commits (60231b10b0fa77355be9f7034c7624e651b2d723)

Author SHA1 Message Date
Pagran 60231b10b0 Apply file name protection only for transformed code 5 years ago
Pagran 7aad04f0e7 Rewrite comment cleanup
Fix method shuffling
Added compatibility with marked //go directives methods
5 years ago
Pagran 7d890c474f Refactoring and documentations
Revert debug code
5 years ago
Pagran 971e595d34 Add line obfuscator
Add tiny flag
5 years ago
Daniel Martí d0e01478f0 keep build flags when calling 'go list'
Otherwise any build flags like -tags won't be used, and we might easily
end up with errors or incorrect packages.

The common case with -tags is covered by one of the integration test
scripts. On top of that, we add a table-driven unit test to cover all
edge cases, since there are many we can do quickly in a unit test.

Fixes #82.
5 years ago
Zachary Wasserman fc4eb4f940 Handle ldflags set variable with . in package name
Fixes #84
5 years ago
Daniel Martí 7fe0bf4787 simplify the main code flow somewhat
We don't really care about tools other than "compile" and "link". Stop
trying to keep a complete list.

Use "if err := f(); err != nil {" where it makes sense.

Simplify some declarations, and use a better variable name than "fW".
5 years ago
Daniel Martí 65461aabce reuse a single 'go list -json -export -deps' call
Instead of doing a 'go list' call every time we need to fetch a
dependency's export file, we now do a single 'go list' call before the
build begins. With the '-deps' flag, it gives us all the dependency
packages recursively.

We store that data in the gob format in a temporary file, and share it
with the future garble sub-processes via an env var.

This required lazy parsing of flags for the 'build' and 'test' commands,
since now we need to run 'go list' with the same package pattern
arguments.

Fixes #63.
5 years ago
lu4p 21c67b91b1
Only obfuscate required identifiers (#79)
The following identifiers are now skipped,
because they never show up in the binary:

- constant identifiers
- identifiers of local variables
(includes function params and named returns)
- identifiers of local types
5 years ago
lu4p d48bdbadae 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.

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

Fixes #62
5 years ago
Daniel Martí bad4e52ac4 don't use CombinedOutput for 'go list -json'
Since sometimes it will output warnings to stderr even when succeeding,
such as when having to deal with cgo.

Fixes #27.
5 years ago
Daniel Martí 47b1bc8e6a minor code cleanup for position shuffling
Make the comments a bit more self-explanatory, and reduce unnecessary
verbosity.
5 years ago
lu4p b4ed621eed
Shuffle the order of top-level definitions. (#60) 5 years ago
lu4p b3616f19c4
fix implementedOutsideGo, fixes #56 (#59)
Injected functions were mistaken for functions implemented outside go.

Asm functions:
obj.Scope().Pos() == 0
obj.Scope().End() == 0

Injected functions:
obj.Scope().Pos() == 0
obj.Scope().End() == 1

We now check for the End instead of the Pos.
5 years ago
Andrew LeFevre 7ede37cc0b
add runtime API to suppress printing fatal errors
Fixes #50.
5 years ago
lu4p baae7a46fd
simplify detection of reflection 5 years ago
lu4p f1bf6f91ee
skip literals used in constant expressions
Fixes #39.
5 years ago
Daniel Martí c9bc7bac3b add a bit of code to aid debugging tests 5 years ago
Andrew LeFevre ee18db7ef1 only add crypto dependencies if -literals is passed 5 years ago
Daniel Martí 3e4f3821ea don't leak build version information via a const either
This requires a bit of extra magic to replace one constant in
runtime/internal/sys, but that was simple enough given that we can reuse
a lot of the code to parse the files and write them to a temporary dir.

We can also drop the -X flags, as runtime.buildVersion is based on the
constant that we replace here.

Fixes #44, again.
5 years ago
Daniel Martí 442eb4e139 speed up builds with the compiler's -dwarf=false flag
Generating DWARF in the compiler object files could take as much as 10%
extra CPU time, while we ignore it entirely at the link stage.

Speeds up 'go test -short' from ~19.5s to ~18.5s on my laptop.
5 years ago
Daniel Martí 649cc2f6ba strip Go version information from the binary too
Fixes #44.
5 years ago
Daniel Martí c7d1fc7c60 strip buildid information from linked binaries
Otherwise, one can use 'go tool buildid' to obtain the main package's
build ID, which can make de-obfuscating the main package much simpler.

Fixes #43.
5 years ago
lu4p 234174b418
don't obfuscate some literals which might break typechecking 5 years ago
lu4p 4c64b13506
make -seed=random use the same random seed for all packages
Otherwise, a different random seed per package will break imported names.
5 years ago
lu4p 0cf8d4e7a6
add seed flag to control how builds are reproducible
Fixes #26.
5 years ago
Nicholas Jones ecbcc61a62
handle embedded struct fields with universe scope
Whilst it may not be particularly common, it is legal to embed fields
where the type has universe scope (e.g. int, error, etc). This can
cause a panic in 2 difference places:

- When embedding `error`, a named type is resolved but the package is
nil. The call to `pkg.Name()` results in a panic
- When embedding a basic type such as `int`, no named type is resolved
at all. The call to `namedType(obj.Type()).Obj()` results in a panic

I'm assuming it is OK to return early when a named type cannot be
resolved.. we could let it continue but I think `pkg` should be set to
nil to be correct, so it'd end up returning straight away anyway.
5 years ago
Daniel Martí c6643d37f9 simplify and tidy up the string obfuscation code
Mainly removing unnecessary indentation and newlines, but also other
minor things like making error handling a bit more consistent.
5 years ago
lu4p 65ceb9b7ca
allow easy inpection of garbled code
Fixes #17.
5 years ago
lu4p 077d02d43a
add basic literal obfuscation, starting with strings
Fixes #16.
5 years ago
Daniel Martí 80538f19c7 blacklist struct fields with reflection too
In the added test, the unexported field used to be garbled.

Reflection can only reach exported methods, exported fields, and
unexported fields. Exported methods and fields are currently never
garbled, so unexported fields was the only missing piece.
5 years ago
Daniel Martí 809b7a8dda remove forgotten debug print 5 years ago
Daniel Martí 4bc64ef8fb make detection of reflect more robust
It now works with variables and composite type expressions too.
5 years ago
lu4p 8b898ad0d2
exclude identifiers used via reflection
If reflect.TypeOf or reflect.ValueOf are used on a type declared in the same package,
don't garble that type name or any of its fields.

Fixes #15.
5 years ago
Daniel Martí e8074d4665 support building ad-hoc plugin packages
That is, plugin packages by source file names, not by package path.

Fixes #19.
5 years ago
Daniel Martí 56a1fd0257 support -ldflags=-X=pkg.name=str with garbled names
Because the linker has access to all the build IDs, just like the
compiler, we can support this transparently. Add a test too.

Fixes #21.
5 years ago
Daniel Martí 7321b29efe first version of plugins working
Add a caveat about -trimpath too.

Fixes #18.
5 years ago
Daniel Martí 012d5d6b34 document objOf 5 years ago
Daniel Martí 3617013cd1 clean up the function that walks the syntax tree
Avoiding a type switch for the entire node prevents an indentation
level.

We can obtain obj and pkg early, and return early as well if either is
uninteresting. That means less nil checks later on, which means even
less indentation and complexity.
5 years ago
Daniel Martí f0a609c7fc fix out of bounds panic with "garble build"
Forgot to run all the tests with the last commit.
5 years ago
Daniel Martí 1ef3daf251 clarify usage text, add help flags
Also remove the -toolexec equivalent, as it's becoming longer now that
we have GARBLE_DIR, and it might become out of date in the future again.
We don't want users to assume it will work forever.
5 years ago
Daniel Martí 19e4c098cd make selection of packages configurable via GOPRIVATE
Carefully select a default that will do the right thing when inside a
module, as well as when building ad-hoc packages.

This means we no longer need to look at the compiler's -std flag, which
is nice.

Also replace foo.com/ with test/, as per golang/go#37641.

Fixes #7.
5 years ago
Daniel Martí 04dea79b2d initial support for cgo
I'm sure that the added test case doesn't cover many edge cases, but
it's a start.

Fixes #12.
5 years ago
Daniel Martí 5aaa086e5d don't remove "//go:" compile directives
For example, this broke cgo, since it uses go:linkname.

Updates #12.
5 years ago
Daniel Martí a7da406207 start supporting asm functions better
Spotted while trying to link a program using unix.Syscall, since its
implementation is assembly.

Telling if a function couldn't be garbled isn't trivial. If that
function belongs to an imported package, we only load its export data
instead of type-checking from source, so we don't have all the
information needed.

Instead, use the gc export data importer to import two versions of each
dependency: its original version, for the initial type-checking, and its
garbled version, to check if any of its exported names weren't garbled.

Updates #9.
5 years ago
Daniel Martí d72c00eafd support building modules which require other modules
We use 'go list -json -export' to locate required modules. This works
fine to locate direct module dependencies; since we're building in the
current module, we run 'go list' in the correct directory.

However, if we're building one of those module dependencies, and it has
other module dependencies of its own, we would fail with cryptic errors
like:

	typecheck error: [...] go list error: updates to go.sum needed, disabled by -mod=readonly

This is because we would try to run 'go list' outside of the main
module, probably inside the module cache. Instead, use a $GARBLE_DIR env
var from the top-level 'garble build' call to always run 'go list' in
the original directory.

We add a few small modules to properly test this.

Updates #9.
5 years ago
Daniel Martí b8aec97e86 don't garble any embedded fields
In the added test case, we'd see a failure, since we garbled the name of
the "Embedded" type but not its use as an anonymous field. Garble both.

This might possibly break some reflect code, but it doesn't seem like we
have an option. When we garble a type, it's impossible to tell if it's
going to be used as an anonymous field later.

Updates #9.
5 years ago
Daniel Martí 4d5ad43f10 allow garble to test itself
With this patch, 'go install && garble test' works.
5 years ago
Daniel Martí 1ce5310440 don't garble exported struct fields
They might reasonably affect the behavior of the code, such as when
encoding/json is used without tags.
5 years ago
Daniel Martí b10cce34f8 parse boolean flags differently from string flags
This is important, because "-std -foo" and "-buildid -foo" are entirely
different cases. The first is equivalent to "-std=true -foo" since the
flag is boolean, but the second is equivalent to "-buildid=-foo" since
the flag isn't boolean.

We can keep track of which of the flags we're interested in are boolean,
which isn't much extra work. Also add unit tests; the build ID is a
hash, so it's very hard to write an end-to-end test that reliably has an
ID starting with a dash.
5 years ago