Golang二进制文件混淆保护操作

 更新时间:2020年12月17日 10:49:36   作者:niconicoSnap  
这篇文章主要介绍了Golang二进制文件混淆保护操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧

Go实在是太棒了。一处编译,处处运行,没有依赖,毫无麻烦!

不过麻烦的事情来了。我们写一个程序,就是想在别人的电脑上运行的。然而,Go语言的默认机制,会泄漏我们的一些信息,虽然不多,但也有点尴尬。

本文结合网上的一些常用方法,总结出一套通用的简单易行的保护措施。

减少 golang 二进制文件大小

1、删除调试符号

默认情况下go编译出的程序在运行出错时会输出自己在哪个线程哪个文件哪个函数哪行出的错,就像这样,

图片来源StackOverflow

DWARF信息对于小黑客们可是如获至宝,这些关键信息不能留下。而且去掉这些东西也非常简单:

go build -ldflags "-s -w” [<your/package]

(需要Go版本大于1.7)

这里的 -ldflags 参数最终会在 go tool link 的时候传给它, go tool link -h解释如下

...

-s disable symbol table

-w disable DWARF generation

删除掉调试符号的另一个好处就是,显著减小了文件大小(平均20%)

-rwxr-xr-x 1 tim staff 1636736 May 5 11:59 bin/hello <- 标准编译

-rwxr-xr-x 1 tim staff 1190272 May 5 11:59 hello <- stripped

再加一个UPX壳,还可以压缩到原文件大小的五分之一!不知道为啥,go语言的二进制特别好压!

2、删除trace文件信息

在go中触发 panic 时,上图的文件目录也是泄漏信息的一部分。比如上图就包括了小黑客用的操作系统(Linux),小黑客的名字(nikos),如果你用homebrew版本的Go还会泄漏你的编译器版本。所以这些当然也要删掉!

这些信息的来源是编译器运行时所处环境的环境变量。

上图中的函数编译时,环境变量就是这样。

GOROOT=/opt/goGOPATH=/home/nikos/projects/goGOROOT_FINAL=$GOROOT

这几个都是可以改的哦。根据参考资料,编译时GO会从$GOPATH寻找我们自己的代码,从$GOROOT提取标准库,在打包时将GOROOT改写为GOROOT_FINAL并作为trace信息的一部分写入目标文件。改写$GOPATH的方式也很简单,在一个不起眼的目录里对真实的GOPATH创建一个软链接(快捷方式),编译器在寻找时就会把快捷方式的目录名写到最终文件里,从而达到我们隐藏自己的目的。

话不多说,上代码。放到自己的.bash_profile或.zshrc中即可

ACTUAL_GOPATH="~/Programming/go"
export GOPATH='/tmp/go'
export GOROOT_FINAL=$GOPATH
 [ ! -d $GOPATH ] && ln -s "$ACTUAL_GOPATH" "$GOPATH"
 [[ ! $PATH =~ $GOPATH ]] && export PATH=$PATH:$GOPATH/bin

我个人把GOROOT_FINAL也写入为GOPATH,其实这个字符串可以是任意值,但写成一样的话,可以让逆向人员无法分辨,调用的库是我们自己写的还是go语言的标准库。非常猥琐哦~

这样一来,生成的二进制文件就相当于其他语言编译时的Release版本了。再发散一下,自己写一个库,将关键的字符串做成外部资源并在调用时解密,代码中不保留明文,再破解就只能人肉跟踪函数了。满分!

3.使用 UPX 给程序加壳

UPX 不仅能大幅压缩 Golang 静态编译的二进制程序,更能有效的增加反汇编的难度。具体命令为:

upx --brute [ binary ]

UPX 副作用是会增加程序的启动时间,但也无妨啦!

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。如有错误或未考虑完全的地方,望不吝赐教。

相关文章

  • 云端golang开发,无需本地配置,能上网就能开发和运行

    云端golang开发,无需本地配置,能上网就能开发和运行

    这篇文章主要介绍了云端golang开发,无需本地配置,能上网就能开发和运行的相关资料,需要的朋友可以参考下
    2023-10-10
  • 详解如何使用Go模块进行依赖管理

    详解如何使用Go模块进行依赖管理

    本文将介绍Go语言中的模块(module)概念,以及如何使用Go模块进行依赖管理,我们会探讨模块的基本概念、使用方法、配置和依赖关系管理等方面的内容,需要的朋友可以参考下
    2023-10-10
  • Golang实现Redis过期时间实例探究

    Golang实现Redis过期时间实例探究

    这篇文章主要介绍了Golang实现Redis过期时间实例探究,
    2024-01-01
  • Go语言copy()实现切片复制

    Go语言copy()实现切片复制

    本文主要介绍了Go语言copy()实现切片复制,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-04-04
  • 浅析Go语言中闭包的定义与使用

    浅析Go语言中闭包的定义与使用

    闭包是编程语言中的一个重要概念,它允许函数不仅仅是独立的代码块,还可以携带数据和状态,本文将深入探讨闭包的定义、用途和注意事项,以及如何正确使用闭包,有需要的可以参考下
    2023-09-09
  • Golang中goroutine和channel使用介绍深入分析

    Golang中goroutine和channel使用介绍深入分析

    一次只做一件事情并不是完成任务最快的方法,一些大的任务可以拆解成若干个小任务,goroutine可以让程序同时处理几个不同的任务,goroutine使用channel来协调它们的工作,channel允许goroutine互相发送数据并同步,这样一个goroutine就不会领先于另一个goroutine
    2023-01-01
  • 关于golang监听rabbitmq消息队列任务断线自动重连接的问题

    关于golang监听rabbitmq消息队列任务断线自动重连接的问题

    这篇文章主要介绍了golang监听rabbitmq消息队列任务断线自动重连接,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-03-03
  • Go中字符串处理 fmt.Sprintf与string.Builder的区别对比分析

    Go中字符串处理 fmt.Sprintf与string.Builder的区别对比分析

    在Go语言中,我们通常会遇到两种主要的方式来处理和操作字符串:使用fmt.Sprintf函数和string.Builder类型,本文给大家介绍它们在性能和用法上有一些关键区别,感兴趣的朋友跟随小编一起看看吧
    2023-11-11
  • Golang中基础的命令行模块urfave/cli的用法说明

    Golang中基础的命令行模块urfave/cli的用法说明

    这篇文章主要介绍了Golang中基础的命令行模块urfave/cli的用法说明,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-12-12
  • Golang实现文件夹的创建与删除的方法详解

    Golang实现文件夹的创建与删除的方法详解

    这篇文章主要介绍了如何利用Go语言实现对文件夹的常用操作:创建于删除。文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2022-05-05

最新评论