我跑了strace
,在它的输出中,我得到了如下行:
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\20\273\0\0\0\0\0\0"..., 832) = 832
我已经在读的人读,所以字符串""
是指向的buf( ssize_t read(int fd, void *buf, size_t count);
),但是那又有什么特定的字符串是什么意思?特别是:
ELF
最有可能与可执行程序链接-为什么在这里输入指针?
\
让我们转义特殊字符-为什么在这里转义数字?
>
这是为了什么?
Marco Bonell.. 5
您在这里看到的是动态加载程序,它打开并读取所需库的标头。几乎任何strace
一个ELF程序(这是在Linux中的标准可执行格式)的开始与一堆open
/ read
/ mmap
/ close
为此:动态加载程序加载需要的库。
您在这里看到的是:
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\20\273\0\0\0\0\0\0"..., 832) = 832
正是加载程序正在从文件读取的内容:
3
:这是fd
分配给打开文件的open()
。
"\177ELF\2\1\1\0..."
:这是正在读取的文件的内容。数字之所以存在是因为它们是八进制转义序列,例如\1
表示字节1。之所以这样打印,是因为否则您将看不到它们,并且会在终端上造成混乱,因为大多数数字都是特殊的不可打印的字符。
832
:这是加载程序要从文件读取的字节数。
= 832
:这是的结果read()
,这意味着已读取所有请求的字节。
换句话说,这些转义序列只是使不可打印字节易于阅读的一种方法。您可以od -bc
在加载程序试图打开的文件上测试它的运行情况,可以八进制形式查看其内容,以及可打印的字符和反斜杠转义符:
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\20\273\0\0\0\0\0\0"..., 832) = 832
下面是一个更完整的示例strace /bin/true
:
open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 4 read(4, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\0\4\2\0\0\0\0\0"..., 832) = 832 fstat(4, {st_mode=S_IFREG|0755, st_size=1689360, ...}) = 0 mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f0d3d877000 mmap(NULL, 3795296, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 4, 0) = 0x7f0d3d2dd000 mprotect(0x7f0d3d472000, 2097152, PROT_NONE) = 0 mmap(0x7f0d3d672000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 4, 0x195000) = 0x7f0d3d672000 mmap(0x7f0d3d678000, 14688, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f0d3d678000 close(4)
您会看到加载程序正在打开“ libc”,这是标准C库的ELF文件。它读取其标头以确定要加载的部分,然后将mmap
所有需要的部分存储在内存中,并分配正确的权限。
您在这里看到的是动态加载程序,它打开并读取所需库的标头。几乎任何strace
一个ELF程序(这是在Linux中的标准可执行格式)的开始与一堆open
/ read
/ mmap
/ close
为此:动态加载程序加载需要的库。
您在这里看到的是:
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\20\273\0\0\0\0\0\0"..., 832) = 832
正是加载程序正在从文件读取的内容:
3
:这是fd
分配给打开文件的open()
。
"\177ELF\2\1\1\0..."
:这是正在读取的文件的内容。数字之所以存在是因为它们是八进制转义序列,例如\1
表示字节1。之所以这样打印,是因为否则您将看不到它们,并且会在终端上造成混乱,因为大多数数字都是特殊的不可打印的字符。
832
:这是加载程序要从文件读取的字节数。
= 832
:这是的结果read()
,这意味着已读取所有请求的字节。
换句话说,这些转义序列只是使不可打印字节易于阅读的一种方法。您可以od -bc
在加载程序试图打开的文件上测试它的运行情况,可以八进制形式查看其内容,以及可打印的字符和反斜杠转义符:
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\20\273\0\0\0\0\0\0"..., 832) = 832
下面是一个更完整的示例strace /bin/true
:
open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 4 read(4, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\0\4\2\0\0\0\0\0"..., 832) = 832 fstat(4, {st_mode=S_IFREG|0755, st_size=1689360, ...}) = 0 mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f0d3d877000 mmap(NULL, 3795296, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 4, 0) = 0x7f0d3d2dd000 mprotect(0x7f0d3d472000, 2097152, PROT_NONE) = 0 mmap(0x7f0d3d672000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 4, 0x195000) = 0x7f0d3d672000 mmap(0x7f0d3d678000, 14688, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f0d3d678000 close(4)
您会看到加载程序正在打开“ libc”,这是标准C库的ELF文件。它读取其标头以确定要加载的部分,然后将mmap
所有需要的部分存储在内存中,并分配正确的权限。