how to extract AT_EXECFN from a coredump file

Viewed 232

I need to extract a value for 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 I'm going to get a struct with ann address where the actual value is stored. My question is how do I find this address in the coredump file?

1 Answers

Here is an example:

int main() { abort(); }

gcc -w -O2 t.c && ulimit -c unlimited && ./a.out
Aborted (core dumped)

First we can look with 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

This proves that the info is in fact present in the core, and also shows what values to expect.

The steps therefore are:

  • read / decode NT_AUXV note until you find an entry with .a_type == AT_EXECFN ( 31). Find the pointer to string ($addr, here you would find 0x7ffd40374ff0).

    Using eu-readelf -n core is helpful to verify that you are reading expected values. Here is the output:

  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
  • iterate over all program headers with .p_type == PT_LOAD until you find one with .p_vaddr <= $addr and $addr < .p_vaddr + .p_memsz (that is, a LOAD segment which "covers" desired address). In above case, that's this entry:
Program Headers:
  Type           Offset   VirtAddr           PhysAddr           FileSiz  MemSiz   Flg Align
...
  LOAD           0x016000 0x00007ffd40354000 0x0000000000000000 0x021000 0x021000 RW  0x1000
...
  • finally you can find location of the string in the core file at .p_offset + $addr - .p_vaddr. Using above numbers, we expect the string to be at offset 0x016000 + 0x7ffd40374ff0 - 0x00007ffd40354000 = 225264 bytes into the file.

    And we do find it there:

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