2013-07-31 41 views
6

继我关于manually generating a core dump file的问题后,我决定深入研究并弄干手。核心转储注意部分

我能够构建基本的核心转储结构,并将我的死程序的内存返回到大LOAD部分的核心转储中。在GDB中调试时,我的变量回来了,没有问题。 这里有棘手的部分,我该如何让GDB检索程序崩溃时的位置信息。

我知道核心转储的note部分包含这些信息(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) 

有人可以给我指导如何构建注释部分? 我试图直接写这些结构到我的文件,它没有工作,我显然在这里失去了一些东西。 我看了一下Google Coredumper code并花了一些时间,但是编写笔记部分并不那么简单,并且欢迎任何关于它究竟包含什么和其格式的详细信息。

编辑#1:1以下评论

我想通了,我的ELF文件应如下结构:

  • ELF头ElfW(EHDR)
  • 程序头(Ehdr.e_phnum时间ElfW(Phdr)),在这里我基本上使用一个PT_NOTE和一个PT_LOAD标头
  • 注意部分:
    • 科的头(ElfW(NHDR))
    • 科的名字(.n_namesz长)
    • 科的数据(.n_descsz长)包含所有我的程序的内存

    然后

  • 程序部分我将不得不放置3条记录,一条用于prstatus,一个用于prpsinfo,另一个用于辅助矢量

    这似乎是正确的方式,因为readelf给了我一个类似的输出,我得到了真正的核心转储。

    编辑#2:得到正确的结构

    后,我现在与构成音符记录的不同结构挣扎。

    下面是我得到我的核心转储时运行欧盟readelf --notes

    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 
    

    有人有任何线索或解释为什么我的笔记记录不正确读取? 我认为这可能是由于不正确的偏移,但为什么记录要正确列出?

    谢谢!

  • +0

    一种高精度关于在笔记记录包含 – d6bels

    +0

    结构(老问题,但可能是有用的人)的问题 我建议看看生成一个标准的核心转储内核源代码: - 基本代码:HTTP:// LXR。 free-electrons.com/source/fs/coredump.c - ELF-特定部分:http://lxr.free-electrons.com/source/fs/binfmt_elf.c#L1090 – patrickdepinguin

    回答

    1

    有人可以给我指导如何构建注释部分?

    笔记部分是可变大小笔记记录的串联。每个票据记录以ElfW(Nhdr)结构开头,后面跟着(可变大小)名称(长度为.n_namesz,填充以使磁盘上的名称总大小可以被4整除)和数据(长度为.n_descsz,类似地填充)。

    +0

    我编辑的问题考虑您的信息帐户和一种高精度我的问题。谢谢。 – d6bels

    0

    一些测试后,我想通的事情了,回答为寻找这样的信息:

    有人可以证实我会以正确的方式构建我的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_PRSTATUSNT_PRPSINFONT_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)