核心转储注释部分
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了核心转储注释部分相关的知识,希望对你有一定的参考价值。
在我关于manually generating a core dump file的问题之后,我决定潜入它并弄脏我的手。
我能够构建基本的核心转储结构,并将我的死程序的内存返回到一个大的LOAD部分的核心转储中。在GDB中调试时,我的变量又回来了,没问题。这里有一个棘手的部分,我如何让GDB检索程序崩溃时的位置信息。
我知道核心转储的注释部分包含这些信息(cpu寄存器等)。这是objdump -h为“真正的”核心转储提供的内容:
core.28339: file format elf32-i386
Sections:
Idx Name Size VMA LMA File off Algn
0 note0 000001e8 00000000 00000000 000000f4 2**0
CONTENTS, READONLY
1 .reg/28339 00000044 00000000 00000000 00000150 2**2
CONTENTS
2 .reg 00000044 00000000 00000000 00000150 2**2
CONTENTS
3 .auxv 000000a0 00000000 00000000 0000023c 2**2
CONTENTS
4 load1a 00001000 08010000 00000000 00001000 2**12
CONTENTS, ALLOC, LOAD, READONLY, CODE
.. other load sections ...
我想知道readelf那些.reg部分包含从某些结构映射的数据:
Notes at offset 0x000000f4 with length 0x000001e8:
Owner Data size Description
CORE 0x00000090 NT_PRSTATUS (prstatus structure)
CORE 0x0000007c NT_PRPSINFO (prpsinfo structure)
CORE 0x000000a0 NT_AUXV (auxiliary vector)
有人可以给我指示如何构建Notes部分吗?我尝试将这些结构直接写入我的文件,它没有用,我显然在这里遗漏了一些东西。我查看了Google Coredumper code并对其进行了一些介绍,但编写注释部分并不那么简单,并且欢迎任何有关它的确切内容及其格式的详细信息。
编辑#1:在第一条评论之后
我想出我的Elf文件的结构应如下:
- 精灵头ElfW(Ehdr)
- 程序头(Ehdr.e_phnum次ElfW(Phdr)),这里我基本上使用了一个PT_NOTE和一个PT_LOAD头
- 注意部分: 部分标题(ElfW(Nhdr)) 部分名称(.n_namesz长) 部分数据(.n_descsz长)
- 程序部分包含我程序的所有内存
然后我将需要输入3个音符记录,一个用于prstatus,一个用于prpsinfo,一个用于辅助向量。
这似乎是正确的方法,因为readelf给了我类似的输出,就像我在真正的核心转储上得到的那样。
编辑#2:获得正确的结构后
我现在正在努力构建记录记录的不同结构。
以下是我在运行eu-readelf时获得的内容 - 我的核心转储上的注释:
Note segment of 540 bytes at offset 0x74:
Owner Data size Type
CORE 336 PRSTATUS
CORE 136 PRPSINFO
CORE 8 AUXV
NULL
这是我在真正的核心转储上运行相同命令时得到的结果:
Note segment of 488 bytes at offset 0xf4:
Owner Data size Type
CORE 144 PRSTATUS
info.si_signo: 11, info.si_code: 0, info.si_errno: 0, cursig: 11
sigpend: <>
sighold: <>
pid: 28339, ppid: 41446, pgrp: 28339, sid: 41446
utime: 0.000000, stime: 0.000000, cutime: 0.000000, cstime: 0.000000
orig_eax: -1, fpvalid: 0
ebx: -1 ecx: 0 edx: 0
esi: 0 edi: 0 ebp: 0xffb9fcbc
eax: -1 eip: 0x08014b26 eflags: 0x00010286
esp: 0xffb9fcb4
ds: 0x002b es: 0x002b fs: 0x0000 gs: 0x0000 cs: 0x0023 ss: 0x002b
CORE 124 PRPSINFO
state: 0, sname: R, zomb: 0, nice: 0, flag: 0x00400400
uid: 9432, gid: 6246, pid: 28339, ppid: 41446, pgrp: 28339, sid: 41446
fname: pikeos_app, psargs: ./pikeos_app
CORE 160 AUXV
SYSINFO: 0xf7768420
SYSINFO_EHDR: 0xf7768000
HWCAP: 0xbfebfbff <fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe>
PAGESZ: 4096
CLKTCK: 100
PHDR: 0x8010034
PHENT: 32
PHNUM: 2
BASE: 0
FLAGS: 0
ENTRY: 0x80100be
UID: 9432
EUID: 9432
GID: 6246
EGID: 6246
SECURE: 0
RANDOM: 0xffb9ffab
EXECFN: 0xffba1feb
PLATFORM: 0xffb9ffbb
NULL
有人对我的笔记记录未正确阅读的原因有任何线索或解释吗?我认为这可能是由于错误的偏移,但那么为什么记录会被正确列出?
谢谢 !
我之前在将CRIU图像转换为核心转储的项目中遇到了同样的麻烦。它完全用python编写(甚至精灵结构都是ctypes),所以它可以用作指南。见https://github.com/efiop/criu-coredump。即。在这里可以看到一切结构如何https://github.com/efiop/criu-coredump/blob/master/criu_coredump/core_dump.py。
有人可以给我指示如何构建Notes部分吗?
注释部分是可变大小的音符记录的串联。每个音符记录以ElfW(Nhdr)
结构开头,后跟(可变大小)名称(长度为.n_namesz
,填充,因此磁盘上名称的总大小可被4整除)和数据(长度为.n_descsz
,类似地填充)。
经过一些测试后,我想出了一些事情,回答任何寻找这些信息的人:
有人可以确认我采用这种方式构建我的Elf文件的正确方法吗?
是。
由于GDB接受该文件,这似乎是正确的做法。 readelf -a显示的结果显示正确的结构,到目前为止良好。
我不确定应该在哪里将数据(注释和程序部分)放入我的文件中:是否有强制命令,或者这是我的程序头偏移量,它定义了数据的位置?
给Phdr.p_offset
的偏移量应指向数据放在Elf文件中的位置。它们从文件的开头开始。
例如 :
PT_NOTE
程序头的p_offset应设置为sizeof(ElfW(Ehdr)) + ehdr.e_phnum*sizeof(ElfW(Phdr))
。 ehdr.e_phnum
是Elf文件中存在的程序头的数量。
对于PT_LOAD
程序标题,这有点长,因为我们还必须添加所有音符部分的长度。对于带有包含NT_PRSTATUS
,NT_PRPSINFO
和NT_AUXV
部分的注释段的“标准”核心转储,PT_LOAD数据(Phdr.p_offset
)的偏移量将为:
sizeof(ElfW(Ehdr)) + ehdr.e_phnum*sizeof(ElfW(Phdr))
+ sizeof(ElfW(Nhdr)) + sizeof(name_of_section) + sizeof(struct prstatus)
+ sizeof(ElfW(Nhdr)) + sizeof(name_of_section) + sizeof(struct prpsinfo)
+ sizeof(ElfW(Nhdr)) + sizeof(name_of_section) + sizeof(struct auxv_t)
以上是关于核心转储注释部分的主要内容,如果未能解决你的问题,请参考以下文章