如何在gdb中使用逻辑地址?

use*_*507 12 x86 gdb memory-segmentation

gdb提供读取或写入特定线性地址的功能,例如:

(gdb) x/1wx 0x080483e4
0x80483e4 <main>:       0x83e58955
(gdb) 
Run Code Online (Sandbox Code Playgroud)

但是如何指定逻辑地址?我按照以下指示来:

   0x0804841a <+6>:     mov    %gs:0x14,%eax
Run Code Online (Sandbox Code Playgroud)

我如何读取gdb中"%gs:0x14"的内存,或者将此逻辑地址转换为我可以在x命令中使用的线性地址?

注意:我知道在这条指令之后我只能阅读%eax,但这不是我关心的问题

Emp*_*ian 5

我如何在gdb中读取“%gs:0x14”处的内存

您不能:GDB无法知道所%gs引用的段是如何设置的。

或将此逻辑地址转换为我可以在x命令中使用的线性地址

同样,您通常无法执行此操作。但是,您似乎在32位x86 Linux上,并且可以执行此操作- %gs通过set_thread_area系统调用将其设置为指向线程描述符。

您可以catch syscall set_thread_area在GDB中进行操作,并检查参数(每个线程都会有一个这样的调用)。实际执行此操作的代码在此处。知道如何%gs设置后,只需将0x14添加到中base_addr,就可以完成。

  • 我不购买“ GDB无法知道如何设置%gs所指向的段”。GDB在用户模式下运行,无法读取GDT / LDT,但是它可以将诸如“ mov%gs:0x14,%eax”之类的机器代码写入其控制的某些内存中,然后跳转到该内存。这样,它可以“读取”`%gs:0x14`。 (4认同)
  • @PeterCordes显然,“info reg all”没有列出所有寄存器。命令“维护打印寄存器组”显示每个寄存器属于哪些寄存器组。对我来说,“fs_base”和“gs_base”属于“system”组(以及“save”和“restore”,但不属于“all”),因此“info reg system”(或“ir sy”)打印他们。 (3认同)
  • @AlexD:或者在Linux下,可以在目标进程的上下文中使用“arch_prctl(ARCH_GET_GS)”询​​问内核GS基础是什么。(顺便说一句,现代操作系统不使用 GDT/LDT 来设置 FS/GS 基础,它们在可用的 CPU 上使用 MSR 甚至新指令,例如“wrfsbase”)。IDK 如果 ptrace 有办法让调试器直接查询 FS/GS 库;我想我记得 GDB 能够以某种方式查询它,但它不是“info reg all”的一部分。 (2认同)

小智 5

正如使用 GDB 读取 MSR中所回答的,这可以在 gdb 8 中使用寄存器$fs_base和 来实现$gs_base