【问题标题】:How to get Control Register (CR2) value?如何获取控制寄存器 (CR2) 的值?
【发布时间】:2014-06-07 11:58:19
【问题描述】:

我们有没有办法从 x86-64 的核心中找到 CR2 的值? 信息寄存器不显示它。

(gdb) info registers  all
rax            0x7fc9ca854000   140504662884352
rbx            0x119ad58        18459992
rcx            0xa0000  655360
rdx            0x7fca99045300   140508127318784
rsi            0x1      1
rdi            0x120    288
rbp            0x7fc9d0104e40   0x7fc9d0104e40
rsp            0x7fc9d0104c70   0x7fc9d0104c70
r8             0x0      0
r9             0xc0     192
r10            0x0      0
r11            0x7fca1432b2e0   140505898988256
r12            0x7fc9c95e5d80   140504643558784
r13            0x800a0003       2148139011
r14            0x0      0
r15            0x7fc94537d198   140502426440088
rip            0x666831 0x666831 
eflags         0x10206  [ PF IF RF ]
cs             0x33     51
ss             0x2b     43
ds             0x0      0
es             0x0      0
fs             0x0      0
gs             0x0      0
st0            0        (raw 0x00000000000000000000)
st1            0        (raw 0x00000000000000000000)
st2            0        (raw 0x00000000000000000000)
st3            0        (raw 0x00000000000000000000)
st4            0        (raw 0x00000000000000000000)
st5            0        (raw 0x00000000000000000000)
st6            0        (raw 0x00000000000000000000)
st7            0        (raw 0x00000000000000000000)
fctrl          0x37f    895
fstat          0x0      0
ftag           0xffff   65535
fiseg          0x0      0
fioff          0x0      0
foseg          0x0      0
fooff          0x0      0
fop            0x0      0
xmm0           {
  v4_float = {0x0, 0x0, 0x0, 0x0},
  v2_double = {0x0, 0x0},
  v16_int8 = {0x0 <repeats 16 times>},
  v8_int16 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
  v4_int32 = {0x0, 0x0, 0x0, 0x0},
  v2_int64 = {0x0, 0x0},
  uint128 = 0x00000000000000000000000000000000
}
xmm1           {
  v4_float = {0x0, 0x0, 0x0, 0x0},
  v2_double = {0x0, 0x0},
  v16_int8 = {0x0 <repeats 16 times>},
  v8_int16 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
  v4_int32 = {0x0, 0x0, 0x0, 0x0},
  v2_int64 = {0x0, 0x0},
  uint128 = 0x00000000000000000000000000000000
}
xmm2           {
  v4_float = {0x0, 0x0, 0x0, 0x0},
  v2_double = {0x0, 0x0},
  v16_int8 = {0x21, 0x80, 0x0 <repeats 14 times>},
  v8_int16 = {0x8021, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
  v4_int32 = {0x8021, 0x0, 0x0, 0x0},
  v2_int64 = {0x8021, 0x0},
  uint128 = 0x00000000000000000000000000008021
}
xmm3           {
  v4_float = {0x0, 0x0, 0x0, 0x0},
  v2_double = {0x0, 0x0},
  v16_int8 = {0xa8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x58, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
  v8_int16 = {0xa8, 0x0, 0x0, 0x0, 0x58, 0x0, 0x0, 0x0},
  v4_int32 = {0xa8, 0x0, 0x58, 0x0},
  v2_int64 = {0xa8, 0x58},
  uint128 = 0x000000000000005800000000000000a8
}
xmm4           {
  v4_float = {0x0, 0x0, 0x0, 0x0},
  v2_double = {0x0, 0x0},
  v16_int8 = {0x0 <repeats 16 times>},
  v8_int16 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
  v4_int32 = {0x0, 0x0, 0x0, 0x0},
  v2_int64 = {0x0, 0x0},
  uint128 = 0x00000000000000000000000000000000
}
xmm5           {
  v4_float = {0x0, 0x0, 0x0, 0x0},
  v2_double = {0x0, 0x0},
  v16_int8 = {0x92, 0xff, 0x0 <repeats 14 times>},
  v8_int16 = {0xff92, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
  v4_int32 = {0xff92, 0x0, 0x0, 0x0},
  v2_int64 = {0xff92, 0x0},
  uint128 = 0x0000000000000000000000000000ff92
}
xmm6           {
  v4_float = {0x0, 0x0, 0x0, 0x0},
  v2_double = {0x0, 0x0},
  v16_int8 = {0xf8, 0x51, 0x0, 0x0, 0x33, 0xcc, 0x0, 0x0, 0xc9, 0x7f, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
  v8_int16 = {0x51f8, 0x0, 0xcc33, 0x0, 0x7fc9, 0x0, 0x0, 0x0},
  v4_int32 = {0x51f8, 0xcc33, 0x7fc9, 0x0},
  v2_int64 = {0xcc33000051f8, 0x7fc9},
  uint128 = 0x0000000000007fc90000cc33000051f8
}
xmm7           {
  v4_float = {0x0, 0x0, 0x0, 0x0},
  v2_double = {0x0, 0x0},
  v16_int8 = {0x0 <repeats 16 times>},
  v8_int16 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
  v4_int32 = {0x0, 0x0, 0x0, 0x0},
  v2_int64 = {0x0, 0x0},
  uint128 = 0x00000000000000000000000000000000
}
xmm8           {
  v4_float = {0x0, 0x0, 0x0, 0x0},
  v2_double = {0x0, 0x0},
  v16_int8 = {0x0 <repeats 16 times>},
  v8_int16 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
  v4_int32 = {0x0, 0x0, 0x0, 0x0},
  v2_int64 = {0x0, 0x0},
  uint128 = 0x00000000000000000000000000000000
}
xmm9           {
  v4_float = {0x0, 0x0, 0x0, 0x0},
  v2_double = {0x0, 0x0},
  v16_int8 = {0xe8, 0x3b, 0x3, 0x0, 0xf8, 0x97, 0x2, 0x0, 0x92, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
  v8_int16 = {0x3be8, 0x3, 0x97f8, 0x2, 0xff92, 0x0, 0x0, 0x0},
  v4_int32 = {0x33be8, 0x297f8, 0xff92, 0x0},
  v2_int64 = {0x297f800033be8, 0xff92},
  uint128 = 0x000000000000ff92000297f800033be8
}
xmm10          {
  v4_float = {0x0, 0x0, 0x0, 0x0},
  v2_double = {0x0, 0x0},
  v16_int8 = {0x82, 0xa3, 0x1, 0x0, 0x66, 0x98, 0x1, 0x0, 0x92, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
  v8_int16 = {0xa382, 0x1, 0x9866, 0x1, 0xff92, 0x0, 0x0, 0x0},
  v4_int32 = {0x1a382, 0x19866, 0xff92, 0x0},
  v2_int64 = {0x198660001a382, 0xff92},
  uint128 = 0x000000000000ff92000198660001a382
}
xmm11          {
  v4_float = {0x0, 0x0, 0x0, 0x0},
  v2_double = {0x0, 0x0},
  v16_int8 = {0x92, 0xff, 0x0 <repeats 14 times>},
  v8_int16 = {0xff92, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
  v4_int32 = {0xff92, 0x0, 0x0, 0x0},
  v2_int64 = {0xff92, 0x0},
  uint128 = 0x0000000000000000000000000000ff92
}
xmm12          {
  v4_float = {0x0, 0x0, 0x0, 0x0},
  v2_double = {0x0, 0x0},
  v16_int8 = {0xf8, 0x51, 0x0, 0x0, 0x33, 0xcc, 0x0, 0x0, 0xc9, 0x7f, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
  v8_int16 = {0x51f8, 0x0, 0xcc33, 0x0, 0x7fc9, 0x0, 0x0, 0x0},
  v4_int32 = {0x51f8, 0xcc33, 0x7fc9, 0x0},
  v2_int64 = {0xcc33000051f8, 0x7fc9},
  uint128 = 0x0000000000007fc90000cc33000051f8
}
xmm13          {
  v4_float = {0x0, 0x0, 0x0, 0x0},
  v2_double = {0x0, 0x0},
  v16_int8 = {0x0 <repeats 16 times>},
  v8_int16 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
  v4_int32 = {0x0, 0x0, 0x0, 0x0},
  v2_int64 = {0x0, 0x0},
  uint128 = 0x00000000000000000000000000000000
}
xmm14          {
  v4_float = {0x0, 0x0, 0x0, 0x0},
  v2_double = {0x0, 0x0},
  v16_int8 = {0xe8, 0x3b, 0x3, 0x0, 0xf8, 0x97, 0x2, 0x0, 0x92, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
  v8_int16 = {0x3be8, 0x3, 0x97f8, 0x2, 0xff92, 0x0, 0x0, 0x0},
  v4_int32 = {0x33be8, 0x297f8, 0xff92, 0x0},
  v2_int64 = {0x297f800033be8, 0xff92},
  uint128 = 0x000000000000ff92000297f800033be8
}
xmm15          {
  v4_float = {0x0, 0x0, 0x0, 0x0},
  v2_double = {0x0, 0x0},
  v16_int8 = {0x82, 0xa3, 0x1, 0x0, 0x66, 0x98, 0x1, 0x0, 0x92, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
  v8_int16 = {0xa382, 0x1, 0x9866, 0x1, 0xff92, 0x0, 0x0, 0x0},
  v4_int32 = {0x1a382, 0x19866, 0xff92, 0x0},
  v2_int64 = {0x198660001a382, 0xff92},
  uint128 = 0x000000000000ff92000198660001a382
}
mxcsr          0x1f80   [ IM DM ZM OM UM PM ]

【问题讨论】:

    标签: gdb x86-64


    【解决方案1】:

    来自Intel's instruction set manual 第 3-514 页“MOV — 移入/移出控制寄存器”。

    该指令只有在当前权限等级为0时才能执行。

    由于 GDB 是一个 ring 3 进程,它无法读取cr2 和任何其他控制寄存器。

    当然,进程核心转储不会有控制寄存器,因为这些寄存器不是任务状态的一部分。

    【讨论】:

    • GDB 使用ptrace 系统调用读取寄存器,因为它想要目标进程的状态,而不是它自己。所以关键是cr2 不是进程状态的一部分,它是操作系统查找页面错误地址的一种机制。 GDB 本身在 ring 3 中运行是无关紧要的,因为它通过内核(ring 0)读取目标寄存器。
    【解决方案2】:

    如果您有核心转储文件,并且该文件由 SIGSEGV 或 SIGBUS 触发。 使用 p $_siginfo 并找到 _sigfault 和 si_addr。在这种情况下,si_addr 应该与 cr2 相同。

    例如,

    $5 = {si_signo = 7, si_errno = 0, si_code = 2, ...  _sigfault = {si_addr = 0x7ff6205bee64, ... }
    

    希望这会有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-10-13
      • 1970-01-01
      • 2016-07-20
      • 1970-01-01
      • 2019-11-09
      • 2013-01-19
      • 1970-01-01
      相关资源
      最近更新 更多