|
|
|
env GOPRIVATE=test/main
|
|
|
|
|
|
|
|
garble -debugdir ./test1 build
|
|
|
|
exists 'test1/test/main/imported/imported.go' 'test1/main/main.go'
|
|
|
|
! grep ImportedFunc $WORK/test1/test/main/imported/imported.go
|
|
|
|
! grep ImportedFunc $WORK/test1/main/main.go
|
|
|
|
! grep 'some comment' $WORK/test1/main/main.go
|
|
|
|
|
|
|
|
[short] stop
|
|
|
|
|
|
|
|
# Sources from previous builds should be deleted
|
|
|
|
cp $WORK/test1/main/main.go $WORK/test1/some_file_from_prev_build.go
|
|
|
|
|
|
|
|
garble -debugdir ./test1 build -v
|
reimplement import path obfuscation without goobj2 (#242)
We used to rely on a parallel implementation of an object file parser
and writer to be able to obfuscate import paths. After compiling each
package, we would parse the object file, replace the import paths, and
write the updated object file in-place.
That worked well, in most cases. Unfortunately, it had some flaws:
* Complexity. Even when most of the code is maintained in a separate
module, the import_obfuscation.go file was still close to a thousand
lines of code.
* Go compatibility. The object file format changes between Go releases,
so we were supporting Go 1.15, but not 1.16. Fixing the object file
package to work with 1.16 would probably break 1.15 support.
* Bugs. For example, we recently had to add a workaround for #224, since
import paths containing dots after the domain would end up escaped.
Another example is #190, which seems to be caused by the object file
parser or writer corrupting the compiled code and causing segfaults in
some rare edge cases.
Instead, let's drop that method entirely, and force the compiler and
linker to do the work for us. The steps necessary when compiling a
package to obfuscate are:
1) Replace its "package foo" lines with the obfuscated package path. No
need to separate the package path and name, since the obfuscated path
does not contain slashes.
2) Replace the "-p pkg/foo" flag with the obfuscated path.
3) Replace the "import" spec lines with the obfuscated package paths,
for those dependencies which were obfuscated.
4) Replace the "-importcfg [...]" file with a version that uses the
obfuscated paths instead.
The linker also needs that last step, since it also uses an importcfg
file to find object files.
There are three noteworthy drawbacks to this new method:
1) Since we no longer write object files, we can't use them to store
data to be cached. As such, the -debugdir flag goes back to using the
"-a" build flag to always rebuild all packages. On the plus side,
that caching didn't work very well; see #176.
2) The package name "main" remains in all declarations under it, not
just "func main", since we can only rename entire packages. This
seems fine, as it gives little information to the end user.
3) The -tiny mode no longer sets all lines to 0, since it did that by
modifying object files. As a temporary measure, we instead set all
top-level declarations to be on line 1. A TODO is added to hopefully
improve this again in the near future.
The upside is that we get rid of all the issues mentioned before. Plus,
garble now nearly works with Go 1.16, with the exception of two very
minor bugs that look fixable. A follow-up PR will take care of that and
start testing on 1.16.
Fixes #176.
Fixes #190.
4 years ago
|
|
|
stderr 'test/main' # we force rebuilds with -debugdir
|
|
|
|
! exists $WORK/test1/some_file_from_prev_build.go
|
|
|
|
|
|
|
|
-- go.mod --
|
|
|
|
module test/main
|
|
|
|
|
|
|
|
go 1.15
|
|
|
|
-- main.go --
|
|
|
|
package main
|
|
|
|
|
|
|
|
import "test/main/imported" // some comment
|
|
|
|
|
|
|
|
type someType int // some comment
|
|
|
|
var someVar = 0
|
|
|
|
|
|
|
|
type someStruct struct {
|
testdata: make syntax.txt pass when offline
The test intended to use an extra module to be obfuscated, rsc.io/quote,
which we were bundling in the local proxy as well. Unfortunately, the
use of GOPRIVATE also meant that we did not actually fetch the module
from the proxy, and we would instead do a full roundtrip to the internet
to "git clone" the actual upstream repository.
To prevent that roundtrip, instead use a locally replaced module. This
fits the syntax.txt test too, since it's one more edge case that we want
to make sure works well with garble. Since rsc.io/quote is used in
another test, simply make up our own tiny module.
Reduces a 'go test -run Syntax/syntax' run with warm cache from ~5s to
~0.5s, thanks to removing the multiple roundtrips. A warm 'go test' run
still sits at ~6s, since we still need that much CPU time in total.
While at it, fix a staticcheck warning and fix inconsistent indentation
in a couple of tests.
5 years ago
|
|
|
someField int // some comment
|
|
|
|
}
|
|
|
|
|
|
|
|
func main() {
|
|
|
|
imported.ImportedFunc()
|
|
|
|
}
|
|
|
|
|
|
|
|
-- imported/imported.go --
|
|
|
|
package imported
|
|
|
|
|
|
|
|
func ImportedFunc() {}
|