/proc/pid/maps
), which means a
local user can easily learn the beginning of each memory segment, which
makes it much easier to defeat address obfuscation. In particular, the
attacker can easily figure out the locations of the code segments, which
makes it possible to craft existing code attacks. This is a limitation of
our current implementation.p_vaddr
,
e.g., this is the case with
libc.so.6 (the Standard C library) on Red Hat Linux
distributions. The lowest loadable segment address specified is
0x42000000. Executables start at virtual address
0x08048000, which leaves a large amount of
space (around 927MB) between the
executable code and the space where shared libraries
are mapped. Typically, every process which uses the dynamically-linked
version of libc.so.6
will have it mapped to the same base address
(0x42000000), which makes the entry points of the libc.so.6
library functions predictable. For example, if we want to know the virtual
address where
function system() is going to be mapped, we can run the following
command:
$ nm /lib/i686/libc.so.6 | grep system 42049e54 T __libc_system 2105930 T svcerr_systemerr 42049e54 W systemThe third line of the output shows the virtual address where
system
is mapped.mmap
.
The dynamic linker uses the mmap
system call to map shared
libraries into memory.
The dynamic linker can be instrumented to instead call a
wrapper function to mmap, which first randomizes the
load address and then calls the original mmap.
The advantage of this method is that in every program
execution, shared libraries will be mapped to different memory addresses.ld
options
-Tbss, -Tdata and -Ttext.
For example, consider a dummy library which is linked by the following
command:
$ ld -o libdummy.so -shared dummy.o -Tdata 0x20000000This causes the load address of the text segment of
libdummy.so
to
be 0x00000000 and the load address of data segment to be
0x20000000, creating a gap of size 0x20000000.
Assuming the text segment is mapped at address 0x40014000
(Note: addresses from 40000000 to 40014000
are used by the dynamic linker itself: /lib/ld-2.2.5.so
),
the data segment will be mapped at address 0x60014000,
thereby offsetting the base address of /lib/i686/libc.so.6.
-fPIC
.
The final executable is created by
introducing a new main function which loads the
shared library generated from the original program (using dlopen)
and invokes the original main
.
This allows random relocation of the original
program's text and data segments.
However, position-independent code is less efficient than its absolute
address-dependent counterpart, introducing a modest amount of extra overhead.
Figure 3: Potential locations of padding inserted between stack frames.
malloc
, and randomly increase the sizes of
dynamic memory allocation requests by 0 to 25%. On some OSes,
including Linux, the heap follows the data segment of the executable. In
this case, randomly relocating the executable causes the heap to also be
randomly relocated.