崩溃报告中的 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 寄存器地址在分析中有何用处?的主要内容,如果未能解决你的问题,请参考以下文章
Windows 逆向OD 调试器工具 ( 分析 OD 硬件断点处的关键代码 | 添加硬件断点 | 关键代码 | MOV 指令 | EAX 寄存器值分析 | 使用命令查看 esi+0cc 地址 )(代码