【发布时间】:2020-12-26 07:15:18
【问题描述】:
我有以下来自 gdb 的 x86 汇编命令:
mov eax, gs:0x14
当我输入(gdb) info registers 时,gs 的值变成了 0x63。
根据我读到的内容,要获得地址本身,我必须将 gs 乘以 0x10 并添加偏移量 (0x14)。
正如预期的那样,该地址无法从内存中读取,因为这是一个相对地址。我试图objdump 文件试图找到任何有意义的起点,我应该添加 0x644 以获取实际内存地址,但没有弹出任何内容。
当我在 gdb 中运行文件时,地址始终为 0x056555XXX,但在代码中间添加 0x644 到 0x56555000。
这个内存段实际位于哪里?
编辑: 我在 64 位 kali linux VM 上运行它,但该文件来自一些 CTF,并且是 32 位 i386 elf 文件。不知道是保护模式还是实模式……
【问题讨论】:
-
gs 是一个寄存器。这一切如何工作取决于您运行它的模式,在哪里,什么处理器(不仅仅是x86,还有32位和64位等),这是386的模拟等等,等等。然后有虚拟地址以及您的代码或文件将看到的物理地址。这导致操作系统在所有其余部分之上,以了解它们如何分配内存,甚至可能是工具链及其链接器脚本。请编辑问题。
-
既然您提到了
eax和gdb,我假设您在Linux 中处于32 位保护模式。您使用的计算仅适用于实模式分段。您需要从操作系统中查询gs段基值。 -
您描述的计算仅适用于实模式。假设您处于保护模式,您必须通过其他方式获取 GS Base 的值。在 32 位模式下,处理器从 GDT 获取段基地址。 (此外,在任何情况下,它都不是相对地址。)
-
是保护模式。
-
如果您的程序已与
libpthread链接,则gdb 命令info threads将显示TLS 基地址作为线程ID,例如* 1 Thread 0xf7dc3700 (LWP 24305)的地址为0xf7dc3700。这是获取地址的最简单方法,但不能保证有效。