West Chester University · CSC 472 · Fall 2026

Lab 1: Stack and Stack Frame

Use GDB in WolfCTF to explain how a 32-bit C program builds and uses stack frames.

The assignment

Lab 1 is live on WolfCTF.
Due: Thursday, September 24, 2026, 11:59 PM Eastern Time
Individual work · 5 points · One PDF report submitted to D2L.

Analyze a small 32-bit C program with GDB + GEF (GDB Enhanced Features). GEF is required and preconfigured in the WolfCTF lab environment. Connect the source code to the generated x86 instructions, inspect caller and callee stack frames, and support every answer with evidence from your own session.

Work window: September 11–24. Start by confirming access and collecting evidence; leave time to write, export, and check your report before the deadline.

Read the required report format and D2L submission guide before beginning. This page and the new handout replace the Lab 1 connection instructions and due dates in earlier handouts or slides.

1. Open your workspace

  1. Visit the WolfCTF login page. Sign in using your WolfCTF username and password.
  2. Open Labs → CSC 472 Fall 2026 → Stack and Stack Frame, or use the direct Lab 1 link above.
  3. Click Start Terminal and wait for the browser terminal prompt. Run all Linux and GDB commands in that terminal.

Use the WolfCTF portal guide if you need account or connection help. An SSH client is not required for this lab.

2. Copy and compile

mkdir -p ~/lab1-work
cp -n ~/courses/lab1/lab1.c ~/lab1-work/
cd ~/lab1-work
gcc -m32 -g -O0 -fno-omit-frame-pointer -fno-pie -no-pie -fno-stack-protector lab1.c -o lab1
file lab1
./lab1

cp -n leaves an existing working copy in place. The supplied source is under ~/courses/lab1/; do your work in ~/lab1-work/. The source contains main, multiply_by_two, and the variables p and q.

file lab1 should identify a 32-bit Intel 80386 ELF executable. The program should run and print a result. Stop and resolve build errors before continuing.

FlagWhy it is used here
-m32Use IA-32 registers and the 32-bit calling convention taught in class.
-g -O0Keep debugging information and make the source-to-instruction relationship easier to inspect.
-fno-omit-frame-pointerKeep frame pointers for this frame-inspection exercise.
-fno-pie -no-pieBuild a non-PIE executable. This does not make stack addresses identical across runs.
-fno-stack-protectorKeep this introductory teaching binary free of stack-canary setup. These are lab flags, not production security recommendations.

Need a fresh source file? Download lab1.c. Do not substitute a different lecture example.

3. Collect GDB + GEF evidence

Run gdb -q ./lab1 in the shell. GEF loads automatically; look for the gef➤ prompt. Enter the remaining commands inside GDB. gef help must list GEF commands. Do not use gdb -nx, which skips the startup configuration.

gdb -q ./lab1
gef help
gef config context.layout 'regs code stack'
set disassembly-flavor intel
set pagination off
set logging file gdb-lab1.txt
set logging overwrite off
set logging enabled on
disassemble main
disassemble multiply_by_two

Record the compiler version (gcc --version in the shell), build command, GDB version, GEF startup/version information, and binary architecture in your report. GDB logging appends to gdb-lab1.txt; it saves text output, not screenshots.

At a breakpoint, context displays the register, disassembly, and stack panes together. The layout command above selects those panes. Keep the explicit register and memory commands below to support your interpretation. See the GEF context documentation.

If GEF is missing: quit GDB and launch it normally again. If gef help still reports an undefined command, contact Dr. Chen with the startup output. Save your work; do not delete your workspace to troubleshoot this.

For the before-call snapshot, find the address of call ... <multiply_by_two> in main. Replace 0xYOUR_CALL_ADDRESS below with that address from your own disassembly.

break *0xYOUR_CALL_ADDRESS
run
context
x/i $pc
info registers esp ebp
x/16xw $esp

This is the caller snapshot, before the call executes. To inspect the callee's frame after its prologue, use a function breakpoint and collect a second snapshot:

break multiply_by_two
continue
context
x/i $pc
info frame
info registers esp ebp
x/16xw $esp
bt
finish
info registers
set logging enabled off

Verify where your breakpoint stopped with x/i $pc and the disassembly. If needed, use si to step past the callee's frame-setup instructions before drawing that frame. Label snapshots separately: the current EBP does not refer to the same frame at both stops.

Include a readable GEF context capture at each of the two stops, showing registers, code, and stack. Use selected text excerpts for the detailed dumps. Explain what the panels show; a screenshot alone is not an answer. Your addresses may differ from a class example or another run. Keep your own evidence together.

4. Answer Q1–Q5

Q1 — Constructing the frame

Identify the instructions that construct main's stack frame. Give their addresses and explain the effect on ESP and EBP. Include any stack-alignment or saved-register instructions that occur in your build.

Evidence to include: Relevant disassembly with addresses; a short explanation of each frame-setup instruction.

Q2 — Locating p and q

Find the instructions that initialize p and q. Explain the values written, operand size, and each variable's location relative to EBP.

Evidence to include: The two initialization instructions, their addresses and offsets, and memory or variable inspection from your own run.

Q3 — Explaining two copies of 3 and 4

Stop immediately before the call to multiply_by_two. Explain why copies of the values 3 and 4 appear in more than one place. Distinguish caller locals from the outgoing arguments using addresses and the instructions that placed them there.

Evidence to include: A stack dump at the call site, the current registers and instruction, and an annotated stack diagram. Mark any unproven words as unknown/padding; do not invent a meaning for every value.

Q4 — Reading the arithmetic

Explain what add eax, edx and add eax, eax do in multiply_by_two, and how they implement the C expression. Give a reasoned explanation for the compiler's choice instead of mul/imul.

Evidence to include: The function disassembly and your step-by-step interpretation. If your build differs, show the actual instructions and explain the equivalent computation.

Q5 — Proving the return value

Identify the register that carries the integer return value. Stop inside multiply_by_two, use finish to return to the caller, and verify the result before later instructions can change it.

Evidence to include: GDB's return-value output and the relevant register immediately after return, linked to the C expression and program output.

5. Write and submit

Prepare one PDF named Lastname_Firstname_Lab1.pdf. Include a separate title page, introduction, environment/method, Q1–Q5 analysis, an annotated diagram showing both frames, discussion/conclusion, and references. Aim for 2–4 pages of main content, plus the title page and any necessary appendix.

Total: 5 points. The report rubric follows the earlier course report guide: technical content 50%, organization 15%, presentation 15%, and layout/visuals 20%. The five technical answers are equally weighted within technical content.

Upload the PDF to D2L → CSC 472 → Assignments → Lab 1 by Thursday, September 24, 2026, 11:59 PM Eastern Time. Read the upload and confirmation steps. Working in WolfCTF does not submit a report to D2L.

Work individually. Discussion of tools is fine; your captures, diagram, and explanations must be your own. Cite external and AI assistance and verify explanations against commands you ran. Follow the course syllabus for academic integrity and late-work rules.