查找tracee的会合结构(正在调试的程序)(Finding the rendezvous stru

2019-10-29 07:39发布

我需要调试器我写给我的LIB是正在调试的程序共享的名称与链接,或动态加载。 我得到在link.h描述的交会结构,并回答其他问题,使用DT_DEBUG,在遍历_DYNAMIC []。 首先,调试器嗟设定在r_brk断点。 然后我把正在调试的程序中断,并使用link_map打印所有加载库。 它只打印调试器,而不是被调试程序加载的库。 看来,交会结构我得到属于调试器本身。 如果是这样,你能告诉我怎么去,我调试程序的集合结构? 如果我在做什么必须的工作,你的确认将是有益的,也许一些提示,到可能需要什么。 谢谢。

Answer 1:

// You need to include <link.h>. All structures are explained
// in elf(5) manual pages.
// Caller has opened "prog_name", the debugee, and fd is the
// file descriptor. You can send the name instead, and do open()
// here.
// Debugger is tracing the debugee, so we are using ptrace().

void getRandezvousStructure(int fd, pid_t pd, r_debug& rendezvous) {

    Elf64_Ehdr elfHeader;
    char* elfHdrPtr = (char*) &elfHeader;
    read(fd, elfHdrPtr, sizeof(elfHeader));

    Elf64_Addr debugeeEntry = elfHeader.e_entry; // entry point of debugee

// Here, set a break at debugeeEntry, and after "PTRACE_CONT",
// and waitpid(), remove the break, and set rip back to debugeeEntry.
// After that, here it goes.

    lseek(fd, elfHeader.e_shoff, SEEK_SET); // offset of section header

    Elf64_Shdr secHeader;
    elfHdrPtr = (char*) &secHeader;
    Elf64_Dyn* dynPtr;

// Keep reading until we get: secHeader.sh_addr.
// That is the address of _DYNAMIC.

    for (int i = 0; i < elfHeader.e_shnum; i++) {
        read(fd, elfHdrPtr, elfHeader.e_shentsize);
        if (secHeader.sh_type == SHT_DYNAMIC) {
            dynPtr = (Elf64_Dyn*) secHeader.sh_addr; // address of _DYNAMIC
            break;
        }
    }

// Here, we get "dynPtr->d_un.d_ptr" which points to rendezvous
// structure, r_debug

    uint64_t data;

    for (;; dynPtr++) {
        data = ptrace(PTRACE_PEEKDATA, pd, dynPtr, 0);
        if (data == DT_NULL) break;
        if (data == DT_DEBUG) {
            data = ptrace(PTRACE_PEEKDATA, pd, (uint64_t) dynPtr + 8 , 0);
            break;
        }
    }

// Using ptrace() we read sufficient chunk of memory of debugee
// to copy to rendezvous.

    int ren_size = sizeof(rendezvous);
    char* buffer = new char[2 * ren_size];
    char* p = buffer;
    int total = 0;
    uint64_t value;

    for (;;) {
        value = ptrace(PTRACE_PEEKDATA, pd, data, 0);
        memcpy(p, &value, sizeof(value));
        total += sizeof(value);
        if (total > ren_size + sizeof(value)) break;
        data += sizeof(data);
        p += sizeof(data);
    }

// Finally, copy the memory to rendezvous, which was
// passed by reference.

    memcpy(&rendezvous, buffer, ren_size);
    delete [] buffer;
}


文章来源: Finding the rendezvous structure of tracee (program being debugged)