0
votes

I have 2 array of type Char in the main() as shown below :

char a[8]="aaaaaaaa";
char b[8] = "bbbbbbbb";

When I print value of &a and &b, I got 0x7ffeefbffa40 and 0x7ffeefbffa38 respectively from gdb. However when I did Info frame, I got the following :

Stack level 0, frame at 0x7ffeefbffa60:
 rip = 0x100003e0a in main (bufferoverflowex1.c:8); saved rip = 0x7fff20395621
 source language c.
 Arglist at 0x7ffeefbffa50, args: 
 Locals at 0x7ffeefbffa50, Previous frame's sp is 0x7ffeefbffa60
 Saved registers:
  rbp at 0x7ffeefbffa50, rip at 0x7ffeefbffa58

I am confused with the value of Locals. It is xxxxffa50. However the addresses of local variables are xxxx40 and xxxx38. How is it possible that variables are stored at the address previous to Locals address returned by info frame ?

3
Local variables are stored on the stack. The stack starts from a high address and grows down to lower addresses.kaylum
Both your arrays are too short.stark
You can study how strings work in C here: How should character arrays be used as strings?.Lundin

3 Answers

0
votes

How is it possible that variables are stored at the address previous to Locals address returned by info frame ?

There is nothing surprising or unusual about it.

On most modern machines, stack grows down (towards lower addresses). So the call frame layout looks something like this:

                   caller stack frame

                   return address
                   saved previous frame pointer
0x7ffeefbffa60 ->
                   space for other callee-saved registers
0x7ffeefbffa50 ->
                   other locals
0x7ffeefbffa48 ->
                   a[8]
0x7ffeefbffa40 ->
                   b[8]
0x7ffeefbffa38 ->
                   possibly other locals, alloca(), unnamed temporaries, etc.

When GDB says "locals at 0xADDRESS", on this (and other "stack grows down" machines), it means "locals are below 0xADDRESS.

0
votes

As established, stack grows downward on x86, ARM. Well, consider for example the following program:

void func(void) {
    int a;
    {
        int b;
    }
    {
        int c;
    }
}

The lifetime of b and c do not overlap so they could be stored at the same location on stack. Clearly however to not waste space, they must be at top of stack, i.e. below a in memory.

Now, if you have an arbitrary complex function to get lowest address where locals are stored, gets a bit tedious. You'd have to assemble the entire function until you'd know the lowest address of the local variables. And it would not help you one bit - because one thing that is easily kept track of is the beginning of the local variables (i.e. the highest address), usually relative to a frame pointer register.

0
votes

Memory for local variables in a function is allocated from the stack, just like this(if you compile with stack-protecter):

  High Memeory Address
[       Allocated     ]
[       Allocated     ]
[       Allocated     ]
[       Allocated     ]
                       <--0x7ffeefbffa50
[       Allocated     ]
[          b          ]
                       <--0x7ffeefbffa40
[          a          ]
                       <--0x7ffeefbffa38
[       Unallocated   ]
[       Unallocated   ]
[       Unallocated   ]
[       Unallocated   ]
[       Unallocated   ]
  Low Memeory Address

if you compile with "-fno-stack-protector" argument, the variables will locate like this in stack(not completely consistent with your results):

  High Memeory Address
[       Allocated     ]
[       Allocated     ]
[       Allocated     ]
[       Allocated     ]
                       <--0x7ffeefbffa50
[          a          ]
                       <--0x7ffeefbffa48
[          b          ]
                       <--0x7ffeefbffa40
[       Unallocated   ]
[       Unallocated   ]
[       Unallocated   ]
[       Unallocated   ]
[       Unallocated   ]
  Low Memeory Address

And according to your result, i think you can refer to the first one.