2010-02-10 47 views
13

我想写一个小函数的示踪器。我使用ptrace。 我在Ubuntu x86_64上。我想找到共享库函数的地址(如printf)。阅读Elf Binary中的GOT条目

但我有一些问题和关于全球抵消表的一些问题。 我有以下代码:

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的绝对地址?

谢谢。

+0

我知道有位C的,但不知道C++。但无论如何,我无法理解这个问题。这应该被重新标记为C++? – Alphaneo 2010-02-10 05:57:24

+0

由于提供的源代码是C++,我已经重申了这个问题。 – jschmier 2010-02-10 15:06:26

回答

0

您可能应该查看_DYNAMIC Elf符号,那就是我的位置。

2

有已经为这个目标
http://binary.nahi.to/hogetrace/

的质疑点使用BFD库做的实现。

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

......除了这点对于注入所有断点而言,它有相当大的开销。

而且很遗憾的一点是,它需要PTRACE_SINGLESTEP功能,这并不总是适用于所有CPU架构如MIPS ...