# Makefile  --  CYBR 358 Buffer Overflow build recipes.
#
# Each target is an INDEPENDENT build from the same source, so a mitigation is
# tested in isolation and never stacked on top of another. The baseline is the
# binary you exploit. NX (a non-executable stack) is ON even in the baseline:
# ret2win does not run code on the stack, so NX does not stop it, and that is
# one of the lessons.
#
# -fcf-protection=none keeps CET / shadow-stack out of the picture so the
# experiment is about the four classic defenses, not a fifth one.

CC     ?= gcc
COMMON  = -g -fcf-protection=none -Wall
NX      = -Wl,-z,noexecstack

.PHONY: all clean
all: bof_baseline bof_canary bof_pie bof_fortify_off bof_fortify_on bof_fixed

# 1) BASELINE: non-PIE, no canary, NX on. This is the graded ret2win target.
bof_baseline: vuln.c win_stub.S
	$(CC) $(COMMON) -O0 -fno-stack-protector -no-pie $(NX) -o $@ vuln.c win_stub.S

# 2) CANARY branch: baseline + stack protector. The overflow is caught at return.
bof_canary: vuln.c win_stub.S
	$(CC) $(COMMON) -O0 -fstack-protector-strong -no-pie $(NX) -o $@ vuln.c win_stub.S

# 3) PIE branch: position-independent + system ASLR. The fixed win() address moves.
bof_pie: vuln.c win_stub.S
	$(CC) $(COMMON) -O0 -fno-stack-protector -fpie -pie $(NX) -o $@ vuln.c win_stub.S

# 4) FORTIFY control pair, both at -O2 so ONLY _FORTIFY_SOURCE differs between them.
#    read() into a fixed-size buffer is fortified by glibc, so the ON build aborts.
bof_fortify_off: vuln.c win_stub.S
	$(CC) $(COMMON) -O2 -U_FORTIFY_SOURCE -fno-stack-protector -no-pie $(NX) -o $@ vuln.c win_stub.S
bof_fortify_on: vuln.c win_stub.S
	$(CC) $(COMMON) -O2 -D_FORTIFY_SOURCE=2 -fno-stack-protector -no-pie $(NX) -o $@ vuln.c win_stub.S

# 5) The safe-fix reference. Bounded read; no win() target needed.
bof_fixed: vuln_fixed.c
	$(CC) $(COMMON) -O0 -fno-stack-protector -no-pie $(NX) -o $@ vuln_fixed.c

clean:
	rm -f bof_baseline bof_canary bof_pie bof_fortify_off bof_fortify_on bof_fixed
