读取 Elf 二进制中的 GOT 条目

发布于 2024-08-20 11:48:03 字数 1728 浏览 1 评论 0原文

我想写一个小函数的跟踪器。我用的是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的绝对地址?

谢谢。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

兔小萌 2024-08-27 11:48:03

这个目标已经有一个实现
http://binary.nahi.to/hogetrace/

质疑点是使用 bfd 库完成的。

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

...除了一点之外,注入所有断点的开销相当大。

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

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...

够运 2024-08-27 11:48:03

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

You probably should look into the _DYNAMIC Elf symbol, that's where I am.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文