Executable Mapping Lab
Prerequisites and supported environment
Section titled “Prerequisites and supported environment”Finish From Executable to Process, Reading an ELF File, and Virtual Memory and Process Maps first. You’ll want the Ubuntu x86-64 course VM, with file, readelf, sha256sum, and the ordinary /proc tools all available. The only thing needing internet access here is the download itself.
Download executable-mapping-v1.0.0.tar and save it in ~/underdunn-course/downloads.
Expected archive SHA-256:
b34e1eab25c8d7bff3544c84c7fd86f5b9f1968889068f47dc8a7b7e2b8b82daMilestone 1: verify and inventory
Section titled “Milestone 1: verify and inventory”cd ~/underdunn-course/downloadssha256sum executable-mapping-v1.0.0.tarmkdir -p ~/underdunn-course/labs/executable-mappingtar -xf executable-mapping-v1.0.0.tar -C ~/underdunn-course/labs/executable-mappingcd ~/underdunn-course/labs/executable-mapping/executable-mapping-v1.0.0find . -maxdepth 2 -type f -printf '%P\n' | sortStop right there unless the digest matches and mapping-target shows up in that listing. Check both the digest and the inventory before you run the target at all, since that’s your baseline for everything afterward.
Milestone 2: predict the mappings
Section titled “Milestone 2: predict the mappings”Use file, readelf -h, and readelf -lW to establish:
- ELF class, machine, type, and entry point.
- Every
LOADsegment’s offset, virtual address, file size, memory size, flags, and alignment. - Which segment contains executable code.
- Which segment requires more memory than it has file-backed bytes.
Before running the target, compare each LOAD segment’s permissions with what you expect in its live mapping. Keep file offsets, ELF virtual addresses and runtime addresses distinct; a scratch table is optional.
Milestone 3: inspect the live process
Section titled “Milestone 3: inspect the live process”Run the target in the background, where it’ll stay alive for two minutes:
./mapping-target &mapping_pid=$!printf 'PID: %s\n' "$mapping_pid"ps -p "$mapping_pid" -o pid,stat,comm,argsConfirm that PID really does belong to mapping-target, and then compare the live executable mappings with the program headers:
target_path="$(readlink "/proc/$mapping_pid/exe")"grep -F "$target_path" "/proc/$mapping_pid/maps"Calculate one load bias from matching file offsets and page-aligned addresses. Use it to predict a second mapping start, and then compare that prediction with /proc. Explain any page-sized expansion you find, rather than expecting one program-header row to match one mapping row character for character (they usually won’t).
When you’re done, stop only the process you recorded, and then confirm it’s gone:
kill -TERM "$mapping_pid"wait "$mapping_pid"ps -p "$mapping_pid" -o pid,stat,comm,argsThat final ps output should contain nothing but the headings.
Milestone 4: check the count and entry point
Section titled “Milestone 4: check the count and entry point”Count the entries whose program-header type is exactly LOAD. Enter that decimal count and the entry point as readelf -h prints it, including the 0x prefix. Use the supplied executable.
Layered hints
Section titled “Layered hints”Hint 1: choose the loader’s view
Use the program header table rather than the section table, because Linux maps segments.Hint 2: match offsets before addresses
Find aLOAD entry and a live mapping backed by the same file offset, and page-align both sides before you calculate any load bias.Hint 3: count exact type labels
Runreadelf -lW ./mapping-target and count only the rows whose first field is LOAD. Take the entry point from readelf -h, and not from a disassembly address.Common failures
Section titled “Common failures”- The checksum doesn’t match: delete only the downloaded archive, fetch the pinned link again, and verify it before you extract anything.
- The target exits before you can inspect it: confirm you launched
./mapping-target, save$!immediately, and usepsbefore you read/proc. - Your calculated load bias fails on a second row: recheck the file offsets and the page alignment. Don’t match rows by permission alone.
grepfinds nothing at all: confirm the PID still exists, and use the exact path from/proc/PID/exe. Don’t assume the extracted relative path is how/procprints it.
Check your result
Section titled “Check your result”The checker should accept the LOAD count and entry point. Use your calculated
load bias to check a second executable-backed mapping. If it differs, compare
file offsets and page alignment. Stop the background process and confirm it is gone.
Reset and cleanup
Section titled “Reset and cleanup”Confirm the recorded PID isn’t running any more before you reset anything. Then restore a fresh working copy:
cd ~/underdunn-course/labs/executable-mappingrm -rf -- executable-mapping-v1.0.0tar -xf ~/underdunn-course/downloads/executable-mapping-v1.0.0.tar -C .For final cleanup, run only the first two lines, and keep the verified archive and any working files you want.