关于c ++:在反汇编代码中跟踪调用堆栈

Tracing call stack in disassembled code

我正在尝试调试一个复杂的核心转储(从-o2优化的二进制文件)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 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)
   {
     .....
   }
}

在调用者和被调用者中,第一个参数都被优化了,这意味着它必须在寄存器的某个地方。调用方反汇编:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
push   %r15
mov    %rdi,%r15
push   %r14
push   %r13
push   %r12
push   %rbp
push   %rbx
sub    $0x68,%rsp
test   %rsi,%rsi
je     0x8ccd62
cmpq   $0x0,(%rsi)
je     0x8ccd62
lea    0x40(%rsp),%rax
lea    0x1b8(%rdi),%rdi
mov    %rax,(%rsp)
mov    %rax,0x40(%rsp)
mov    %rax,%rdx
mov    %rax,0x48(%rsp)
mov    (%rsi),%rsi
callq  0x8cc820

呼叫者注册信息:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
rax            0x7fbfffc7e0 548682057696
rbx            0x2a97905ba0 182931446688
rcx            0x0  0
rdx            0x2  2
rsi            0x1  1
rdi            0x7fbfffc7e2 548682057698
rbp            0x4f 0x4f
rsp            0x7fbfffc870 0x7fbfffc870
r8             0x40 64
r9             0x20 32
r10            0x7fbfffc7e0 548682057696
r11            0x2abe466600 183580911104
r12            0x7fbfffd910 548682062096 // THIS IS HOLDING buf_
r13            0x7fbfffdec0 548682063552
r14            0x5dc    1500
r15            0x2a97905ba0 182931446688
rip            0x8cca89 0x8cca89
eflags         0x206    [ PF IF ]
cs             0x33 51
ss             0x2b 43
ds             0x0  0
es             0x0  0
fs             0x0  0
gs             0x0  0

调用的函数反汇编:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
push   %r14
push   %r13
mov    %rdx,%r13
push   %r12
mov    %rdi,%r12
push   %rbp
push   %rbx
sub    $0x10,%rsp
mov    0x8(%rdi),%rdx
test   %rdx,%rdx
jne    0x8cc843
jmpq   0x8cc9cb
mov    %rax,%rdx
mov    0x8(%rdx),%rax
test   %rax,%rax
mov    %rsi,0x8(%rdx)
mov    0x8(%r12),%rax
test   %rax,%rax
xor    %edx,%edx
add    0x4(%rax),%edx
mov    0x8(%rax),%rax
lea    0x8(%rsp),%rsi
mov    %r12,%rdi
movq   $0x0,0x8(%rsp)

调用函数寄存器信息:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
rax            0x7fbfffc7e0     548682057696
rbx            0x2abc49f9c0     183547591104
rcx            0x0      0
rdx            0x2      2
rsi            0x1      1
rdi            0x7fbfffc7e2     548682057698
rbp            0xffffffff       0xffffffff
rsp            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
rip            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)。

我确实在某种程度上理解汇编,但是所有这些代码内联都让我感到困惑。在消除所谓的函数反汇编中会得到一些帮助。更新:添加数据如下:

1
2
3
4
5
6
7
<wyn>
if (m_data_in) {
    m_data_in->next = data;
} else {
    m_data_in = data;
}
</wyn>


这看起来像是if (m_data_in)

1
2
3
4
5
mov    0x8(%rdi),%rdx
test   %rdx,%rdx
test   %rdx,%rdx
jne    0x8cc843
jmpq   0x8cc9cb

现在,我不太清楚0x8cc8430x8cc9cb在您的代码中的位置,因此不能进一步遵循代码。仍然没有足够的代码和信息来准确说明原始问题中发生了什么。如果提供更多信息,我很乐意填写更多的答案。