1

I'm on an Ubuntu ( 22.04.3) x86_64 system.

I know how virtual memory and pages work in general and I also know that systems can use ASLR. However I'd like to know what exactly happens in an Ubuntu system in this specific scenario. I have this little program in a file named test.c :

#include <stdio.h>

int main(){

    int a = 10;
    a++;
    printf("%p\n",(void*)&main);
}

I've compiled this file with "gcc test.c -o test". Then I ran the command "objdump -d test" and I got this :


0000000000001149 <main>:
    1149:   f3 0f 1e fa             endbr64 
    114d:   55                      push   %rbp
    114e:   48 89 e5                mov    %rsp,%rbp
    1151:   48 83 ec 10             sub    $0x10,%rsp
    1155:   c7 45 fc 0a 00 00 00    movl   $0xa,-0x4(%rbp)
    115c:   83 45 fc 01             addl   $0x1,-0x4(%rbp)
    1160:   48 8d 05 e2 ff ff ff    lea    -0x1e(%rip),%rax        # 1149 <main>
    1167:   48 89 c6                mov    %rax,%rsi
    116a:   48 8d 05 93 0e 00 00    lea    0xe93(%rip),%rax        # 2004 <_IO_stdin_used+0x4>
    1171:   48 89 c7                mov    %rax,%rdi
    1174:   b8 00 00 00 00          mov    $0x0,%eax
    1179:   e8 d2 fe ff ff          call   1050 <printf@plt>
    117e:   b8 00 00 00 00          mov    $0x0,%eax
    1183:   c9                      leave  
    1184:   c3                      ret 

As you can see main address is 0x1149. When I run the program the address of main is different, and it is different each time I run it. I've done it three times and I got three different results :

0x55b032770149
0x5615f1082149
0x557829668149

I can infer this has something to do with ASLR. Here are my questions :

  1. How did we get from 0x1149 to for example 0x55b032770149 ? What is the whole process that happens under the hood ?

  2. Are the addresses printed in a C program, like 0x55b032770149, the actual and definitive virtual addresses of our programs ?

  3. Does the RIP register contain virtual addresses, like for example, 0x55b032770149 as the address of the next instruction to execute ?

alessio solari
  • 313
  • 1
  • 6
  • 2
    The R in ASLR stands for Randomization. So the address is chosen randomly. – Barmar Aug 16 '23 at 16:04
  • 2
    Yes, they're the actual address. And user-mode processes only deal with virtual addresses, so they couldn't be anything else. – Barmar Aug 16 '23 at 16:05
  • 1
    `objdump` is before loading the program into the process, while the `printf` occurs afterw loading. – Erik Eidt Aug 16 '23 at 16:12
  • @Erik Eidt, how would you briefly answer the three questions I made ? – alessio solari Aug 16 '23 at 16:14
  • 1
    2. yes. 3. yes, it did on entry to `main`, like you could see with GDB if you single-step. 1. notice how the low 3 hex digits are the same; it just added a large random number starting with `0x55` to the placeholder `0x1000` address from your ELF metadata. [How is the address of the text section of a PIE executable determined in Linux?](https://stackoverflow.com/q/51343596) – Peter Cordes Aug 16 '23 at 16:34
  • 1
    Also related: [How to find load relocation for a PIE binary?](https://stackoverflow.com/q/55066749) / [I am wondering if pie does anything if the aslr is turned off on the system? Or is pie dependant on aslr?](https://stackoverflow.com/q/61061830) / [pie base address is fixed in gdb](https://stackoverflow.com/q/22148084) / [ELF, PIE ASLR and everything in between, specifically within Linux](https://stackoverflow.com/q/38189169) – Peter Cordes Aug 16 '23 at 16:36
  • @Peter Cordes, when you said 2.yes. 3.yes were you referring to your answers to my questions 2 and 3 respectively ? – alessio solari Aug 16 '23 at 16:39
  • 1
    If you had looked at the /proc//maps file for each of those runs, you would have seen the first mapping starting at address 0x55b03276f000, 0x5615f1081000, 0x557829667000 respectively, i.e. the address of `main` minus 0x1149. (If the ELF file had a non-zero base address, you would need to subtract that too, but your ELF file has a zero base address.) – Ian Abbott Aug 16 '23 at 17:27
  • 1
    @alessiosolari: Yes, of course. "the actual and definitive virtual addresses of our programs ?" **Yes for this execution**; it's randomized so it can be different for different runs. Re: function addresses, see also [Unexpected value of a function pointer local variable](https://stackoverflow.com/q/56760086) - compilers may choose to just get the address of a PLT stub instead of the actual function address, for shared library functions in non-PIE executables. That's a non-issue for a program that prints the address of its own functions like `main`, though. – Peter Cordes Aug 16 '23 at 17:36

0 Answers0