# CSC 472 - Class 16: StackGuard (canary) + Format String Bug
#
# Two targets, two lessons:
#
#   easy_canary  -- the canary is ON (-fstack-protector-all). The point is that
#                   a forking server shares ONE canary across children, so it
#                   can be brute-forced byte by byte. 32-bit so the stack
#                   diagrams and the 4-byte canary match the slides.
#
#   fmt_wrong    -- printf(user_input): a format-string bug. No %n needed to do
#   fmt_write       damage. fmt_wrong LEAKS the stack (%x / %s); fmt_write uses
#                   %n to WRITE an attacker-chosen value to an attacker-chosen
#                   address (changes `token` 0xdeadbeef -> 0xcafebabe).
#
# The format-string targets are built with the canary OFF and no PIE so the
# stack walk and the token address in the slides are reproducible.

CC = gcc
M  = -m32 -g -Wno-deprecated-declarations

all: easy_canary fmt_wrong fmt_write

# --- canary ON (that is the lesson) -----------------------------------------
easy_canary: src/easy_canary.c
	$(CC) $(M) -fstack-protector-all -no-pie -o $@ $<
	@echo "[built] easy_canary  (canary ON; forking server on 127.0.0.1:4444)"

# --- format-string targets: canary OFF, no PIE, fixed addresses -------------
fmt_wrong: src/fmt_wrong.c
	$(CC) $(M) -fno-stack-protector -no-pie -o $@ $<
	@echo "[built] fmt_wrong    (printf(user) -> stack leak)"

fmt_write: src/fmt_write.c
	$(CC) $(M) -fno-stack-protector -no-pie -o $@ $<
	@echo "[built] fmt_write    (printf(user) -> %n arbitrary write)"

# Prove the canary is really in easy_canary and really absent in the fmt bins.
checkcanary: all
	@for b in easy_canary fmt_wrong fmt_write; do \
	  printf '%-12s ' $$b; \
	  if readelf -s $$b | grep -q __stack_chk_fail; then echo "canary: ON"; \
	  else echo "canary: OFF"; fi; \
	done

# Address of the token fmt_write flips (fixed, no-PIE).
token: fmt_write
	@echo "--- &token (give this to %n in fmt_write.py) ---"
	@nm fmt_write | grep -E ' token$$'

clean:
	rm -f easy_canary fmt_wrong fmt_write

.PHONY: all checkcanary token clean
