如何在核心文件中编辑 $rip 和 $rsp 以帮助调试器生成更加用户友好的体验?

问题描述 投票:0回答:2

我目前正在尝试调试导致堆栈损坏的 C++ 应用程序崩溃。 经过一番调查后,我非常确定我知道有效的 $rsp 和 $rip 地址,它们对应于堆栈上应该未损坏的非常有用的帧。

当 gdb 具有有效堆栈时,能够使用 gdb 的所有内置功能来处理动态寻址调用将非常有用。 不幸的是,gdb 在调试核心文件时无法直接设置这些寄存器值,并且我发现了一个十年前的功能请求,要求此功能。

有没有办法直接编辑核心文件来设置这些值? 或者 lldb 是否可能允许您在调试核心文件时覆盖这些寄存器值?

gdb x86-64 binaryfiles elf core-file
2个回答
4
投票

有没有办法直接编辑核心文件来设置这些值?

当然——这些值存储在

core
某处;诀窍是找出确切的位置。

寄存器值存储在

PRSTATUS
注释中(第一个这样的注释通常是与崩溃线程对应的注释)。

您可以使用

core
elfutils
检查现有
eu-readelf -Wn core
中的笔记。输出将类似于:

Note segment of 5200 bytes at offset 0x580:
  Owner          Data size  Type
  CORE                 336  PRSTATUS
    info.si_signo: 3, info.si_code: 0, info.si_errno: 0, cursig: 3
    sigpend: <>
    sighold: <>
    pid: 4174783, ppid: 140563, pgrp: 4174783, sid: 140563
    utime: 0.000000, stime: 0.000000, cutime: 0.000000, cstime: 0.000000
    orig_rax: 230, fpvalid: 1
    r15:         140725686367064  r14:                       1
    r13:         140725686367064  r12:         140725686366544
    rbp:      0x00007ffd408bf190  rbx:                      60
    r11:                     514  r10:         140725686366608
    r9:                        0  r8:                        0
    rax:                    -516  rcx:         139740173005747
    rdx:         140725686366544  rsi:                       0
    rdi:                       0  rip:      0x00007f17cb5f73b3
    rflags:   0x0000000000000202  rsp:      0x00007ffd408bf138
    fs.base:   0x00007f17cb525740  gs.base:   0x0000000000000000
    cs: 0x0033  ss: 0x002b  ds: 0x0000  es: 0x0000  fs: 0x0000  gs: 0x0000

在这里您可以看到

Note
位于偏移量
0x580
处,并且
rsp
寄存器位于其中的某个位置。

从这里,您可以使用

offsetof(struct elf_prstatus, pr_reg)
112
上的
x86_64
)和
offsetof(struct user_regs_struct, rsp)
152
)。

如果我的算术正确,

rsp
的值应该是
0x580 + 20 + 112 + 152
。让我们检查一下:

xxd -e -s $((0x580+20+112+152)) -g8 core | head -1
0000069c: 00007ffd408bf138 000000000000002b  8..@....+.......

因此,将偏移量

0x69c
处的 8 字节值覆盖到此
core
中应该会产生所需的结果。

附注多余的

20
从哪里来?
Elf64_Nhdr
在音符数据开始之前有一些数据项:
n_namesz, n_descsz, n_type
(每个 4 字节),后跟音符名称(此处为
CORE\0
),四舍五入到 4 字节边界(因此总共 8 字节)。


0
投票

您可以使用

$rsp
十六进制搜索
$rip
mcview
值(作为小端)并根据需要进行更新。

© www.soinside.com 2019 - 2024. All rights reserved.