So here's the deal. I am working on a debugger using a pin tool and the dwarf info from the process that I am attaching to. Pin is a framework that lets you create instrumentation tools for processes that are already running, I attach to the process and then I parse the DWARF info from it.
Obviously, pin let me grab the registers in the precise moment on where I attach to the program. I am able to get ebp
, esp
, and eip
. But the information from the stack doesn't match the information from the DWARF info.
For example:
Pin tells me that ebp
is: bfe0abe8
I assume this is the actual address of the register and not the value that is inside of it.
If I go to the stack I have this:
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
And a lot more, I don't know what is actually the bottom of the stack, so I am showing just a bit of it.
If I go to the DWARF info, this is the function that the top of the stack is currently in, and which ebp should be pointing to:
<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
I know this because the local variables that I see on the stack are inside this function. These local variables are:
<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
I know that according to DWARF (and this: How to see variables stored on the stack with GDB), ebp in this function should be the current ebp + 8 (which because I am working with DWORD should be +2). And then I should subtract -24 to 8, making it ebp-16 (ebp-4 in reality). On paper this should work, but when going to the stack I am encountering a lot of problems:
- I am not even seeing near the top of the stack the address of the current ebp that pin is returning to me.
- Assuming that
bfe0abb9
is the current ebp and that pin is actually returning the value, and not the address, of the register if I subtract 4 from that register I would not be getting the value of tib, since as my understanding of the stack, I would be going up not down. And even if I would be going down when trying to get jos (ebp-28+8 = ebp -20 = ebp -5
) I would definitely not be getting jos but000000a
.
Am I missing something here? Am I having a wrong understanding of the stack and/or registers or DWARF info? Or is Pin screwing me up and giving the wrong information?
Any suggestions?