Commit Graph

85 Commits (b250b64d2c7ddcf027a916c68e137eccc510b5fc)

Author SHA1 Message Date
pagran bd46c29380
add blacklist for runtime std packages 4 years ago
lu4p 388ff7d1a4
remove buggy number literal obfuscation
Also remove boolean literal obfuscation.
4 years ago
Daniel Martí d3af58b558 complain when GOPRIVATE matches no packages
This is important, because it would mean that we would obfuscate
nothing. At best, it would be confusing; at worst, it could mislead
the user into thinking the binary is obfuscated.

Fixes #20.
Updates #108.
4 years ago
Daniel Martí 81b4c49702 move the "missing -trimpath" test to the slow group (#106)
This shouldn't break often, so it doesn't need to be covered by 'go test
-short'. Moreover, it's still a relatively expensive step, since we end
up reaching package compilation.
4 years ago
Daniel Martí 511779d8ff testdata: set GOPRIVATE in all but two tests (#104)
basic.txt just builds main.go without a module. Similarly, we leave
imports.txt without a GOPRIVATE, to test the 'go list -m' fallback.

For all other tests, explicitly set GOPRIVATE, to avoid two exec calls -
both 'go env GOPRIVATE' as well as 'go list -m'. Each of those calls
takes in the order of 10ms, so saving ~26 exec calls should easily add
to 200-300ms saved from 'go test -short'.
4 years ago
lu4p ea51e78283 Check that all files use LF line endings in CI 4 years ago
Daniel Martí 75e904f6d4
various minor cleanups and fixes (#99)
Error strings should never be capitalized.

A binsubstr line in one of the tests was duplicate and thus useless.

Remove duplicate or trailing spaces in test scripts.

Finally, add a TODO for an optimization I just spotted.
4 years ago
pagran 2735555ab2
Update filename and add line number obfuscation (#94)
Fixes  #2.

Line numbers are now obfuscated, via `//line` comments.
Filenames are now obfuscated via `//line` comments, instead of changing the actual filename.
New flag `-tiny` to reduce the binary size, at the cost of reversibility.
4 years ago
lu4p 7df14ad860 Fix reflect detection if -literals is passed.
Fixes #93.

The second typecheck lead to the creation of different type objects,
which didn't match the types in the blacklist anymore.

It turns out we don't need the second typecheck,
therfore it is now removed.
4 years ago
Daniel Martí cdac2cd3d6 testdata: avoid fmt in the implement test script
Like other tests, importing fmt results in quite a lot of extra work,
due to the lack of build caching.

In this particular test, we wanted fmt.Println so that T.String would be
called in an indirect way, without defining or referencing Stringer
interface in the main package.

We can do that by rolling our own "tinyfmt" package in a dozen or so
lines of code.

Below is how 'go test -short -vet=off -run Script/implement' is
affected, measured via benchcmd and benchstat:

	name                   old time/op         new time/op         delta
	GoTestScriptImplement          3.67s ± 9%          2.65s ±11%  -27.68%  (p=0.008 n=5+5)

	name                   old user-time/op    new user-time/op    delta
	GoTestScriptImplement          8.18s ± 4%          4.55s ± 9%  -44.35%  (p=0.008 n=5+5)

	name                   old sys-time/op     new sys-time/op     delta
	GoTestScriptImplement          1.27s ±12%          0.71s ±13%  -44.07%  (p=0.008 n=5+5)

	name                   old peak-RSS-bytes  new peak-RSS-bytes  delta
	GoTestScriptImplement          145MB ± 1%          145MB ± 2%     ~     (p=1.000 n=5+5)

All in all, we shave about one full second. It doesn't seem to affect
the total 'go test -short' noticeably, but every little bit counts.
4 years ago
pagran 28adbaa73b
Randomize operator (xor, add, subtract) on all obfuscators (#90)
Co-authored-by: lu4p <lu4p@pm.me>
4 years ago
pagran 2eba744530
Add XorSeed obfuscator (#86)
Co-authored-by: lu4p <lu4p@pm.me>
4 years ago
Daniel Martí aa9767b0d2 add a regression test for #82
The test case we had didn't have a realistic-looking module path with a
dot, so we hadn't noticed the bug with IndexByte.

Fix that. We verified that the new test fails if we undo the fix.
4 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.
4 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".
4 years ago
pagran 9c25f4c2b2
Add xorShuffle obfuscator (#85)
* Refactoring

* Rename Xor2 to XorShuffle
4 years ago
pagran c51e08ef37
Add split obfuscator (#81) 4 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.
4 years ago
pagran c2079ac0a1
Add test for literal obfuscators (#80)
* Combine literals-all-obfuscators.txt nad literals.txt
Rewrite literals.txt logic

* Remove unused \s

* Refactoring and add float ast helpers
4 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
4 years ago
lu4p 50d24cdf51 Add float, int, and boolean literal obfuscation.
Add ast helper functions to reduce ast footprint.

Add binsubfloat and binsubint functions for testing.

Fixes #55.
4 years ago
lu4p 705f9d3a28 Fix byte array and untyped constant obfuscation.
Byte arrays were previously,
obfuscated as byte slices.

Untyped constants are now skipped,
because they cannot be replaced with typed variables.
4 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
4 years ago
Daniel Martí 9c4b7d5a44 add the first benchmark and CONTRIBUTING doc 4 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.
4 years ago
Andrew LeFevre 7ede37cc0b
add runtime API to suppress printing fatal errors
Fixes #50.
4 years ago
lu4p f1bf6f91ee
skip literals used in constant expressions
Fixes #39.
4 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.
4 years ago
Daniel Martí 649cc2f6ba strip Go version information from the binary too
Fixes #44.
4 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.
4 years ago
lu4p 234174b418
don't obfuscate some literals which might break typechecking 4 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.
4 years ago
lu4p 0cf8d4e7a6
add seed flag to control how builds are reproducible
Fixes #26.
4 years ago
Daniel Martí 5604a2aa9e avoid importing fmt in strings test
Reduces its 'go test -short' time from ~3s to ~2.4s on my laptop, since
we have to compile fewer dependencies.
4 years ago
Daniel Martí a09b197fe2 remove the code to handle a nil file.Imports
I could not reproduce the supposed panic, even after I was able to reach
a nil x.Imports in that line in question with the modified test.
4 years ago
lu4p dd1fc4ed87
don't replace all consts with vars
In some cases, such as iotas or when constants are later required to be constants,
we could break compilation. Be more conservative.

Fixes #32.
4 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.
4 years ago
Daniel Martí 04e8beed32 testdata: add sections to scripts/test.txt 4 years ago
lu4p 65ceb9b7ca
allow easy inpection of garbled code
Fixes #17.
4 years ago
lu4p 077d02d43a
add basic literal obfuscation, starting with strings
Fixes #16.
4 years ago
Daniel Martí 462f60a307 sto pusing -toolexec directly in the tests
Since we introduced $GARBLE_DIR, we stopped recommending the use of
toolexec directly. It's still possible to set up the right flags and env
vars, but that will be a moving target.

In particular, string obfuscation in #16 will require using $GARBLE_DIR
in more scenarios. A work-in-progress patch for string obfuscation
triggered this test script to start failing for the reason above.

While at it, we don't care about what the second build contains, since
we already compare it with the previous build.
4 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.
4 years ago
Daniel Martí 4bc64ef8fb make detection of reflect more robust
It now works with variables and composite type expressions too.
4 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.
4 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.
4 years ago
Daniel Martí e4b58b1452 reduce unnecessary std imports in tests
Since we have to recompile all dependencies, this reduces a substantial
amount of work, reducing 'go test -short' time from ~16s to ~12s on my
laptop.
4 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.
4 years ago
Daniel Martí 3c97725ccc skip plugin test case on Windows
Spotted by CI.
4 years ago
Daniel Martí 7321b29efe first version of plugins working
Add a caveat about -trimpath too.

Fixes #18.
4 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.
4 years ago