宅宅很神 發表於 2023-5-24 20:12:13

Golang 二進制文件混淆保護

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

不過麻煩的事情來了。我們寫一個程序,就是想在別人的電腦上運行的。然而,Go 語言的默認機制,會泄漏我們的一些信息,雖然不多,但也有點尷尬。本文結合網上的一些常用方法,總結出一套通用的簡單易行的保護措施。

刪除一些測試時的訊息

默認情況下 go 編譯出的程序在運行出錯時會輸出自己在哪個線程哪個文件哪個函數哪行出的錯,就像這樣,



DWARF 這些關鍵訊息很危險,但且去掉這些東西也非常簡單:(需要 Go 版本大於 1.7)

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

加上 -ldflags 參數 -s -w 的意義如下



去除這些資訊一來有保密效果,也減少了檔案大小(約變為原本的1/5)

刪除 trace 文件信息

在 go 中觸發 panic 時,上圖的文件目錄也是泄漏信息的一部分。比如上圖就包括了小黑客用的操作系統(Linux),小黑客的名字(nikos),如果你用 homebrew 版本的 Go 還會泄漏你的編譯器版本。所以這些當然也要刪掉!

這些信息的來源是編譯器運行時所處環境的環境變量。

上圖中的函數編譯時,環境變量就是這樣。

GOROOT=/opt/go
GOPATH=/home/nikos/projects/go
GOROOT_FINAL=$GOROOT

這幾個都是可以改的哦。根據參考資料,編譯時 GO 會從尋找我們自己的代碼,從 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 版本了。再發散一下,自己寫一個庫,將關鍵的字符串做成外部資源並在調用時解密,代碼中不保留明文,再破解就只能人肉跟蹤函數了。滿分!

來源:
zhuanlan.zhihu.com/p/26733683









頁: [1]
檢視完整版本: Golang 二進制文件混淆保護