如何从核心转储文件中提取 AT_EXECFN
Posted
技术标签:
【中文标题】如何从核心转储文件中提取 AT_EXECFN【英文标题】:how to extract AT_EXECFN from a coredump file 【发布时间】:2021-05-14 05:34:02 【问题描述】:我需要从 coredump 文件中提取 AT_EXECFN
的值。对于那些不知道这个值的人是the auxiliary vector 的一部分。在运行过程中获取此值非常简单,只需使用getauxval
,但是当您拥有 ELF 核心转储文件时,我找不到任何有关如何执行此操作的信息。 I can find the NT_AUXV
section of this file,但我不知道如何找到AT_EXECFN
指向的确切字符串。假设我在核心转储中找到了AT_EXECFN
。根据this,我将获得一个带有 ann 地址的结构,其中存储了实际值。我的问题是如何在 coredump 文件中找到这个地址?
【问题讨论】:
【参考方案1】:这是一个例子:
int main() abort();
gcc -w -O2 t.c && ulimit -c unlimited && ./a.out
Aborted (core dumped)
首先我们可以看一下 GDB:
gdb -q ./a.out core
Reading symbols from ./a.out...
(No debugging symbols found in ./a.out)
[New LWP 86]
Core was generated by `./a.out'.
Program terminated with signal SIGABRT, Aborted.
#0 __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
50 ../sysdeps/unix/sysv/linux/raise.c: No such file or directory.
(gdb) info auxv
33 AT_SYSINFO_EHDR System-supplied DSO's ELF header 0x7ffd4037a000
16 AT_HWCAP Machine-dependent CPU capability hints 0x178bfbff
...
31 AT_EXECFN File name of executable 0x7ffd40374ff0 "./a.out"
15 AT_PLATFORM String identifying platform 0x7ffd403739c9 "x86_64"
0 AT_NULL End of vector 0x0
这证明该信息实际上存在于core
中,并且还显示了预期的值。
因此,步骤是:
读取/解码NT_AUXV
注释,直到找到带有.a_type == AT_EXECFN
的条目(31
)。找到指向字符串的指针($addr
,在这里你会找到0x7ffd40374ff0
)。
使用eu-readelf -n core
有助于验证您正在读取预期值。这是输出:
CORE 320 AUXV
SYSINFO_EHDR: 0x7ffd4037a000
HWCAP: 0x178bfbff <fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht>
...
EXECFN: 0x7ffd40374ff0
PLATFORM: 0x7ffd403739c9
NULL
使用.p_type == PT_LOAD
遍历所有程序头,直到找到带有.p_vaddr <= $addr
和$addr < .p_vaddr + .p_memsz
的程序头(即“覆盖”所需地址的LOAD
段)。在上述情况下,就是这个条目:
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
...
LOAD 0x016000 0x00007ffd40354000 0x0000000000000000 0x021000 0x021000 RW 0x1000
...
最后您可以在core
文件.p_offset + $addr - .p_vaddr
中找到字符串的位置。使用上述数字,我们希望字符串位于文件中的偏移量 0x016000 + 0x7ffd40374ff0 - 0x00007ffd40354000 = 225264
字节处。
我们确实在那里找到了它:
dd status=none bs=1 skip=225264 count=10 if=core | xxd -g1
00000000: 2e 2f 61 2e 6f 75 74 00 00 00 ./a.out...
【讨论】:
我不知道您是如何确定路径的实际地址的,换句话说,您是如何确定.p_offset + $addr - .p_vaddr
的?我一直在阅读文档,但无法理解您是如何得出这个公式的。
@flashburn 对不起,我不明白这个问题:我使用的所有数字:EXECFN == 0x7ffd40374ff0
、.p_offset == 0x016000
和 .p_vaddr == 0x00007ffd40354000
都在答案中可见。
没关系。我想我明白了。我花了一些时间才弄清楚你是如何计算路径地址的,但我的意思是.p_offset + $addr - .p_vaddr
。我不明白为什么这个公式有效,但后来我想通了。感谢您提供帮助,我真的很感激。以上是关于如何从核心转储文件中提取 AT_EXECFN的主要内容,如果未能解决你的问题,请参考以下文章