-
-
Notifications
You must be signed in to change notification settings - Fork 254
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
add an "export" command for libraries #369
Comments
It's unclear to me if this means we should keep GOPRIVATE or GOGARBLE support around. On one hand, it makes sense to keep GOGARBLE as a configuration option, because On the other hand, would anyone ever set GOGARBLE directly? When building manually, one would (presumably) always want to obfuscate all packages. When exporting a library like the example above, one would just want to obfuscate the library's packages. One possible use case for GOGARBLE would be to emulate the Right now, I'm still leaning towards phasing out GOGARBLE/GOPRIVATE support. |
Also, I think this command should be akin to |
In the added test case, "garble -literals build" would fail: --- FAIL: TestScripts/literals (8.29s) testscript.go:397: > env GOPRIVATE=test/main > garble -literals build [stderr] # test/main Usz1FmFm.go:1: cannot call non-function string (type int), declared at Usz1FmFm.go:1 Usz1FmFm.go:1: string is not a type Usz1FmFm.go:1: cannot call non-function append (type int), declared at Usz1FmFm.go:1 That is, for input code such as: var append int println("foo") _ = append We'd end up with obfuscated code like: var append int println(func() string { // obfuscation... x = append(x, ...) // obfuscation... return string(x) }) _ = append Which would then break, as the code is shadowing the "append" builtin. To work around this, always obfuscate variable names, so we end up with: var mwu1xuNz int println(func() string { // obfuscation... x = append(x, ...) // obfuscation... return string(x) }) _ = mwu1xuNz This change shouldn't make the quality of our obfuscation stronger, as local variable names do not currently end up in Go binaries. However, this does make garble more consistent in treating identifiers, and it completely avoids any issues related to shadowing builtins. Moreover, this also paves the way for publishing obfuscated source code, such as burrowers#369. Fixes burrowers#417.
In the added test case, "garble -literals build" would fail: --- FAIL: TestScripts/literals (8.29s) testscript.go:397: > env GOPRIVATE=test/main > garble -literals build [stderr] # test/main Usz1FmFm.go:1: cannot call non-function string (type int), declared at Usz1FmFm.go:1 Usz1FmFm.go:1: string is not a type Usz1FmFm.go:1: cannot call non-function append (type int), declared at Usz1FmFm.go:1 That is, for input code such as: var append int println("foo") _ = append We'd end up with obfuscated code like: var append int println(func() string { // obfuscation... x = append(x, ...) // obfuscation... return string(x) }) _ = append Which would then break, as the code is shadowing the "append" builtin. To work around this, always obfuscate variable names, so we end up with: var mwu1xuNz int println(func() string { // obfuscation... x = append(x, ...) // obfuscation... return string(x) }) _ = mwu1xuNz This change shouldn't make the quality of our obfuscation stronger, as local variable names do not currently end up in Go binaries. However, this does make garble more consistent in treating identifiers, and it completely avoids any issues related to shadowing builtins. Moreover, this also paves the way for publishing obfuscated source code, such as burrowers#369. Fixes burrowers#417.
In the added test case, "garble -literals build" would fail: --- FAIL: TestScripts/literals (8.29s) testscript.go:397: > env GOPRIVATE=test/main > garble -literals build [stderr] # test/main Usz1FmFm.go:1: cannot call non-function string (type int), declared at Usz1FmFm.go:1 Usz1FmFm.go:1: string is not a type Usz1FmFm.go:1: cannot call non-function append (type int), declared at Usz1FmFm.go:1 That is, for input code such as: var append int println("foo") _ = append We'd end up with obfuscated code like: var append int println(func() string { // obfuscation... x = append(x, ...) // obfuscation... return string(x) }) _ = append Which would then break, as the code is shadowing the "append" builtin. To work around this, always obfuscate variable names, so we end up with: var mwu1xuNz int println(func() string { // obfuscation... x = append(x, ...) // obfuscation... return string(x) }) _ = mwu1xuNz This change shouldn't make the quality of our obfuscation stronger, as local variable names do not currently end up in Go binaries. However, this does make garble more consistent in treating identifiers, and it completely avoids any issues related to shadowing builtins. Moreover, this also paves the way for publishing obfuscated source code, such as #369. Fixes #417.
I think unidocs obfuscation is cute, I might try to reverse it tomorrow. |
I just realised what is the biggest hurdle with But when exporting, we want to obfuscate all files - no matter the GOOS, GOARCH, or any other build tags. If a package has I can think of two options:
A third option would be to obfuscate in some way that doesn't rely on build tags. But this would require giving up |
2 - what if we consider each tag as a unique build and put all files obfuscated with this tag under this tag as well? This would highly increase the total size (and obfuscation time), but make the resulting package universal and with unique obfuscation for each tag (tags combination?). |
This could multiply the size of Go modules though, so I'd rather avoid it unless there are significant benefits. I don't see any significant benefits, given that I expect that most users would want to publish all the "build tag variants" alongside each other. Spotting the common bits between them wouldn't be that hard. |
I want to publish a private Go library without exposing the source code. I really need this feature and I hope for support. |
Any news? I really need this feature, too! |
This issue is only aspirational no one is actually working on it or planning to. @wubin1989 @jitcor |
So garble can realize the effect similar to unipdf? Or java proguard the kind of obfuscation effect, through the obfuscation configuration file to add obfuscation rules. |
Yes garble export would generate code in a similar manner how unipdf is obfuscated. |
@lu4p do you mean we just need to add "export" command line subcommand, the feature has already implemented, right? |
No this is not implemented |
I implemented something (minimal) like this here: https://github.com/yardenlaif/balagan |
@yardenlaif stared and forked. Many thanks! |
In the context of #276 (comment), I've been thinking that there are scenarios where one might want to obfuscate only some packages: when publishing or packaging an obfuscated library, to be consumed as regular Go packages via source code.
We do sort of support this already, via something like:
Then, the obfuscated source code will be under
out/my.corp/some/library
.I think this use case is valid, given that it's not possible (or at least not easy) to distribute Go libraries without distributing source code too. One such example is unidoc, where its libraries like unipdf are obfuscated then pushed to GitHub.
We already have much of the machinery here, and garble is pretty advanced as a Go obfuscator, so I think it makes sense to take it one step further and make this easier to do. For example, via:
Some key differences compared to how we currently obfuscate code:
Internal packages such as
my.corp/some/library/internal/foo
would still be fully obfuscated, including changing their API names and import paths. That could be a way to tell what packages must remain importable and usable.Otherwise, I think obfuscation could stay the same: stripping unexported names, position information, most comments, etc.
We might have to tweak our obfuscator to collapse newlines, too - right now, it does that via
/*line
comments for the compiler, but newlines in the printed source code remain, since those don't affect binaries. They affect published source code, though - and it's also likely that those compiler directives shouldn't be present in this new mode.The text was updated successfully, but these errors were encountered: