1. 程式人生 > 程式設計 >Golang二進位制檔案混淆保護操作

Golang二進位制檔案混淆保護操作

Go實在是太棒了。一處編譯,處處執行,沒有依賴,毫無麻煩!

不過麻煩的事情來了。我們寫一個程式,就是想在別人的電腦上執行的。然而,Go語言的預設機制,會洩漏我們的一些資訊,雖然不多,但也有點尷尬。

本文結合網上的一些常用方法,總結出一套通用的簡單易行的保護措施。

減少 golang 二進位制檔案大小

1、刪除除錯符號

預設情況下go編譯出的程式在執行出錯時會輸出自己在哪個執行緒哪個檔案哪個函式哪行出的錯,就像這樣,

Golang二進位制檔案混淆保護操作

圖片來源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 副作用是會增加程式的啟動時間,但也無妨啦!

以上為個人經驗,希望能給大家一個參考,也希望大家多多支援我們。如有錯誤或未考慮完全的地方,望不吝賜教。