从标头计算 linux 核心文件大小

Posted

技术标签:

【中文标题】从标头计算 linux 核心文件大小【英文标题】:Computing linux core file size from headers 【发布时间】:2016-02-07 12:10:01 【问题描述】:

我正在尝试编写 C 代码,该代码将根据其 ELF 标头计算 Linux 核心转储文件的大小。这是必需的,因为我将它通过管道传输到 STDIN 并需要传递它,首先指定它的大小,而不是实际将它写入文件。将整个文件读入内存也不是一种选择。

首先,我正在研究核心转储标头:

ELF Header:
  Magic:   7f 45 4c 46 02 02 01 00 00 00 00 00 00 00 00 00 
  Class:                             ELF64
  Data:                              2's complement, big endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              CORE (Core file)
  Machine:                           MIPS R3000
  Version:                           0x1
  Entry point address:               0x0
  Start of program headers:          64 (bytes into file)
  Start of section headers:          0 (bytes into file)
  Flags:                             0x0
  Size of this header:               64 (bytes)
  Size of program headers:           56 (bytes)
  Number of program headers:         257
  Size of section headers:           0 (bytes)
  Number of section headers:         0
  Section header string table index: 0

There are no sections in this file.

There are no sections to group in this file.

接下来,我在循环中读取程序标头并获取所有 FileSiz 字段的总和。 我的假设是(ELF 标头大小)+(程序标头大小)*(程序标头数量)+(所有段大小的总和)将为我提供整体文件大小。然而,这种情况并非如此。就我而言,我得到的实际文件大小为 729088000 字节,而上面的数学给了我 729054616 字节。我错过了什么?

【问题讨论】:

【参考方案1】:

设法解决了问题。总文件大小可以通过获取具有最大偏移量的程序头并将文件大小添加到它来计算,因为核心文件仅由头和段组成。

例如如果您通过 readelf 阅读程序标题,并查看最后的条目:

  LOAD           0x00000000287d0000 0x000000557d5c0000 0x0000000000000000
                 0x0000000002730000 0x0000000002730000  RW     10000
  LOAD           0x000000002af00000 0x000000557fcf0000 0x0000000000000000
                 0x0000000000010000 0x0000000000010000         10000
  LOAD           0x000000002af10000 0x000000557fd00000 0x0000000000000000
                 0x00000000007f0000 0x00000000007f0000  RWE    10000
  LOAD           0x000000002b710000 0x000000ffffe70000 0x0000000000000000
                 0x0000000000040000 0x0000000000040000  RW     10000

那么文件大小或核心转储实际上将是 0x2b710000 + 0x40000

【讨论】:

这个答案完全错了,问题的前提是假的。【参考方案2】:

我正在尝试编写 C 代码,该代码将根据其 ELF 标头计算 Linux 核心转储文件的大小。

这是不可能的,因为

使用动态链接,您有许多不同的ELF 标头,每个共享库都会影响最终的core 文件大小,并且 动态分配的内存(通常是核心转储中最重要的部分)在ELF 标头中根本没有描述,可以是10、100 或比可执行文件中的任何 .data 大 1000 倍。

但是,可以确定核心大小如果您已设法停止可执行文件并且可以访问其/proc/$pid/maps: google userspace coredumper 正是这样做的。

【讨论】:

以上是关于从标头计算 linux 核心文件大小的主要内容,如果未能解决你的问题,请参考以下文章

linux中du和df 的区别

C 中的 .BMP 文件 - DIB 标头返回图像大小 0,即使 BMP 标头返回文件大小

linux 遍历相同文件名,并计算所有文件大小之和

位图文件头大小

如何在不使用“内容长度”标头的情况下查看网页中的所有文件大小?

Linux怎样计算一个目录下一部分文件的总大小