- 深入浅出Go语言编程
- 阮正平 杜军
- 651字
- 2024-08-15 17:00:57
1.6.2 Go语言的反汇编方法
Go语言提供了多种反汇编方法,具体如下。
● 使用objdump工具实现,命令为“objdump -S Go二进制文件”。
● 使用gdb的反汇编实现,命令为disassemble/disass。
● 将Go代码编译成汇编代码,命令为go tool compile。
● 将Go语言的二进制文件反编译成汇编代码,命令为go tool objdump。
● 在构建Go程序的同时生成汇编代码文件,命令为go build -gcflags。
在上述反汇编方法中,前两种主要用在操作系统层面,我们常用的是后面三种,下面具体介绍这三种。
1.使用go tool compile命令将Go代码编译成汇编代码
将Go代码编译成汇编代码时,输出的汇编代码没有链接,呈现的地址都是偏移量。go tool compile命令的使用方式如下。
$ go tool compile -N -l -S main.go
"".plan9ExampleFunc STEXT size=80 args=0x0 locals=0x28 funcid=0x0 align=0x0
0x0000 00000 (main.go:3) TEXT "".plan9ExampleFunc(SB), ABIInternal, $40-0
0x0000 00000 (main.go:3) CMPQ SP, 16(R14)
...
0x0024 00036 (main.go:4) CALL runtime.newobject(SB)
...
"".main STEXT size=86 args=0x0 locals=0x20 funcid=0x0 align=0x0
0x0000 00000 (main.go:8) TEXT "".main(SB), ABIInternal, $32-0
0x0000 00000 (main.go:8) CMPQ SP, 16(R14)
...
0x004f 00079 (main.go:8) CALL runtime.morestack_noctxt(SB)
0x0054 00084 (main.go:8) PCDATA $0, $-1
0x0054 00084 (main.go:8) JMP 0
2.使用go tool objdump命令将Go语言的二进制文件反汇编成汇编代码
go tool objdump命令的使用方式如下。
$ go tool objdump main.o
TEXT "".plan9ExampleFunc(SB) gofile..../main.go
main.go:3 0x723 493b6610 CMPQ 0x10(R14), SP
...
main.go:5 0x76b c3 RET
main.go:3 0x76c e800000000 CALL 0x771 [1:5]R_CALL:runtime.morestack_noctxt
main.go:3 0x771 ebb0 JMP "".plan9ExampleFunc(SB)
TEXT "".main(SB) gofile...../main.go
main.go:8 0x773 493b6610 CMPQ 0x10(R14), SP
...
main.go:8 0x7c2 e800000000 CALL 0x7c7 [1:5]R_CALL:runtime.morestack_noctxt
main.go:8 0x7c7 ebaa JMP "".main(SB)
要说明的是,反编译Go二进制文件成汇编代码时会丢失很多信息。
3.在构建Go程序的同时使用go build -gcflags命令生成汇编代码
go build -gcflags命令的使用方式如下。
$ go build -gcflags -S main.go
"".plan9ExampleFunc STEXT size=61 args=0x0 locals=0x18 funcid=0x0 align=0x0
0x0000 00000 (..../main.go:3) TEXT "".plan9ExampleFunc(SB), ABIInternal, $24-0
0x0000 00000 (..../main.go:3) CMPQ SP, 16(R14)
...
0x0036 00054 (..../main.go:3) CALL runtime.morestack_noctxt(SB)
0x003b 00059 (..../main.go:3) PCDATA $0, $-1
0x003b 00059 (..../main.go:3) JMP 0
"".main STEXT size=66 args=0x0 locals=0x10 funcid=0x0 align=0x0
0x0000 00000 (..../main.go:8) TEXT "".main(SB), ABIInternal, $16-0
0x0000 00000 (..../main.go:8) CMPQ SP, 16(R14)
...
0x0040 00064 (..../main.go:8) JMP 0
也可以使用上述命令查看某个具体的函数。
$ go build -gcflags '-l' -o main main.go
$ go tool objdump -s "main\.plan9ExampleFunc" main
TEXT main.plan9ExampleFunc(SB) ..../main.go
main.go:3 0x1053f60 493b6610CMPQ 0x10(R14), SP
...
main.go:3 0x1053f96 e865d0ffff CALL runtime.morestack_noctxt.abi0(SB)
main.go:3 0x1053f9b ebc3 JMP main.plan9ExampleFunc(SB)
小技巧:命令go build -gcflags -S用于生成正在处理的汇编代码,命令go tool objdump则用于生成最终机器码的汇编代码。