如何从核心转储文件中提取 AT_EXECFN

how to extract AT_EXECFN from a coredump file

我需要为 AT_EXECFN from a coredump file. For those who don't know this value is part of the auxiliary vector. It is really simple to get this value while in your running process, just use getauxval, however I couldn't find any information on how to do it when you have an ELF coredump file. I can find the NT_AUXV section of this file, but I can't find out how to find an exact string where AT_EXECFN is pointing to. Say I found AT_EXECFN in the coredump. According to this 提取一个值 我将获得一个结构,其中包含存储实际值的地址。我的问题是如何在 coredump 文件中找到这个地址?

这是一个例子:

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...