WCU / Cybersecurity
~/CSC 472/Lab 1
CSC 472 · Lab 1

Stack Frames, GDB, and pwntools

higher addressessaved return addresshijack targetsaved RBPchar buffer[ ]local variablelower addresses (RSP)overflowwrites up
A stack frame: overflowing the buffer overwrites the saved return address.

The goals of this lab:

  • Understand the concepts of the stack and stack frames in compiled C on x86-64.
  • Use GDB (with pwndbg) to disassemble and read a binary and watch the stack at runtime.
  • Set up and get comfortable with the pwntools exploitation toolkit — our workhorse for the rest of the course.

Course platform: all work is done on the Badger CTF Linux server via SSH.

Experiment Setup

  • Log in to Badger CTF: ssh username@badger-host -p port
  • Copy the provided source and build it (mitigations off so the assembly is easy to read): cp /workdir/ss2026/lab1/lab1.c . gcc -g -O0 -no-pie lab1.c -o lab1
  • Confirm your tools are present: gdb (with pwndbg), python3, and pwntools (python3 -c "import pwn"), plus checksec.

Part 1: Read the Assembly with GDB (6 points)

Open the binary and set Intel syntax:

gdb ./lab1 (gdb) set disassembly-flavor intel (gdb) disas main (gdb) disas multiply_by_two
Q1: Identify the instructions that build main's stack frame (the prologue). (1 pt)
Q2: Where are the local variables x and y initialized, and how are they addressed relative to rbp or rsp? (1 pt)
Q3: Before the call to multiply_by_two, how are the two arguments passed? Which registers, and in what order (System V AMD64 convention)? (1 pt)
Q4: Look at how (p+q)*2 is compiled. Does the compiler use imul, or a lea/add/shift sequence? Explain what you see. (1 pt)
Q5: Which register holds the return value, and where is it used back in main? (1 pt)
Q6: Set a breakpoint at the prologue of multiply_by_two, run, and use info registers and x/16xg $rsp to view the stack frame. Identify the saved return address on the stack and explain how you know it is the return address. Include a screenshot. (1 pt)

Part 2: pwntools Warm-up (4 points)

Write a short pwntools script that starts the binary, reads its output, and prints it:

from pwn import *
context.update(arch="amd64", os="linux")
io = process("./lab1")
print(io.recvall(timeout=2).decode())
Q7: Run your script and confirm you see result = 14. Now use pwntools to load the ELF (elf = ELF("./lab1")) and print the address of multiply_by_two (elf.symbols[...]). Paste your script and its output. (2 pts)
Q8: Run checksec ./lab1 and explain what each protection line (RELRO, Stack Canary, NX, PIE) means and whether it is enabled here. (2 pts)

Hint

Review the lecture slides — Class 02: Process Memory, x86-64 Assembly, and the Stack.

Deliverables

A PDF report answering Q1—Q8 with screenshots and your pwntools script.

Submission

  • Check the lab due date on the course website. Late submissions will not be accepted.
  • Submit your assignment to D2L directly.
  • No copy or cheating is tolerated. If your work is based on others' or AI, please give clear attribution. Otherwise, you WILL FAIL this course.