I want to write a little function's tracer. I use ptrace.
I'm on ubuntu x86_64. I want to found the address of the shared library function (like printf
).
But i have some problem and some question about the Global Offset Table. I have the following code:
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));
The function readMemory
read on the memory of the traced process.
When I try to read the linkList->l_ld
, it doesn't seem to point on a dynamic section.
I'm not sure my code is correct. When i use readelf
, the address of GOT section is the same than my program found.
I must read only the first offset of the GOT section or more? The GOT entry point contains only absolute address that point to struct link_map
?
Thank you.
There's already an implementation for this objective
http://binary.nahi.to/hogetrace/
The questioned point is done using bfd library.
Not as famous as other tracing programs, but this one is the best one I know.
...Except the point this has quite significant overhead for injecting all the breakpoints.
And the point I regret is that it needs PTRACE_SINGLESTEP functionality, which is not always available for every cpu architecture such as MIPS...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With