2010-02-10 9 views
13

Je veux écrire un petit traceur de fonction. J'utilise ptrace. Je suis sur Ubuntu x86_64. Je veux trouver l'adresse de la fonction de bibliothèque partagée (comme printf).Lire l'entrée GOT dans Elf Binary

Mais j'ai un problème et une question à propos de la table de décalage global. I ont le code ci-dessous:

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)); 

La fonction readMemory lu dans la mémoire du processus tracé.

Lorsque j'essaie de lire le linkList->l_ld, il ne semble pas pointer sur une section dynamique.

Je ne suis pas sûr que mon code soit correct. Quand j'utilise readelf, l'adresse de la section GOT est la même que mon programme trouvé.

Je dois lire uniquement le premier décalage de la section GOT ou plus? Le point d'entrée GOT contient uniquement l'adresse absolue qui pointe vers struct link_map?

Merci.

+0

Je connais un peu de C, mais ne sais pas C++. Mais de toute façon, je ne suis pas capable de comprendre cette question. Devrait-il être marqué de nouveau comme C++ ??? – Alphaneo

+0

Puisque la source fournie est C++, j'ai repensé la question. – jschmier

Répondre

0

Vous devriez probablement regarder dans le symbole _DYNAMIC Elf, c'est où je suis.

2

Il y a déjà une mise en œuvre de cet objectif
http://binary.nahi.to/hogetrace/

Le point en question est fait à l'aide de la bibliothèque BFD.

Pas aussi célèbre que d'autres programmes de traçage, mais celui-ci est le meilleur que je connaisse. ... À l'exception du point, ceci a un surcoût assez important pour l'injection de tous les points d'inflexion.

Et le point que je regrette est qu'il a besoin de fonctionnalités PTRACE_SINGLESTEP, qui ne sont pas toujours disponibles pour toutes les architectures cpu telles que MIPS ...