在反汇编代码中跟踪调用堆栈
Posted
技术标签:
【中文标题】在反汇编代码中跟踪调用堆栈【英文标题】:Tracing call stack in disassembled code 【发布时间】:2014-05-29 20:34:24 【问题描述】:我正在尝试调试一个棘手的核心转储(来自 -O2 优化的二进制文件)。
// Caller Function
void caller(Container* c)
std::list < Message*> msgs;
if(!decoder.called(c->buf_, msgs))
....
.....
// Called Function
bool
Decoder::called(Buffer* buf, list < Message*>& msgs)
add_data(buf); // Inlined code to append buf to decoders buf chain
while(m_data_in && m_data_in->length() > 0)
.....
在调用者和被调用者中,第一个参数都被优化了,这意味着它必须在寄存器中的某个地方。 调用者反汇编:
推 %r15 移动 %rdi,%r15 推 %r14 推 %r13 推 %r12 推%rbp 推%rbx 低于 $0x68,%rsp 测试 %rsi,%rsi 0x8ccd62 cmpq $0x0,(%rsi) 0x8ccd62 lea 0x40(%rsp),%rax lea 0x1b8(%rdi),%rdi mov %rax,(%rsp) mov %rax,0x40(%rsp) mov %rax,%rdx mov %rax,0x48(%rsp) 移动 (%rsi),%rsi 呼叫 0x8cc820来电登记信息:
rax 0x7fbfffc7e0 548682057696 rbx 0x2a97905ba0 182931446688 回复 0x0 0 rdx 0x2 2 rsi 0x1 1 rdi 0x7fbfffc7e2 548682057698 rbp 0x4f 0x4f 回复 0x7fbfffc870 0x7fbfffc870 r8 0x40 64 r9 0x20 32 r10 0x7fbfffc7e0 548682057696 r11 0x2abe466600 183580911104 r12 0x7fbfffd910 548682062096 // 这是持有 buf_ r13 0x7fbfffdec0 548682063552 r14 0x5dc 1500 r15 0x2a97905ba0 182931446688 撕裂 0x8cca89 0x8cca89 eflags 0x206 [PF IF] CS 0x33 51 ss 0x2b 43 ds 0x0 0 es 0x0 0 fs 0x0 0 GS 0x0 0调用函数反汇编:
推 %r14 推 %r13 移动 %rdx,%r13 推 %r12 移动 %rdi,%r12 推%rbp 推%rbx 低于 $0x10,%rsp mov 0x8(%rdi),%rdx 测试 %rdx,%rdx jne 0x8cc843 jmpq 0x8cc9cb mov %rax,%rdx mov 0x8(%rdx),%rax 测试 %rax,%rax mov %rsi,0x8(%rdx) mov 0x8(%r12),%rax 测试 %rax,%rax 异或 %edx,%edx 添加 0x4(%rax),%edx mov 0x8(%rax),%rax lea 0x8(%rsp),%rsi 移动 %r12,%rdi movq $0x0,0x8(%rsp)调用函数注册信息:
rax 0x7fbfffc7e0 548682057696 rbx 0x2abc49f9c0 183547591104 回复 0x0 0 rdx 0x2 2 rsi 0x1 1 rdi 0x7fbfffc7e2 548682057698 rbp 0xffffffff 0xffffffff 回复 0x7fbfffc830 0x7fbfffc830 r8 0x40 64 r9 0x20 32 r10 0x7fbfffc7e0 548682057696 r11 0x2abe466600 183580911104 r12 0x2a97905d58 182931447128 r13 0x7fbfffc8b0 548682057904 r14 0x5dc 1500 r15 0x2a97905ba0 182931446688 撕裂 0x8cc88a 0x8cc88a eflags 0x206 [PF IF] CS 0x33 51 ss 0x2b 43 ds 0x0 0 es 0x0 0 fs 0x0 0 GS 0x0 0问题是,在被调用的函数中,"add_data"
函数似乎什么也没做。
所以,想知道在被调用函数的反汇编中,我们是否看到"buf_"
指针在任何地方被使用(在被调用函数中注册r12)。
我确实在一定程度上了解汇编,但所有这些代码内联都让我感到困惑。 希望能在消除被调用函数反汇编方面提供一些帮助。 更新: add_data 如下:
if (m_data_in)
m_data_in->next = data;
else
m_data_in = data;
【问题讨论】:
首先,还要显示add_data()
的来源。然后,确保您正在编译正确的源代码,而不是 add_data()
尚未完成的旧版本。
很难说不知道 add_data
和 buf
的实际样子(并且在反汇编中没有地址也无济于事)
@VáclavZeman:感谢您的回复。这段代码已经投入生产了大约 1.5 年。确定 add_data 已完成。
@MatsPetersson:感谢您的回复。这时候我只想知道,传入的buf_的地址是否在被调用函数的任何地方使用。
就像我说的,我们需要看看add_data
做了什么。
【参考方案1】:
这看起来像if (m_data_in)
mov 0x8(%rdi),%rdx
test %rdx,%rdx
test %rdx,%rdx
jne 0x8cc843
jmpq 0x8cc9cb
现在,我不太清楚 0x8cc843
和 0x8cc9cb
在您的代码中的位置,因此无法真正进一步遵循代码。仍然没有足够的代码和信息来准确说明原始问题中发生了什么。如果提供更多信息,我很乐意填写更多此答案。
【讨论】:
非常感谢您在这方面的帮助。我将再次查看大会以检查您所说的内容。会回复你的:) 我心平气和地详细看了一下程序集,完全可以看到add_data函数的说明。但是,无法理解我在所谓的反汇编“movq $0x0,0x8(%rsp)”中发布的最后一条指令的目的。 "mov %rsi,0x8(%rdx)" 基本上是将我的第二个参数分配给被调用函数的指令到 next_ 字段。在此之后,我没有看到任何改变“rdx”值的指令。仍然在寄存器信息中显示看似不正确的 0x2 值。有什么可能的原因吗? 另外,我还没有发布整个程序集,因为它很大,但你可以相信我上面的评论:)。我已经完全经历过了 了解汇编代码。看起来不错,但我想我无法追查到底发生了什么。以上是关于在反汇编代码中跟踪调用堆栈的主要内容,如果未能解决你的问题,请参考以下文章