gdb 提供了读取或写入特定线性地址的功能,例如:
(gdb) x/1wx 0x080483e4
0x80483e4 <main>: 0x83e58955
(gdb)
但是如何指定逻辑地址?我遇到了以下说明:
0x0804841a <+6>: mov %gs:0x14,%eax
如何读取 GDB 中"%gs:0x14"处的内存,或将此逻辑地址转换为我可以在命令中使用的线性地址x
?
注意:我知道我可以在此指令之后简单地阅读%EAX,但这不是我关心的问题
如何在 GDB 中读取"%gs:0x14"处的内存
您不能:GDB 无法知道%gs
引用的区段是如何设置的。
或者将此逻辑地址转换为我可以在 x 命令中使用的线性地址
同样,您通常不能这样做。但是,您似乎使用的是 32 位 x86 Linux,在那里您可以做到这一点 - %gs
设置为通过系统调用指向线程描述符set_thread_area
。
您可以在 GDB 中执行catch syscall set_thread_area
,并检查参数(每个线程将有一个这样的调用)。实际执行此操作的代码在这里。一旦您知道%gs
是如何设置的,只需将0x14添加到base_addr
,您就完成了。
如使用 GDB 读取 MSR 中所述,使用 gdb 8 可以使用寄存器 $fs_base
和 $gs_base
来实现这一点。
我认为最简单的方法是读取EAX寄存器的内容,因为您可以看到%gs:0x14的值已移至EAX。
在 GDB 中,在0x0804841a后立即使用中断的地址设置断点。例如
break *0x0804841e
然后运行该程序,您可以打印EAX寄存器的内容
info registers eax