Mask
Mask

Reputation: 34207

Why is a function executed from the same memory address each time?

I'm disassembling an executable:

(gdb) disas main
Dump of assembler code for function main:
0x004012d0 <main+0>:    push   %ebp
0x004012d1 <main+1>:    mov    %esp,%ebp
...

Each time the memory address is the same:0x004012d0.

Isn't the memory address to be dynamically assigned by the OS?

UPDATE

Now I see it's virtual space,and it can be randomized on some platforms.

Can someone post a gdb dump that changes ?

Upvotes: 10

Views: 2549

Answers (8)

Peter Teoh
Peter Teoh

Reputation: 6733

These are terminologies from computer security. In the past it was fixed address (< 1996, according to LKML, but it is only recently that executeable began to be compiled as relocatable, in order to implement ASLR. (But much longer ago, all libraries have been compiled as relocatable, so that libraries can be reloaded into different addresses if necessary - read dynamic relocation but due to order of loading, those main syscall API is normally loaded into fixed address.) Even today,

doing a gdb /bin/ls and following by "run", u will discover that default address is not change:

(gdb) disassemble __open Dump of assembler code for function open: 0xb7f017f0 <+0>: cmpl $0x0,%gs:0xc 0xb7f017f8 <+8>: jne 0xb7f0181c

Anyway, ASLR originate with PaX - read the wiki, it covered a lot on the requirements of implementing ASLR.

Why ASLR? To prevent 2 types of attack: http://en.wikipedia.org/wiki/Return-to-libc_attack and http://en.wikipedia.org/wiki/Return-oriented_programming, because both attack assumed your code area if fixed in memory.

Upvotes: 0

Mike Dinsdale
Mike Dinsdale

Reputation: 1511

I think the problem here (at least on Linux) might be gdb trying to help out, from the docs:

set disable-randomization

set disable-randomization on

This option (enabled by default in gdb) will turn off the native randomization of the virtual address space of the started program. This option is useful for multiple debugging sessions to make the execution better reproducible and memory addresses reusable across debugging sessions.

This feature is implemented only on gnu/Linux. You can get the same behavior using

         (gdb) set exec-wrapper setarch `uname -m` -R

http://sourceware.org/gdb/current/onlinedocs/gdb/Starting.html

UPDATE: I've now checked this and it does seem to be the case for me (running Linux 2.6.28). Compile a simple Hello World program and start gdb with no command-line args (we don't want to load the program before overriding the disable-randomization setting) and then enter:

(gdb) set disable-randomization off
(gdb) file ./a.out
(gdb) break main
(gdb) run
(gdb) disas printf

The address of printf is different each time the program is run.

Upvotes: 4

Suma
Suma

Reputation: 34423

Executable relocation

Some executables are set so that they are always loaded at the same address. Some are set so that they are "relocatable". The option controlling this in Visual Studio linker is called /FIXED. Even such executables are most often loaded at preferred address. Newer OS (Win7, Vista) randomize the loading address for some executables to improve security (attacking process loaded at unknown address is harder) - this is called ASLR. Note: Even executable marked as /FIXED:NO is not assumed to be suitable for ASLR. Developer needs to allow ASLR explicitly for the executable.

Virtual address space

Note: It is important to understand the process owns the whole address space. Multiple processes have each address space of their own, therefore if you launch the same executable multiple times, there is no reason why it could not be loaded at the same address every time.

Upvotes: 2

mrjoltcola
mrjoltcola

Reputation: 20842

That is a virtual address. The physical address is known to the OS, but each process has its own virtual address space. A relocatable image is likely to get the same mapping everytime, especially the main executable. But it is not guaranteed. An example is DLLs. DLLs may load in different order, resulting in different virtual addresses between runs, because as DLL 1 is loaded, then DLL 2 cannot be loaded into that virtualaddress and must get its own address.

Upvotes: 2

rook
rook

Reputation: 67029

It depends on the OS. Most of the time the address of the binary stays the same. This is important for exploiting memory manipulation bugs, such as buffer overflows. The address of linked libraries under Linux will always be different due to ASLR. Under Windows Vista and Windows 7 the binary's virtual memory space is also randomized each time it is executed, so the function address will be different for each run.

Upvotes: 3

Paul R
Paul R

Reputation: 213039

It depends on the operating systems. In most modern operating systems with virtual memory there is no need for executable code to be relocatable, but in older operating systems, and in some specialised operating systems (e.g. real-time, embedded) code overlays may be used in conjunction with position-independent code and jump tables. In this case it's possible for a function's address to change, e.g. if its code segment is swapped out and then swapped back in at a different address.

Upvotes: 0

tloach
tloach

Reputation: 8040

Yes and no. The physical memory is allocated by the OS, and only the OS is aware of where your program is in physical RAM. Your program only sees the virtual address, which will always be the same if everything is loaded in the same order.

Upvotes: 2

Anon
Anon

Reputation: 345

Why would the OS pick a different address?

When the OS execs a process, it loads an executable file into a virtual memory space. Along the way, it will resolve any relative and/or symbolic references. Assuming that you have the same executable, and the same shared libraries, and start it the same way that you did the previous time, it would be very strange for the OS to decide to load the executable in a different way.

Upvotes: -3

Related Questions