在Elf二进制文件中读取GOT表项

13

我想编写一个小函数的跟踪器。我使用ptrace。 我在ubuntu x86_64上。我想找到共享库函数的地址(如printf)。

但是我对全局偏移表有一些问题和疑问。 我有以下代码:

size_t baseAddress = this->getBaseAddress();
Elf_Ehdr const * headerElf = static_cast<Elf_Ehdr const *> (this->_manager.readMemory((void*) baseAddress, sizeof (Elf_Ehdr)));
Elf_Phdr const * headerProgram = static_cast<Elf_Phdr const *> (this->_manager.readMemory((void*) (baseAddress + headerElf->e_phoff), headerElf->e_phentsize * headerElf->e_phnum));
unsigned int i = 0;
while (headerProgram[i].p_type != PT_DYNAMIC)
{
    ++i;
}
size_t addrToRead = headerProgram[i].p_vaddr;
Elf_Dyn const * dynSection = static_cast<Elf_Dyn const *> (this->_manager.readMemory((void*) addrToRead, sizeof (Elf_Dyn)));
while (dynSection->d_tag != DT_PLTGOT)
{
    addrToRead += sizeof (Elf_Dyn);
    dynSection = static_cast<Elf_Dyn const *> (this->_manager.readMemory((void*) addrToRead, sizeof (Elf_Dyn)));
}

size_t addrGot = dynSection->d_un.d_ptr/* + (4 * sizeof (Elf64_Word))*/;
std::cout << "addr got = " << std::hex << "0x" << dynSection->d_un.d_ptr << " 0x" << addrGot << std::endl;

Elf64_Word const * temp = (Elf64_Word const *) this->_manager.readMemory((void*) addrGot, sizeof (Elf64_Word));
struct link_map * linkList = (struct link_map *) this->_manager.readMemory((void*) *temp, sizeof (struct link_map));

函数readMemory用于读取跟踪进程的内存。

当我尝试读取linkList->l_ld时,它似乎没有指向动态段。

我不确定我的代码是否正确。当我使用readelf时,GOT段的地址与我的程序找到的地址相同。

我应该只读取GOT段的第一个偏移量还是更多?GOT入口点只包含指向struct link_map的绝对地址吗?

谢谢。


我了解一些C语言,但不懂C++。但无论如何,我无法理解这个问题。这是否应该重新标记为C++? - Alphaneo
由于提供的源代码是C ++,我已经重新标记了这个问题。 - jschmier
2个回答

2

已经有一个实现此目标的方案。

http://binary.nahi.to/hogetrace/

这个功能是使用bfd库完成的。

虽然不像其他跟踪程序那样出名,但这是我所知道的最好的一个。

唯一的遗憾之处是注入所有断点需要相当大的开销。

而且我后悔的一点是它需要PTRACE_SINGLESTEP功能,该功能并不总是适用于每种cpu架构,例如MIPS...


0
你可能应该研究一下动态Elf符号,那就是我所在的地方。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接