查找fs:28h的内存地址

2024-02-17

我为了好玩而使用 gdb 调试程序,并使用堆栈保护,以便它从 fs:28h 将金丝雀写入堆栈。出于好奇,我试图找到 fs:28h 指向的内存地址。 我遇到两个问题。首先,gdb 无法显示 gdtr/ldtr 中的值,因为它不在环零中运行。第二,当用gdb读取fs时,它包含0,这有什么意义?我知道 gdt/ldt 在第一个索引中包含 0 以返回无效地址,并且 RPL 已关闭,所以我在这里缺少什么?如果有人知道如何找到段寄存器 fs 指向的地址,我想知道。

file: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), statically linked

您似乎正在使用x86_64-linux-gnu,即 x86-64 CPU、Linux 内核和 GNU C 库的所有三个。通过硬件和系统软件的组合,FS 段被设置为使得内存操作数%fs:0指的是开始线程控制块对于当前正在执行的线程。 (线程控制块是描述正在运行的线程的内部C库数据结构。您可以将其视为由pthread_t线程句柄。)

正是因为 x86 历来无法让非特权代码轻松查找由 a 引用的“实际”地址(更准确地说是“线性虚拟地址”)%fs:xxx or %gs:xxx内存操作数,线程控制块的第一个字段x86_64-linux-gnu是指向线程控制块本身的指针 https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/x86_64/nptl/tls.h;h=1403f939f7e5a81aeabf58aefac011dd3ce14de6;hb=bb9a4fc02841cf58a112a44b259477547893838b#l142. Thus,

void *read_fs(void) {
    void *rv;
    asm("movq %%fs:0, %0" : "=r" (rv));
    return rv;
}

将返回您想要的地址。请记住,这是only保证为真x86_64-linux-gnu。如果你切换到不同的 Unix 内核(例如 FreeBSD)或不同的 C 库(例如 musl libc),FS 段很有可能仍然指向线程控制块,但该空间中的数据很可能是相当不同。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

查找fs:28h的内存地址 的相关文章

随机推荐