所以这是交易。我正在使用 pin 工具和我附加到的进程中的 dwarf 信息来开发调试器。Pin 是一个框架,可让您为已经运行的进程创建检测工具,我附加到该进程,然后从中解析 DWARF 信息。
显然,pin 让我可以在我附加到程序的精确时刻抓住寄存器。我能够得到ebp
,esp
和eip
. 但是堆栈中的信息与 DWARF 信息中的信息不匹配。
例如:
Pin 告诉我ebp
:bfe0abe8
我假设这是寄存器的实际地址,而不是其中的值。
如果我去堆栈,我有这个:
bfe0abb5 -> 00000020 \\this is esp
bfe0abb6 -> 0804855d
bfe0abb7 -> 08048720
bfe0abb8 -> 0000000a
bfe0abb9 -> bfe0abe8 \\this is what I think is ebp, but according to pin is not
bfe0abba -> 0015711f
bfe0abbb -> bfe0ac28
bfe0abbc -> 4236b852 \\this is a local float variable named jos
bfe0abbd -> 42c0947b \\this is a local float variable named tib
bfe0abbe -> 0000000a
bfe0abbf -> 08048724
bfe0abc0 -> bfe0abf8
bfe0abc1 -> bfe0ac28
bfe0abc2 -> 08048612
bfe0abc3 -> 00000000
bfe0abc4 -> 0000000a
bfe0abc5 -> 00006680
bfe0abc6 -> 08048689
bfe0abc7 -> 00266324
bfe0abc8 -> 00265ff4
bfe0abc9 -> 936498a8
bfe0abca -> 4072464d
bfe0abcb -> 0013f4a5
bfe0abcc -> 424ab852 \\this is another local variable
bfe0abcd -> 42bc947b \\this is another local variable
bfe0abce -> 0000000a
bfe0abcf -> 08048670
bfe0abd0 -> 00000000
bfe0abd1 -> bfe0aca8
还有很多,我不知道堆栈的底部实际上是什么,所以我只展示了一点。
如果我转到 DWARF 信息,这是堆栈顶部当前所在的函数,并且 ebp 应该指向:
<1>< 962> DW_TAG_subprogram
DW_AT_external yes(1)
DW_AT_name add
DW_AT_decl_line 36
DW_AT_prototyped yes(1)
DW_AT_low_pc 0x8048513
DW_AT_high_pc 0x804855f
DW_AT_frame_base <loclist with 3 entries follows>
[ 0]<lowpc=0x2f><highpc=0x30>DW_OP_breg4+4
[ 1]<lowpc=0x30><highpc=0x32>DW_OP_breg4+8
[ 2]<lowpc=0x32><highpc=0x7b>DW_OP_breg5+8
我知道这一点,因为我在堆栈上看到的局部变量在这个函数内部。这些局部变量是:
<2>< 1029> DW_TAG_variable
DW_AT_name tib
DW_AT_decl_line 38
DW_AT_type <837>
DW_AT_location DW_OP_fbreg -24
<2>< 1043> DW_TAG_variable
DW_AT_name jos
DW_AT_decl_line 39
DW_AT_type <837>
DW_AT_location DW_OP_fbreg -28
我知道根据 DWARF(以及这个:如何使用 GDB 查看存储在堆栈上的变量),此函数中的 ebp 应该是当前的 ebp + 8(因为我正在使用 DWORD 应该是 +2)。然后我应该将 -24 减去 8,使其成为 ebp-16(实际上是 ebp-4)。在纸上这应该可以工作,但是在进入堆栈时我遇到了很多问题:
- 我什至没有在堆栈顶部附近看到该引脚返回给我的当前 ebp 的地址。
- 假设这
bfe0abb9
是当前的 ebp 并且该引脚实际上返回的是寄存器的值,而不是地址,如果我从该寄存器中减去 4,我将不会得到 tib 的值,因为根据我对堆栈的理解,我会上升而不是下降。即使我在尝试获取 jos (ebp-28+8 = ebp -20 = ebp -5
) 时会失败,但我绝对不会得到 jos000000a
。
我在这里错过了什么吗?我对堆栈和/或寄存器或 DWARF 信息有错误的理解吗?还是 Pin 搞砸了我并提供了错误的信息?
有什么建议么?