華為云計算 云知識 go語言逆向技術(shù)之---常量字符串解密
go語言逆向技術(shù)之---常量字符串解密

【摘要】go語言編譯出來的二進制文件中,字符串數(shù)據(jù)是如何存放的,逆向時如何快速和準確的識別出源代碼中定義的字符串,本文給你解密。

Go語言源代碼編譯成二進制文件后,源代碼中的字符串存放在哪里?是如何組織的?

以下面go語言源代碼為例:
package main
import “fmt”
func main() {
fmt.Println(“Hello, World!”)
}

雖然只是打印一個字符串"Hello, World!",生成的二進制文件中字符串卻是非常的多:
image.png

Go語言二進制文件中字符串是存放在哪里的呢?其實存放的位置遵循的elf格式原則,在.rodata節(jié)中(如上圖所示)。

有同學(xué)會問C語言編譯出來的elf格式中字符串也是這樣存放的,Go語言的字符串組織方法和C語言的字符串組織方法有什么不同的呢?最大的不同點就是C語言字符串是以’\x00’結(jié)尾的,這樣不同字符串之間可以方便的以’\x00’來切割,而Go語言的字符串你可以發(fā)現(xiàn)是沒有’\x00’結(jié)尾的,比如上圖中"Hello, World!"后面緊接著就是"SIGKILL:"了,沒有’\x00’分隔。

Go語言字符串按以下方法來組織:

● 字符串按長度從小到大排列

● 相同長度的字符串按字符比較的方法從小到大排列

● 非可見字符串先轉(zhuǎn)義再存放

另外Go語言字符串一般從go_string位置開始存放,如下圖所示
image.png

逆向時正確切割Go語言字符串方法有兩種:

● 進行反匯編,解析匯編指令,確定字符串起始位置和處理長度

image.png

● 直接根據(jù)Go語言字符串組織原則進行切割

基于Go語言字符串組織原則的快速切割算法:

● 1、 搜索確定go_string起始位置

● 2、 設(shè)置字符串搜索起始長度為1

● 3、 根據(jù)當前字符串長度切割字符串

● 4、 預(yù)切割下一個字符串,和當前字符串進行比較,檢查是否違反原則,若符合保存當前字符串,繼續(xù)第3步切割下一個字符串,否則表示字符串有變化進行第5步操作

● 5、 把當前字符串長度加1,繼續(xù)第3步的搜索,直至全部正確搜索完畢

如下圖所示(長度為13個字節(jié)的字符串):
image.png

總結(jié)】go語言字符串的切割在二進制安全檢測中可以真實的還原源代碼中引用字符串的信息,提升檢測準確率。

可以試試下面的漏掃服務(wù),看看系統(tǒng)是否存在安全風險:>>> 漏洞掃描服務(wù)