Skip to content
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

reduce Go code to its simplest form before obfuscation #459

Closed
mvdan opened this issue Jan 14, 2022 · 4 comments
Closed

reduce Go code to its simplest form before obfuscation #459

mvdan opened this issue Jan 14, 2022 · 4 comments
Labels
enhancement New feature or request

Comments

@mvdan
Copy link
Member

mvdan commented Jan 14, 2022

Obfuscation is all about reducing the amount of useful information from code. We already do the easy ones like filenames and names, as well as literal obfuscation, but we don't do much at all about the chunks of code: they largely retain their structure at the moment.

As a first step to improve with that, I propose that we make garble alter the code to reduce the amount of ways that certain operations can be written in. Code authors will tend to write code in a way that helps readability, but we want to strip that away. For example:

  • We'd simplify all declarations, such as foo := bar, to var foo = bar
  • We'd split all groups, such as var foo, bar string to var foo string; var bar string, and func(foo, bar string)
  • We'd sort all composite literal keys, such as T{Before: X, After: X} to T{After: X, Before: X}, and likewise for maps
  • We'd likewise sort all field lists, such as interface method lists - but not struct fields, as those may affect performance
  • We'd deterministically shuffle or reorder integer/float/string expression switch cases, as their respective values must be unique
  • We'd remove all newlines that gofmt doesn't enforce, to break logical separators such as those found in multi-line lists

It's worth noting that many of these don't matter right now, because their information is already gone via the process of a garble build. For instance, removing newlines shouldn't matter as we replace all recorded position via compiler directives.

However, I still think this would be a generally useful idea for three reasons:

  1. Some of these may still make it into the final obfuscated binary, such as the order of map keys or switch cases.
  2. If we force code to use a simpler and more consistent form, it should be easier to obfuscate. For instance, I'm trying to fix "unknown field in struct literal" errors with cgo-exported struct type #401 now, and having to deal with all the different forms of var foo = "bar" to insert a string value is tricky.
  3. We'd need the ones that don't matter for binaries for the sake of producing obfuscated code, such as for add an "export" command for libraries #369.

Ideas welcome. This enhancement has been in my mind for a few days, but I haven't thought about it that hard - it's likely that the idea needs some polishing.

@lu4p
Copy link
Member

lu4p commented Jun 26, 2023

We could now do ast -> ssa -> simple ast, is this still something you want to do @mvdan ?

@mvdan
Copy link
Member Author

mvdan commented Jul 15, 2023

Assuming that @pagran's SSA->AST feature can work on every Go function, this issue would be fixed.

@pagran
Copy link
Member

pagran commented Jul 15, 2023

I think ssa->ast works on every function :)

@mvdan
Copy link
Member Author

mvdan commented Jul 15, 2023

Gotcha. Let's close this as fixed, then; we can keep #462 open for turning on control flow obfuscation by default for all funcs.

@mvdan mvdan closed this as completed Jul 15, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Development

No branches or pull requests

3 participants