Virtual Memory and Process Maps
An address belongs to a process
Section titled “An address belongs to a process”When a running program uses an address such as 0x7ffd12340000, that number identifies a location in the process’s virtual address space. It is not a raw label printed on a particular RAM chip.
Linux and the processor translate virtual addresses to physical memory as needed. This gives each process a private, orderly view even while the machine shares physical memory among many processes. It also lets Linux enforce permissions and leave invalid gaps that catch bad accesses.
The useful beginner model is a private street map. The addresses are locations on one process’s map. Linux decides what, if anything, each range maps to and whether it may be read, written, or executed. Two processes may show the same virtual address while referring to separate state.
Create a process long enough to inspect
Section titled “Create a process long enough to inspect”sleep 300 &sleep_pid=$!printf 'PID: %s\n' "$sleep_pid"Display its mappings:
cat "/proc/$sleep_pid/maps"Each line describes a range. A typical line resembles:
55a1c0000000-55a1c0009000 r-xp 00002000 08:02 12345 /usr/bin/sleepExact addresses will differ. Read the fields as evidence:
| Field | Meaning |
|---|---|
start-end |
Half-open virtual-address range: start included, end excluded |
rwx |
Read, write, and execute permissions; - means absent |
p or s |
Private or shared mapping |
| file offset | Where the mapped bytes begin in the backing file |
| device and inode | Filesystem identity of a backing file |
| path | Backing file or a kernel label such as [stack] |
Subtract the start from the end to get the mapping size. The values are hexadecimal, so use Python when the arithmetic is not pleasant:
python3 -c 'print(hex(0x2000 - 0x1000), 0x2000 - 0x1000)'Knowledge check
Question 1 of 2
Knowledge check complete
You answered all 2 questions correctly.
Connect the live map to the ELF file
Section titled “Connect the live map to the ELF file”Show only mappings backed by the executable:
grep "$(readlink "/proc/$sleep_pid/exe")" "/proc/$sleep_pid/maps"Compare their file offsets and permissions with the LOAD segments from the previous lesson:
readelf -lW "$(readlink "/proc/$sleep_pid/exe")"The numbers may not appear identical at first glance. Program headers describe ELF loading requirements; /proc/PID/maps describes page-aligned live mappings. Alignment and PIE relocation affect the displayed addresses. The relationship is evidence to work out, not a promise of matching rows.
Other file-backed mappings usually belong to the dynamic loader and shared libraries. Lines without a normal pathname may represent anonymous memory created at runtime. Kernel labels such as [heap], [stack], [vvar], and [vdso] identify special roles.
Observe randomization
Section titled “Observe randomization”Start a second process:
sleep 300 &second_pid=$!grep '/sleep$' "/proc/$sleep_pid/maps"grep '/sleep$' "/proc/$second_pid/maps"With address-space layout randomization enabled, the executable mappings of a PIE binary will normally begin at different virtual addresses. The relative layout inside each loaded image remains meaningful even when the base changes.
This is why vulnerability research often speaks in offsets from a module base instead of assuming one absolute address works forever.
Clean up:
kill "$sleep_pid" "$second_pid"wait "$sleep_pid" "$second_pid"What this gives us as researchers
Section titled “What this gives us as researchers”You can now read a live address-space map, explain its permissions, and connect file-backed regions to ELF loading metadata. The first lab will ask you to reconstruct that relationship for a supplied executable.