admin管理员组

文章数量:1336346

When I print the address of a variable using %p, I get a very large 12-digit hexadecimal value. However, when I look at the actual layout of my executable using objdump, the variable is located at a much smaller 4-digit hex value. Why is this?

I'm pretty sure the larger address isn't the physical address of the variable, since this is running in user space and definitely shouldn't have access to physical addresses. I've also disabled ASLR for this, so the large address isn't just a product of the randomization.

#include <unistd.h>
#include <stdio.h>

static int testInt = 5;

int main() {
    printf("address of testInt: %p\n", (void*)&testInt);

    return 0;
}

When I run this, it prints the address 0x555555558010 for testInt. However, according to objdump, testInt is located at byte 0000000000004010.

When I print the address of a variable using %p, I get a very large 12-digit hexadecimal value. However, when I look at the actual layout of my executable using objdump, the variable is located at a much smaller 4-digit hex value. Why is this?

I'm pretty sure the larger address isn't the physical address of the variable, since this is running in user space and definitely shouldn't have access to physical addresses. I've also disabled ASLR for this, so the large address isn't just a product of the randomization.

#include <unistd.h>
#include <stdio.h>

static int testInt = 5;

int main() {
    printf("address of testInt: %p\n", (void*)&testInt);

    return 0;
}

When I run this, it prints the address 0x555555558010 for testInt. However, according to objdump, testInt is located at byte 0000000000004010.

Share Improve this question asked Nov 20, 2024 at 2:33 EnderhippoEnderhippo 651 silver badge7 bronze badges 1
  • 2 You're correct that it isn't a physical address -- it's a virtual memory address. Maybe start with en.m.wikipedia./wiki/Position-independent_code, which covers historical reasoning. – Charles Duffy Commented Nov 20, 2024 at 2:58
Add a comment  | 

2 Answers 2

Reset to default 2

What you're seeing is a virtual offset. The kernel picks a base address to load the program at (even without ASLR) and the segments of your ELF file will be loaded relative to that address. Without ASLR, 0x555555554000 is used as the base address (see the ELF_ET_DYN_BASE macro in the kernel source), and since your symbol is at a virtual offset of 0000000000004010, that comes out to 0x555555558010.

That is, assuming your program is compiled as a PIE, which it looks like it is.

It is the function of the OS loader to locate code at runtime as a whole, the "addresses" in the executable are offsets from the final runtime location, not absolute addresses.

Modern operating systems will load to a virtual address and typically (though in this case you have disabled it) use address space layout randomization (ASLR) as a security measure against certain types of attack - so it may not even be the same address between executions.

本文标签: