崩溃报告中的 CPU 寄存器地址在分析中有何用处?

Posted

技术标签:

【中文标题】崩溃报告中的 CPU 寄存器地址在分析中有何用处?【英文标题】:How are CPU register addresses in crash reports useful in analysis? 【发布时间】:2017-02-08 11:35:45 【问题描述】:

Apple 会生成这些崩溃日志,并且我的线程 0 已崩溃,但这个问题与此无关。这是一个通用问题,我想知道我们如何在崩溃分析中使用这些处理器寄存器值?他们如何帮助您调查车祸?我想到的唯一一件事是,如果任何寄存器后面都有像rcx 这样的空指针,这让您了解代码中可能的空指针取消引用,这是正确的假设吗?

Thread 0 crashed with X86 Thread State (64-bit):
  rax: 0x00000001046e17a0  rbx: 0x00000001043665f0  rcx: 0x0000000000000000  rdx: 0x00000001046e14f0
  rdi: 0x00000001046e14e0  rsi: 0x00000001046314e8  rbp: 0x00007fff5b89f890  rsp: 0x00007fff5b89f7e0
   r8: 0x00007fff686a7690   r9: 0x0000000000000250  r10: 0x00007fffa2478201  r11: 0x000000000009ea18
  r12: 0x00000001046b11d8  r13: 0x00007fff686a75c8  r14: 0x00007fff686ae638  r15: 0x0000000000000000
  rip: 0x00000001043601be  rfl: 0x0000000000010206  cr2: 0x0000000000000060

Logical CPU:     0
Error Code:      0x00000004
Trap Number:     14

【问题讨论】:

他们以各种方式提供帮助;您可以看到内存地址或寄存器的值是什么,这一事实对您有很大帮助...... @l'L'l 没错,但你有哪些使用方法? 【参考方案1】:

您可以使用寄存器 RIP(指令指针)来确定它在哪条机器指令上失败。我不确定 GDB 是否适用于 Mac OSx,但在 Linux 中,您可以使用 GDB(GNU 调试器)然后分析汇编指令以找到产生错误的确切指令。此外,寄存器 RBP(帧指针)和 RSP(堆栈指针)分别指向内存中堆栈的底部和顶部。知道了这一切,你就可以准确地查看崩溃时堆栈是什么,以及是哪条指令导致了崩溃。

【讨论】:

OS X 以前使用 gdb,但是现在 lldb 是标准的。 -fomit-frame-pointer 有几年的默认值(即使是 32 位代码),所以 RBP 只是另一个寄存器(如 RBX 或 R12-R15),而不是帧指针。这种堆栈展开需要元数据(来自.eh_frame 部分)和堆栈内存的内容,所以如果你有核心转储,你可以得到它。【参考方案2】:

除了@nrabbit 所说的之外,如果您知道代码的调用约定,您还可以使用寄存器来了解函数的某些参数的值是什么以及函数调用的结果是什么。 Here are some examples of Intel calling conventions。因此,eax 寄存器通常保存 32 位程序中的函数结果。

【讨论】:

仅当您知道崩溃发生在函数 CALL 或 RET 指令上时。在函数内部,寄存器都是临时暂存空间,直到最终修改 eax 产生返回值。函数也会修改它们的 arg 寄存器。因此,您只需查看崩溃位置的 asm 即可了解这对所涉及的 C 变量意味着什么。 如果不仔细查看 asm 中有关 RIP 值的代码,您可以说没有任何用处。

以上是关于崩溃报告中的 CPU 寄存器地址在分析中有何用处?的主要内容,如果未能解决你的问题,请参考以下文章

intelx86为何从0xFFFF0处执行

Linux内核分析实验四----

Windows 逆向OD 调试器工具 ( 分析 OD 硬件断点处的关键代码 | 添加硬件断点 | 关键代码 | MOV 指令 | EAX 寄存器值分析 | 使用命令查看 esi+0cc 地址 )(代码

SunnyOS准备4

关于寄存器的总结

CPU是怎么执行指令的?