起因
在看 go 源码的时候,看到新包 debug/elf
包,手动进行尝试解析编译的二进制
写了一个demo
func TestElf2(t *testing.T) {
f, err := os.Open("testdata/binary") // 一个在mac系统下编译成功的二进制
if err != nil {
t.Fatal(err)
}
ef, err := elf.NewFile(f)
if err != nil {
t.Fatal(err)
}
_ = ef
t.Logf("%+v", ef)
}
执行结果失败,读取不到 elf 信息
=== RUN TestElf2
elf_test.go:20: bad magic number '[207 250 237 254]' in record at byte 0x0
--- FAIL: TestElf2 (0.00s)
在命令行使用 readelf
查看格式
$ readelf -h binary
readelf: Error: Not an ELF file - it has the wrong magic bytes at the start
说明不是一个ELF格式的文件,为了探明原因就去查询了一番
ELF 魔法数字
报错信息提示 bad magic number
:不是合法的魔法数字
那合法的数字应该是多少,查看源码
sr := io.NewSectionReader(r, 0, 1<<63-1)
// Read and decode ELF identifier
var ident [16]uint8
if _, err := r.ReadAt(ident[0:], 0); err != nil {
return nil, err
}
if ident[0] != '\x7f' || ident[1] != 'E' || ident[2] != 'L' || ident[3] != 'F' {
return nil, &FormatError{0, "bad magic number", ident[0:4]}
}
二进制文件前4个字节应该为 '\x7f' 'E' 'L' 'F'
,十六进制表示为: 7f 45 4c 46
使用 hexdump
查看该二进制的前几位
$ hexdump -Cb -n 16 binary
00000000 cf fa ed fe 0c 00 00 01 00 00 00 00 02 00 00 00 |................|
确实并不是源码中的信息,那我交叉编译下看看linux下是怎么样的呢
设置 GOOS 和 GOARCH 重新编译linux 64位二进制,并使用 hexdump
再次查看
$ hexdump -Cb -n 16 binary
00000000 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 |.ELF............|
0000000 177 105 114 106 002 001 001 000 000 000 000 000 000 000 000 000
看来不同系统有不同的标识
常见可执行文件格式
这是chatgpt 的回答
Mach-O(Mach Object)和 ELF(Executable and Linkable Format)是两种不同的可执行文件格式。
Mach-O 是苹果公司开发的可执行文件格式,用于 macOS 和 iOS 系统。它是基于 Mach 内核的操作系统所使用的标准格式,支持多种架构(如 x86、x86_64、ARM 等)。Mach-O 文件包含了可执行代码、数据和符号表等信息,用于加载和执行程序。
ELF 是一种通用的可执行文件格式,广泛用于类 UNIX 系统,如 Linux 和 BSD。ELF 文件同样包含了可执行代码、数据和符号表等信息,以及其他一些用于动态链接和装载的信息。ELF 支持多种架构和操作系统,使得它成为跨平台开发的标准格式。
虽然 Mach-O 和 ELF 是不同的可执行文件格式,但它们都用于存储和执行程序。每个操作系统和体系结构通常都有自己的默认格式,例如 macOS 使用 Mach-O,而 Linux 使用 ELF。这些格式定义了可执行文件的结构、布局和标准,以便操作系统能够正确加载和执行程序。
标签:可执行文件,00,操作系统,ELF,000,格式,Mach
From: https://www.cnblogs.com/sooooooul/p/17435401.html