Golang二進制反匯編問題
Golang二進制反匯編
Go的源碼是Plan 9匯編與Go語言的混合使用,即有匯編調用Go,也有Go調用匯編。
在很多情況下,直接看匯編代碼更直觀,特別是在研究編譯器生成的函數實現(xiàn)時更有用。
下面介紹兩種反匯編方法:
假設有個helloworld.go程序,源碼如下:
package main import "fmt" func main() { fmt.Println("Hello, World!") }
先將代碼編譯成二進制,命令如下:
go build --gcflags="-l -N" -o helloworld
會生成一個helloworld的二進制,--gcflags="-l -N"
參數的作用是去掉編譯器優(yōu)化,使生成的匯編代碼與編寫的代碼更相近,同時也方便GDB調試。
反匯編成AT&T匯編
AT&T是Linux操作系統(tǒng)最常用的匯編語言,Linux系統(tǒng)提供的objdump工具也是將二進制反編譯成AT&T匯編,命令如下:
objdump -d helloworld > att.asm
最終反匯編的結果放在了att.asm文件。
下面是匯編結果(截取了部分代碼):
0000000000487200 <main.main>: 487200: 64 48 8b 0c 25 f8 ff mov %fs:0xfffffffffffffff8,%rcx 487207: ff ff 487209: 48 3b 61 10 cmp 0x10(%rcx),%rsp 48720d: 76 7a jbe 487289 <main.main+0x89> 48720f: 48 83 ec 68 sub $0x68,%rsp 487213: 48 89 6c 24 60 mov %rbp,0x60(%rsp) 487218: 48 8d 6c 24 60 lea 0x60(%rsp),%rbp 48721d: 0f 57 c0 xorps %xmm0,%xmm0 487220: 0f 11 44 24 38 movups %xmm0,0x38(%rsp) 487225: 48 8d 44 24 38 lea 0x38(%rsp),%rax ...
反匯編成Plan 9匯編
Plan 9目前看到的只有Go語言在用,而且網上的資料很匱乏,學習成本挺高的,但如果學會了Plan 9匯編,再看Go源碼會非常簡單,而且可以通過Go調用匯編寫出高效率代碼。
要把二進制反匯編成Plan 9匯編,也只能用Go提供的工具,命令如下:
go tool objdump -S helloworld > plan9.asm
最終反匯編的結果放在了plan9.asm文件。
下面是匯編結果(截取了部分代碼):
TEXT main.main(SB) /root/program/golang/helloworld/helloworld.go func main() { 0x487200 64488b0c25f8ffffff MOVQ FS:0xfffffff8, CX 0x487209 483b6110 CMPQ 0x10(CX), SP 0x48720d 767a JBE 0x487289 0x48720f 4883ec68 SUBQ $0x68, SP 0x487213 48896c2460 MOVQ BP, 0x60(SP) 0x487218 488d6c2460 LEAQ 0x60(SP), BP fmt.Println("Hello, World!") 0x48721d 0f57c0 XORPS X0, X0 0x487220 0f11442438 MOVUPS X0, 0x38(SP) 0x487225 488d442438 LEAQ 0x38(SP), AX 0x48722a 4889442430 MOVQ AX, 0x30(SP)
建議
從上面展示的結果來看,兩種匯編還是有點差別的。
在學習Go源碼時,選擇用哪種匯編去看這個要根據自已的實際情況來。
我的建議先必須對AT&T匯編有一定了解,因為Plan 9匯編資料實在是太少了,甚至沒有一個對命令的完整介紹,一個沒有匯編基礎的人直接看Plan 9的一些文檔,絕對會一臉絕望。
在整理網上一些Plan 9匯編資料時,發(fā)現(xiàn)都是講的Plan 9與AT&T的差異,所以只有了解AT&T,才能進一步學好Plan 9匯編。
總結
以上為個人經驗,希望能給大家一個參考,也希望大家多多支持腳本之家。