Linux读取strace记录的系统调用-如何理解指向缓冲区值的指针?

tjvv9vkg  于 2022-12-17  发布在  Linux
关注(0)|答案(1)|浏览(121)

我运行了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

我读过man on read,所以字符串""是指向buf(ssize_t read(int fd, void *buf, size_t count);)的指针,但是这个特定的字符串是什么意思呢?

  • ELF最有可能是链接的可执行文件-为什么在这里使用指针?
  • \允许转义特殊字符-为什么在这里转义数字?
  • >它是做什么用的?
hts6caw3

hts6caw31#

你在这里看到的是动态加载器打开并阅读所需库的头文件,几乎所有的ELF程序(Linux中的标准可执行格式)的strace都以一串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:这是由open()分配给打开文件的fd
  • "\177ELF\2\1\1\0...":这是正在读取的文件的内容。数字在那里是因为它们是八进制转义序列,例如\1表示字节1。它们这样打印是因为否则你将无法看到它们,并且会在你的终端上造成混乱,因为大多数数字是特殊的不可打印字符。
  • 832:这是加载程序希望从文件中读取的字节数。
  • = 832:这是read()的结果,表示已读取所有请求的字节。

换句话说,那些转义序列,只是一种使不可打印字节可读的方法.你可以在加载器试图打开的文件上运行od -bc来测试这个,你可以看到它的内容是八进制格式,加上可打印字符和反斜杠转义:

$ od -bc /lib/x86_64-linux-gnu/libc.so.6 | head -n4
0000000 177 105 114 106 002 001 001 003 000 000 000 000 000 000 000 000
        177   E   L   F 002 001 001 003  \0  \0  \0  \0  \0  \0  \0  \0
0000020 003 000 076 000 001 000 000 000 260 034 002 000 000 000 000 000
        003  \0   >  \0 001  \0  \0  \0 260 034 002  \0  \0  \0  \0  \0

下面是一个更完整的示例,来自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将所有需要的节都放到内存中,并分配正确的权限。

相关问题