-1

Please refer to the below program:

#include<stdio.h>
int main()
{
        int a, b;
        printf("address of main =%p\n", main);
        a=3;
        printf("Address of 'a' =%p\n", &a);
        return 0;
}

I compiled the above program using gcc and then ran the binary. I am getting the below output:

[root@localhost gdb]# ./a.out
address of main =0x400536
Address of 'a' =0x7ffc4802cbdc
[root@localhost gdb]# ./a.out
address of main =0x400536
Address of 'a' =0x7ffe2bdcd66c
[root@localhost gdb]#

Same source code compiled with –m32, now I'm getting the output:

[root@localhost gdb]# ./a.out
address of main =0x804841b
Address of 'a' =0xffa6b29c
[root@localhost gdb]# ./a.out
address of main =0x804841b
Address of 'a' =0xff9b808c

Here is my question: why the address of a variable range has changed while running 64 and 32 bits application in 64 bit kernel?. The main function address remains unchanged, Why does a variable addresses change every run? And where is the address of a variable stored?

Dmitriy
  • 3,305
  • 7
  • 44
  • 55
  • How would a 32-bit program be able to use a 64-bit address space? It doesn't, 32 bits means 32 bits. – Some programmer dude Jan 11 '19 at 14:16
  • 3
    Also please read about [ASLR (Address Space Layout Radnomization)](https://en.wikipedia.org/wiki/Address_space_layout_randomization). – Some programmer dude Jan 11 '19 at 14:22
  • 1
    Lastly please read [the help pages](http://stackoverflow.com/help), especially ["What topics can I ask about here?"](http://stackoverflow.com/help/on-topic) and ["What types of questions should I avoid asking?"](http://stackoverflow.com/help/dont-ask). Also [take the tour](http://stackoverflow.com/tour) and [read about how to ask good questions](http://stackoverflow.com/help/how-to-ask) and [this question checklist](https://codeblog.jonskeet.uk/2012/11/24/stack-overflow-question-checklist/). And please, one question per question. – Some programmer dude Jan 11 '19 at 14:23
  • You have a position-dependent executable, so you don't have code ASLR, only stack ASLR. If you built a PIE, you'd get a varying address for `main`, too. (But 32-bit PIE is slow, don't actually use it.) See [32-bit absolute addresses no longer allowed in x86-64 Linux?](https://stackoverflow.com/q/43367427) for more about PIE vs. non-PIE. – Peter Cordes Jan 12 '19 at 09:43
  • This had nothing to do with embedded systems or assembly, please don't abuse tags. – Chris Stratton Jan 12 '19 at 18:45

1 Answers1

2

The software that loads programs intentionally varies the location of the stack in each execution to make it harder for attackers to exploit bugs.

The program knows where a is because its offset within the stack frame of main is built into it by the compiler, and the address of the stack frame for main comes from the stack pointer passed to main by the software that loads the program and starts main.

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312
  • Thanks for your update. Another doubt is that the 3: 1 memory splits are not applicable to 32-bit applications on 64-bit kernels. That's what address of "a" variable is stored in outside of 3GB of address space. is it right here? – user3172612 Jan 11 '19 at 14:50
  • @user3172612: yes, Linux always puts the user-space stack at a virtual address near the top of the user-space range. For 32-bit user-space under a 64-bit kernel, that's near the highest possible address. (But not quite, because the VDSO claims the top two usable pages, and the highest page is reserved for pointer-values that mean "error" inside the kernel. See [Why can't I mmap(MAP\_FIXED) the highest virtual page in a 32-bit Linux process on a 64-bit kernel?](https://stackoverflow.com/q/47712502). – Peter Cordes Jan 12 '19 at 09:41