如何保护(混淆)Go二进制文件,防止被破解。

16
我希望出售Go应用程序。我会向我的客户提供序列号。有没有方法使破解应用程序变得更加复杂? 我说破解C应用程序很复杂,而破解Java应用程序很容易。是否有工具可以使Go应用程序的破解工作像破解C应用程序一样困难?或者有一些教程吗?至少有些我可以做的事情来保护我的项目。我不要求超级重型保护。

2
由于您似乎不确定是否应该使用混淆,建议阅读此问题。链接 - nemo
1
据我所知,目前还没有办法使您的二进制文件无法反编译。当然,您可以尽可能地增加反编译的难度,但是我建议您寻找其他保护应用程序的方法,而不是仅仅使用模糊化技术。 - ymg
2
实际上,反编译C二进制文件比反编译Java二进制文件要困难得多,因为Java编译器的变化不是很大。一个.class文件与原始的.java文件有很多相似之处,但如果你编译一个C源代码并剥离它的符号,几乎所有的结构信息都会丢失。 - fuz
@FUZxxl 这就是我说的。一旦我丢失了Jar文件的源代码,反编译jad只有一个错误(goto)。.class就是源代码。 - Shuriken
@YasirG。我并不希望让它变得不可能。我只想做一些基本的步骤,这些步骤是合理的,比如junitas提到的链接器标志“-s”。 - Shuriken
3个回答

8
一旦您拥有二进制文件本身,混淆就变得非常困难。人们之前尝试过从Go二进制文件中剥离符号,但通常会导致不稳定和不可预测的行为,因为某些反射操作需要符号。
虽然您不能必然地混淆静态链接到的库,但您肯定可以通过在编译之前更改变量、类型和函数名称以及更改为无意义的名称来混淆自己的代码。如果您想再进一步,可以尝试获取您使用的库的源代码(标准库的源代码可用,并且包含在大多数Go安装程序中),并将此混淆应用于库源代码。
至于后编译二进制文件修改,正如我之前提到的,最好远离它。

7
补充joshlf13的回答:尽管不建议剥离Go二进制文件,但有一个标志可以传递给链接器以省略整个调试符号:
使用“-s”标志传递给链接器以省略调试信息(例如,go build -ldflags“-s”prog.go)。
(在使用GDB调试Go代码中)
至少这应该是一种更好的方法,因为我没有看到任何有关剥离编译后符号的警告。

1
你知道它能移除多少吗? 我怀疑它不能全部移除,因为反射还需要正常工作。 - joshlf
2
我不确定反射是如何实现的,但它似乎是在Go运行时本身完成,而不依赖于调试符号。即使没有调试符号,在这个程序中运行得很好。这个程序 - justinas
1
这种像(*runtime.Func).Name()的东西让我觉得还有一些信息仍然存在。 - joshlf
2
哦,糟糕了。看起来它会采取激进的方式,即使它会破坏运行时反射。请查看此代码片段(它获取main函数的地址,然后使用反射找到函数的名称)。 - joshlf
2
似乎在后续版本中已经修复:使用Go 1.2编译它,它可以正常工作 - justinas

3

另一个选项,使用 Go 1.16+ (2021年2月):

burrowers/garble

生成一个二进制文件,它能够像常规构建一样工作,但是对于原始源代码的信息尽可能少。

该工具旨在:

  • cmd/go 结合使用,以支持模块和构建缓存
  • 确定性和可重现性,给定相同的初始源代码
  • 在给定原始源代码的情况下是可逆的,以解密 panic 堆栈跟踪

这可能对您的需求来说还不够模糊,但这是一个很好的开始。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接