【问题标题】:how to extract AT_EXECFN from a coredump file如何从核心转储文件中提取 AT_EXECFN
【发布时间】: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 文件中找到这个地址?

【问题讨论】:

    标签: linux elf 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 &lt;= $addr$addr &lt; .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。我不明白为什么这个公式有效,但后来我想通了。感谢您提供帮助,我真的很感激。
    猜你喜欢
    • 1970-01-01
    • 2011-10-20
    • 1970-01-01
    • 1970-01-01
    • 2023-01-12
    • 2016-02-25
    • 2013-05-11
    • 1970-01-01
    • 2013-01-23
    相关资源
    最近更新 更多