Golang 隱藏技能 -- 訪問私有成員

警告一下柬唯!以下代碼均不是常規(guī)操作,且存在各種潛在不可控的風(fēng)險寨辩。在項目中應(yīng)用有可能被同事打死吓懈,慎用!C夷耻警!

1.調(diào)用其他包中公有結(jié)構(gòu)的私有成員變量

如果需要引用某個包中公有結(jié)構(gòu)體的私有變量,而這個變量又沒有提供對應(yīng)的訪問方法甸怕。那么如何繞過“小寫不公開”這個限制呢甘穿?簡單介紹一種方法直接通過變量地址訪問變量:

package other1

import "fmt"

type TestPointer struct {
    A int
    b int    // 私有變量
}

func (T *TestPointer) OouPut() {
    fmt.Println("TestPointer OouPut:", T.A, T.b)
}
package main

import (
    "fmt"
    "test/test4/other1"
    "unsafe"
)

func main() {
    T := other1.TestPointer{A:1}
    pb := (*int)(unsafe.Pointer(uintptr(unsafe.Pointer(&T)) + 8))
    /*
    Tmp := uintptr(unsafe.Pointer(&T)) + 8)
    pb := (*int)(unsafe.Pointer(Tmp)
    千萬不能出現(xiàn)這種用臨時變量中轉(zhuǎn)一下的情況。因為GC可能因為優(yōu)化內(nèi)存碎片的原因移動了這個對象梢杭。只保留了指針的地址是沒有意義的温兼。
    */
    *pb = 2
    T.OouPut()    //1 2
}

用unsafe包中的unsafe.Pointer獲取到結(jié)構(gòu)體對象的首地址,然后加上想訪問的私有變量的偏移地址就是私有變量的地址武契。關(guān)于成員變量偏移量的問題請參閱 內(nèi)存對齊

2.調(diào)用其他包的私有func

go提供了一個編譯指令募判,繞過編譯器檢查荡含。直接訪問func的實現(xiàn)
//go:linkname

package other1

import "fmt"

func privateFunc() {
    fmt.Println("this is private func")
}

package main

import (
    _ "test/test4/other1"
    _ "unsafe"
)
// call private func
//go:linkname private_func test/test4/other1.privateFunc
func private_func()

func main() {
    private_func() // this is private func
}

關(guān)于編譯指令可以參閱 編譯指令Command compile
上面代碼需要在調(diào)用者(這里是main.go)同目錄添加一個.s匯編文件,騙過編譯器届垫。讓編譯器認為是實現(xiàn)是在.s匯編文件中释液,從而跳過檢查

3. 調(diào)用其他包的公有結(jié)構(gòu)的私有方法

package other1
import "fmt"
type PublicStruct struct {
    I int
    b int
}
func (p *PublicStruct) f(a int) {
    println("PublicStruct f()", p.I, p.b, a)
}
package main
import (
    "test/test4/other1"
    _ "unsafe"
)
// 調(diào)用其他包的公有結(jié)構(gòu)的私有func
//go:linkname public_struc_private_func test/test4/other1.(*PublicStruct).f
func public_struc_private_func(p *other1.PublicStruct, a int)

func main() {
    // 先構(gòu)造一個other1.PublicStruct
    p := &other1.PublicStruct{I:1}
    public_struc_private_func(p, 100)   // PublicStruct f() 1 0 100
}

和上面的類似用linkname指令騙過編譯器。這里聲明了一個指針接收者的func public_struc_private_func
第一個參數(shù)是對應(yīng)對象的指針装处,第二個參數(shù)開始是對應(yīng)func需要的參數(shù)误债。
其實這就是指針接收者func原本的實現(xiàn)方式(即 本質(zhì)上是一個普通的函數(shù),只是隱式傳遞了對象的指針)

4. 調(diào)用其他包的私有全局變量

package other1
var private_m = map[int]string {
    1:"a",
}
import (
    "fmt"
    _ "test/test4/other1"
    _ "unsafe"
) // 調(diào)用其他包的私有全局變量
//go:linkname private_member test/test4/other1.private_m
var private_member map[int]string

func main() {
    fmt.Println(private_member[1])  // a
    private_member[2] = "b"
    for k, v := range private_member {
        fmt.Println(k, v)       // 1 a; 2 b
    }
}

和上面的linkname類似妄迁,騙過編譯器寝蹈。直接訪問變量

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市判族,隨后出現(xiàn)的幾起案子躺盛,更是在濱河造成了極大的恐慌,老刑警劉巖形帮,帶你破解...
    沈念sama閱讀 206,602評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件槽惫,死亡現(xiàn)場離奇詭異,居然都是意外死亡辩撑,警方通過查閱死者的電腦和手機界斜,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,442評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來合冀,“玉大人各薇,你說我怎么就攤上這事【桑” “怎么了峭判?”我有些...
    開封第一講書人閱讀 152,878評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長棕叫。 經(jīng)常有香客問我林螃,道長,這世上最難降的妖魔是什么俺泣? 我笑而不...
    開封第一講書人閱讀 55,306評論 1 279
  • 正文 為了忘掉前任疗认,我火速辦了婚禮,結(jié)果婚禮上伏钠,老公的妹妹穿的比我還像新娘横漏。我一直安慰自己,他們只是感情好熟掂,可當(dāng)我...
    茶點故事閱讀 64,330評論 5 373
  • 文/花漫 我一把揭開白布缎浇。 她就那樣靜靜地躺著,像睡著了一般赴肚。 火紅的嫁衣襯著肌膚如雪华畏。 梳的紋絲不亂的頭發(fā)上鹏秋,一...
    開封第一講書人閱讀 49,071評論 1 285
  • 那天尊蚁,我揣著相機與錄音亡笑,去河邊找鬼。 笑死横朋,一個胖子當(dāng)著我的面吹牛仑乌,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播琴锭,決...
    沈念sama閱讀 38,382評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼晰甚,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了决帖?” 一聲冷哼從身側(cè)響起厕九,我...
    開封第一講書人閱讀 37,006評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎地回,沒想到半個月后扁远,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,512評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡刻像,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,965評論 2 325
  • 正文 我和宋清朗相戀三年畅买,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片细睡。...
    茶點故事閱讀 38,094評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡谷羞,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出溜徙,到底是詐尸還是另有隱情湃缎,我是刑警寧澤,帶...
    沈念sama閱讀 33,732評論 4 323
  • 正文 年R本政府宣布蠢壹,位于F島的核電站嗓违,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏知残。R本人自食惡果不足惜靠瞎,卻給世界環(huán)境...
    茶點故事閱讀 39,283評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望求妹。 院中可真熱鬧乏盐,春花似錦、人聲如沸制恍。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,286評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽净神。三九已至何吝,卻和暖如春溉委,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背爱榕。 一陣腳步聲響...
    開封第一講書人閱讀 31,512評論 1 262
  • 我被黑心中介騙來泰國打工瓣喊, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人黔酥。 一個月前我還...
    沈念sama閱讀 45,536評論 2 354
  • 正文 我出身青樓藻三,卻偏偏與公主長得像,于是被迫代替她去往敵國和親跪者。 傳聞我的和親對象是個殘疾皇子棵帽,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,828評論 2 345

推薦閱讀更多精彩內(nèi)容