diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e83f0ef..6cb4227 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,23 +1,18 @@ -name: Build +name: Build and Test on: [push, pull_request] jobs: - compile: + verify: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4 - - name: Install GCC + - name: Install build tools run: | sudo apt-get update - sudo apt-get install -y gcc + sudo apt-get install -y gcc make - - name: Compile all lab programs - run: | - gcc -Wall -Wextra -Werror src/vuln_buffer_overflow.c -o vuln_buffer_overflow - gcc -Wall -Wextra -Werror src/safe_input_demo.c -o safe_input_demo - gcc -Wall -Wextra -Werror src/stack_layout_demo.c -o stack_layout_demo - gcc -Wall -Wextra -Werror src/overflow_behavior_demo.c -o overflow_behavior_demo - gcc -Wall -Wextra -Werror src/control_flow_simulation.c -o control_flow_simulation + - name: Run project verification + run: make check diff --git a/Makefile b/Makefile index 87fb4dd..36f443e 100644 --- a/Makefile +++ b/Makefile @@ -2,19 +2,38 @@ CC = gcc CFLAGS = -Wall -Wextra -g -O0 VERIFY_CFLAGS = -Wall -Wextra -Werror SRC_DIR = src +TEST_DIR = tests PROGRAMS = vuln_buffer_overflow safe_input_demo stack_layout_demo overflow_behavior_demo control_flow_simulation +TEST_PROGRAM = demo_runtime_checks +TEST_SOURCES = $(TEST_DIR)/$(TEST_PROGRAM).c $(addprefix $(SRC_DIR)/,$(addsuffix .c,$(PROGRAMS))) -.PHONY: all verify clean +ifeq ($(OS),Windows_NT) +RUN_TEST = .\$(TEST_PROGRAM).exe +CLEAN_CMD = powershell -NoProfile -Command "$(foreach file,$(PROGRAMS) $(addsuffix .exe,$(PROGRAMS)) $(TEST_PROGRAM) $(TEST_PROGRAM).exe,Remove-Item -ErrorAction SilentlyContinue '$(file)';) exit 0" +else +RUN_TEST = ./$(TEST_PROGRAM) +CLEAN_CMD = rm -f $(PROGRAMS) $(addsuffix .exe,$(PROGRAMS)) $(TEST_PROGRAM) $(TEST_PROGRAM).exe +endif + +.PHONY: all verify test check clean all: $(PROGRAMS) -$(PROGRAMS): %: $(SRC_DIR)/%.c +$(PROGRAMS): %: $(SRC_DIR)/%.c $(SRC_DIR)/demo_programs.h $(CC) $(CFLAGS) -o $@ $< -verify: $(addprefix verify-,$(PROGRAMS)) +verify: $(addprefix verify-,$(PROGRAMS)) verify-tests -verify-%: $(SRC_DIR)/%.c +verify-%: $(SRC_DIR)/%.c $(SRC_DIR)/demo_programs.h $(CC) $(VERIFY_CFLAGS) -o $* $< +verify-tests: $(TEST_SOURCES) $(SRC_DIR)/demo_programs.h + $(CC) $(VERIFY_CFLAGS) -DDEMO_NO_MAIN -I$(SRC_DIR) -o $(TEST_PROGRAM) $(TEST_SOURCES) + +test: verify-tests + $(RUN_TEST) + +check: verify test + clean: - -$(RM) $(PROGRAMS) $(addsuffix .exe,$(PROGRAMS)) + -$(CLEAN_CMD) diff --git a/README.md b/README.md index 4d78502..a4d4d9c 100644 --- a/README.md +++ b/README.md @@ -1,114 +1,152 @@ -# Exploit Lab +# Exploit Lab (C Memory Safety Demos) -Hands-on C demos for observing unsafe input, stack layout, overflow behavior, and control-flow concepts in a controlled, educational environment. +A beginner-friendly C lab for observing unsafe input, safer input handling, stack layout, deterministic overflow side effects, and conceptual control-flow changes. ## Overview -This repository is a memory-safety learning lab built around small, focused C programs. It exists to show how unsafe input handling behaves, how stack memory is laid out at runtime, how undefined behavior can appear after an out-of-bounds write, and how function-pointer reassignment changes execution flow in a safe, explicit way. +This project is built for learning, not exploitation. Each demo is small enough to read quickly and focused enough to show one memory-safety idea at a time. -The project is relevant to application security, systems programming, and debugging workflows. It is designed to help developers and learners understand why bounded input, runtime inspection, and defensive coding practices matter in real programs. +Core demos: -## Features +- `vuln_buffer_overflow`: shows why `scanf("%s", ...)` is dangerous with fixed-size buffers. +- `safe_input_demo`: contrasts that behavior with bounded input using `fgets(...)`. +- `stack_layout_demo`: prints local and parameter addresses so you can inspect stack-frame layout. +- `overflow_behavior_demo`: safely simulates how an unbounded copy can spill past a buffer into adjacent bytes. +- `control_flow_simulation`: demonstrates how changing a function pointer changes executed code. -- Demonstrates unsafe input handling with `scanf("%s", ...)` in a small stack-buffer example. -- Demonstrates safe input handling with `fgets(...)` and newline cleanup. -- Prints stack-frame addresses for local variables and function parameters. -- Shows overflow-related instability in a controlled demo that warns when input exceeds the buffer capacity. -- Simulates control-flow redirection with a function pointer reassignment. -- Includes GDB-oriented walkthroughs for inspecting locals, registers, and stack state. -- Documents runtime protections such as ASLR, NX, and stack canaries at a conceptual level. -- Provides captured screenshots and notes for the demos in `docs/images/`. -- Includes a GitHub Actions workflow that compiles all active demos on push and pull request. +## What Improved -## Tech Stack +The project now behaves like a real teaching lab instead of a compile-only collection of demos: -- Language: C -- Compiler: GCC -- Debugger: GDB -- Build tool: Make -- CI: GitHub Actions -- Target platforms: Linux and Windows with MinGW-compatible builds +- The overflow demo is deterministic and no longer relies on real undefined behavior just to explain overwrite effects. +- Each demo exposes a reusable `run_*` entry point through [`src/demo_programs.h`](/d:/GitHub%20Repo/exploit-lab-cpp/src/demo_programs.h:1), which makes the demos testable without changing their CLI behavior. +- A runtime smoke-test harness in [`tests/demo_runtime_checks.c`](/d:/GitHub%20Repo/exploit-lab-cpp/tests/demo_runtime_checks.c:1) validates the expected output of every stable demo. +- The Makefile now supports `make check`, and CI uses the same project-owned verification path instead of duplicating compile commands by hand. ## Project Structure -- `src/` -> active lab programs that build into the five demo binaries - - `vuln_buffer_overflow.c` -> unsafe input demo using `scanf("%s", ...)` - - `safe_input_demo.c` -> bounded input demo using `fgets(...)` - - `stack_layout_demo.c` -> prints stack addresses for local values and a parameter - - `overflow_behavior_demo.c` -> shows undefined behavior risk after oversized input - - `control_flow_simulation.c` -> safe function-pointer reassignment demo -- `docs/` -> guided learning material and reference notes - - `demo.md` -> quick walkthrough and sample outputs - - `gdb-guide.md` -> debugging workflow for the active binaries - - `lab-exercises.md` -> step-by-step beginner exercises - - `memory-layout.md` -> stack and buffer basics - - `protections.md` -> ASLR, NX, and stack canaries overview - - `advanced-concepts.md` -> conceptual theory only - - `images/` -> screenshots and supporting visual assets -- `archive/` -> deprecated placeholder files retained for compatibility - - `main.c` -> inactive placeholder - - `stack_behavior_demo.c` -> inactive placeholder -- `.github/workflows/` -> CI workflow that compiles the demo programs -- `Makefile` -> build, verify, and clean targets -- `README.md` -> project overview and setup guide - -## Setup & Installation - -Clone the repository: +```text +exploit-lab-cpp/ +|- src/ +| |- demo_programs.h +| |- vuln_buffer_overflow.c +| |- safe_input_demo.c +| |- stack_layout_demo.c +| |- overflow_behavior_demo.c +| |- control_flow_simulation.c +|- tests/ +| |- demo_runtime_checks.c +|- docs/ +| |- demo.md +| |- gdb-guide.md +| |- lab-exercises.md +| |- memory-layout.md +| |- protections.md +| |- advanced-concepts.md +|- archive/ +|- .github/workflows/ +|- Makefile +|- project.md +|- README.md +``` + +## Build + +Prerequisites: + +- GCC +- Make or `mingw32-make` +- Optional: GDB + +Linux/macOS: ```bash -git clone https://github.com/urvalkheni/exploit-lab-cpp.git -cd exploit-lab-cpp +make ``` -Install the required tools: +Windows (MinGW): -- Linux: `gcc`, `make`, and optionally `gdb` -- Windows: MinGW or another GCC-compatible toolchain, plus `make` +```powershell +mingw32-make +``` + +## Verify -Build all demos: +Strict compile verification: ```bash -make +make verify ``` -Run a demo: +End-to-end compile plus runtime verification: ```bash -./safe_input_demo +make check ``` Windows (MinGW): ```powershell -.\safe_input_demo.exe +mingw32-make check ``` -If you want to verify compilation without using the default build target, run: +## Run The Demos + +Linux/macOS: ```bash -make verify +./vuln_buffer_overflow +./safe_input_demo +./stack_layout_demo +./overflow_behavior_demo +./control_flow_simulation +``` + +Windows: + +```powershell +.\vuln_buffer_overflow.exe +.\safe_input_demo.exe +.\stack_layout_demo.exe +.\overflow_behavior_demo.exe +.\control_flow_simulation.exe ``` -## Available Demos +## Example Output + +`overflow_behavior_demo` + +```text +[overflow_behavior_demo] Deterministic overflow impact demo +Value of x before input: 10 +Enter input: AAAAAAAAAAAAAAAAAAAAAA +Input length: 22 +WARNING: Input length (22) exceeds buffer capacity (15). +Simulated bytes written past buffer: 4 +Bytes that reached adjacent int: 4 of 4 +Adjacent int bytes after simulation: 41 41 41 41 +Value of x after simulated copy: 1094795585 +Buffer preview: AAAAAAAAAAAAAAAA +``` + +`control_flow_simulation` -- `vuln_buffer_overflow` -> unsafe input behavior demonstration -- `safe_input_demo` -> bounded input demonstration -- `stack_layout_demo` -> runtime stack address observation -- `overflow_behavior_demo` -> overflow effect observation with a warning -- `control_flow_simulation` -> conceptual control-flow redirection via a function pointer +```text +[control_flow_simulation] Conceptual control-flow demo +Calling through function pointer (before change): +safe_function(): normal control flow path. -## Helpful Docs +Simulating conceptual pointer corruption by manual reassignment... +Calling through function pointer (after change): +target_function(): alternate control flow path. +``` -- [Demo guide](docs/demo.md) -- [Lab exercises](docs/lab-exercises.md) -- [GDB guide](docs/gdb-guide.md) -- [Memory layout basics](docs/memory-layout.md) -- [Runtime protections](docs/protections.md) -- [Advanced concepts](docs/advanced-concepts.md) +## Why This Matters -## Safety and Scope +- You can compare unsafe and safe input paths directly. +- You can study memory layout concepts without needing exploit code. +- You can reproduce the same learning signals in CI and on contributor machines. -This project is educational and defensive in scope. It does not include exploit payloads or a real exploitation walkthrough. The focus is on understanding memory behavior, debugging, and safer programming patterns. +## Disclaimer -Do not run these experiments on systems you do not own or have explicit permission to analyze. +This repository is for educational and defensive learning only. diff --git a/docs/demo.md b/docs/demo.md index db815c3..583ac61 100644 --- a/docs/demo.md +++ b/docs/demo.md @@ -1,150 +1,109 @@ # Demo Guide -This is a quick, clean walkthrough for running the core memory lab demos. +This guide walks through the core lab demos and the new verification flow. -## 1) Setup +## 1. Build Everything -Compile all core programs: +Linux/macOS: ```bash make ``` -Windows (MinGW) note: -- Use `.\\program.exe` instead of `./program`. +Windows (MinGW): -## 2) Run Each Core Lab - -### Lab 1: Unsafe Input Behavior +```powershell +mingw32-make +``` -Run: +If you want the full quality gate, run: ```bash -./vuln_buffer_overflow +make check ``` -Example output: +Windows: -```text -[vuln_buffer_overflow] Unsafe input demo -Enter a word: AAAAAAAAAAAAAAAAAAAAA -You entered: AAAAAAAAAAAAAAAAAAAAA +```powershell +mingw32-make check ``` -What you will see: -- Input is accepted without explicit length limits. -- Long input can produce unstable behavior in unsafe programs. +## 2. Run Each Demo -### Lab 2: Safe Input Demo - -Run: +### Lab 1: Unsafe Input Behavior ```bash -./safe_input_demo +./vuln_buffer_overflow ``` -Example output: +What to look for: -```text -[safe_input_demo] Safe input demo -Enter text: hello -You entered safely: hello +- The program accepts a word without a width limit. +- Short input is fine. +- Long input is dangerous because the read itself is unbounded. + +### Lab 2: Safe Input Demo + +```bash +./safe_input_demo ``` -What you will see: -- `fgets(...)` reads with a size boundary. -- Behavior is safer and more predictable. +What to look for: -### Lab 3: Stack Layout Demo +- `fgets(...)` respects the buffer size. +- The output stays predictable with normal input. -Run: +### Lab 3: Stack Layout Demo ```bash ./stack_layout_demo ``` -Example output: +What to look for: -```text -[stack_layout_demo] Stack address observation -Address of main_local: 0x7ff... -Address of buffer: 0x7ff... -Address of x: 0x7ff... -Address of parameter demo_id: 0x7ff... -``` - -What you will see: -- Local addresses are often close together. -- Absolute addresses may change between runs. +- `main_local`, `buffer`, `x`, and `demo_id` all print nearby addresses. +- The absolute addresses may change between runs. ### Lab 4: Overflow Behavior Demo -Run: - ```bash ./overflow_behavior_demo ``` -Example output: +Example long-input output: ```text -[overflow_behavior_demo] Observe behavior with long input +[overflow_behavior_demo] Deterministic overflow impact demo Value of x before input: 10 -Enter input: WARNING: Input length (30) exceeds buffer capacity (15). -Behavior may be unstable (undefined behavior). -Value of x after input: 1094795585 -Buffer content: AAAAAAAAAAAAAAAA... +Enter input: AAAAAAAAAAAAAAAAAAAAAA +Input length: 22 +WARNING: Input length (22) exceeds buffer capacity (15). +Simulated bytes written past buffer: 4 +Bytes that reached adjacent int: 4 of 4 +Adjacent int bytes after simulation: 41 41 41 41 +Value of x after simulated copy: 1094795585 +Buffer preview: AAAAAAAAAAAAAAAA ``` -Clean beginner-friendly version: +What to look for: -```text -User types: AAAAAAAAAAAAAAAA -Output: -Value of x before input: 10 -WARNING: Input exceeds buffer size -Value of x after input: 1094795585 -``` - -What you will see: -- Warning for oversized input. -- Possible unstable values because overflow is undefined behavior. +- The input is read safely first. +- The demo then simulates how an unbounded copy would move across adjacent bytes. +- You get a repeatable view of what reaches the neighboring `int` without depending on real undefined behavior. ### Lab 5: Control Flow Simulation -Run: - ```bash ./control_flow_simulation ``` -Example output: - -```text -[control_flow_simulation] Conceptual control-flow demo -Address of safe_function: 00401460 -Address of target_function: 00401475 -Address of func_ptr var: 0061FF1C - -Calling through function pointer (before change): -safe_function(): normal control flow path. - -Simulating conceptual pointer corruption by manual reassignment... -Calling through function pointer (after change): -target_function(): alternate control flow path. -``` - -What you will see: -- Changing function pointer target changes executed function. -- This is a controlled simulation, not real memory corruption. +What to look for: -Visual proof: -- `docs/images/overflow-output.png` -- `docs/images/control-flow.png` +- The function pointer calls `safe_function()` first. +- After reassignment, the same pointer calls `target_function()`. +- The program demonstrates control-flow redirection conceptually, not through real corruption. -### Lab 6: Debugging with GDB (Optional but Recommended) - -Start with `stack_layout_demo`: +### Lab 6: GDB Walkthrough ```bash gdb ./stack_layout_demo @@ -161,31 +120,10 @@ info locals info registers ``` -What you will see: -- Line-by-line execution state. -- Variable and register values during runtime. - -Visual proof: -- `docs/images/gdb-session.png` - -## 3) What This Teaches - -- Why unbounded input is risky. -- How bounded input reduces risk. -- How stack variables are arranged in memory. -- Why undefined behavior is dangerous. -- How control flow concepts can be taught safely. - -## 4) Screenshot Evidence - -### GDB Session - -![GDB session](images/gdb-session.png) - -### Overflow Output - -![Overflow output](images/overflow-output.png) - -### Control Flow Simulation +## 3. What This Teaches -![Control flow simulation](images/control-flow.png) +- Why unbounded input is risky +- Why bounded input is safer +- How stack-frame data can be inspected +- How overflow side effects can be explained safely and deterministically +- How control-flow changes can be demonstrated without exploit code diff --git a/docs/lab-exercises.md b/docs/lab-exercises.md index b0a735d..4d3af44 100644 --- a/docs/lab-exercises.md +++ b/docs/lab-exercises.md @@ -1,15 +1,9 @@ -# Lab Exercises (Beginner-Friendly) +# Lab Exercises -These exercises help you practice memory-safety concepts step by step. -Each lab includes: -- what to run -- what to observe -- what it means +These exercises are designed to be repeatable on contributor machines and in CI. ## Lab 1: Unsafe Input Behavior -### What to run - Build: ```bash @@ -18,59 +12,40 @@ make vuln_buffer_overflow Run: -Linux/macOS: - ```bash ./vuln_buffer_overflow ``` -Windows (MinGW): +Observe: -```powershell -.\vuln_buffer_overflow.exe -``` +- Normal input works as expected. +- The code path is still unsafe because `scanf("%s", ...)` does not limit length. -Try entering a long input string. +Meaning: -### What to observe - -- Program behavior with normal input vs long input -- Whether output becomes unstable or unexpected - -### What it means - -`scanf("%s", ...)` does not limit input length. -If input is longer than the buffer, memory outside the buffer may be overwritten (undefined behavior). +- Even simple code can become dangerous when input size is not bounded. ## Lab 2: Safe vs Unsafe Comparison -### What to run - -Build both: +Build: ```bash make safe_input_demo vuln_buffer_overflow ``` -Run each program and enter similar inputs: - -- short input (for example: `hello`) -- long input (for example: many `A` characters) +Run both programs with short input such as `hello`. -### What to observe +Observe: -- `safe_input_demo` remains stable because input is bounded -- `vuln_buffer_overflow` may behave unpredictably with long input +- Both programs handle short input. +- Only `safe_input_demo` enforces a read boundary. -### What it means +Meaning: -Bounded input functions like `fgets(...)` reduce overflow risk. -Unbounded input patterns are dangerous in C. +- Safe input handling is mostly about preventing the dangerous read in the first place. ## Lab 3: Stack Memory Layout -### What to run - Build: ```bash @@ -79,32 +54,21 @@ make stack_layout_demo Run: -Linux/macOS: - ```bash ./stack_layout_demo ``` -Windows (MinGW): - -```powershell -.\stack_layout_demo.exe -``` - -### What to observe +Observe: -- Printed addresses for local variables and function parameters -- Addresses are often close together -- Re-running may change absolute addresses +- Printed addresses for locals and a parameter +- Similar relative ordering across runs +- Different absolute addresses on some systems -### What it means +Meaning: -Local variables are typically placed in the current stack frame. -Relative ordering is often similar, while exact addresses can change between runs (for example, due to ASLR). +- Stack memory is structured, but exact addresses are environment-dependent. -## Lab 4: Overflow Behavior - -### What to run +## Lab 4: Deterministic Overflow Impact Build: @@ -112,35 +76,25 @@ Build: make overflow_behavior_demo ``` -Run and enter a long string: - -Linux/macOS: +Run with a long string: ```bash ./overflow_behavior_demo ``` -Windows (MinGW): +Observe: -```powershell -.\overflow_behavior_demo.exe -``` +- Input length and buffer capacity +- How many bytes spill past the buffer +- How many bytes reach the adjacent `int` +- The hex view of the neighboring bytes after the simulated copy -### What to observe +Meaning: -- Value of variable `x` before and after input -- Warning message for oversized input -- Possible instability depending on run/environment - -### What it means - -When input exceeds buffer size, nearby memory may be affected. -This is undefined behavior, so outcomes are not guaranteed. +- You can study overwrite direction and side effects without relying on a real overflow to corrupt process memory. ## Lab 5: Control Flow Simulation -### What to run - Build: ```bash @@ -149,58 +103,37 @@ make control_flow_simulation Run: -Linux/macOS: - ```bash ./control_flow_simulation ``` -Windows (MinGW): - -```powershell -.\control_flow_simulation.exe -``` - -### What to observe +Observe: -- Function pointer calls `safe_function()` first -- After reassignment, the same pointer calls `target_function()` -- Printed function addresses and pointer variable address +- The same function pointer calls different functions before and after reassignment. -### What it means +Meaning: -Control flow depends on which code address is used. -This lab safely demonstrates redirection conceptually through normal reassignment, not memory corruption. +- Control flow follows the currently stored code address. -## Lab 6: Debugging with GDB +## Lab 6: Runtime Verification -### What to run - -Use GDB on any demo program (example: `stack_layout_demo`): +Run: ```bash -gdb ./stack_layout_demo +make check ``` -Useful commands inside GDB: +Windows (MinGW): -```gdb -break main -run -next -step -info locals -print x -info registers +```powershell +mingw32-make check ``` -### What to observe +Observe: -- Program state line by line -- Current variable values -- Register changes during execution +- Every stable demo is compiled with strict warnings enabled. +- The smoke-test harness validates key output markers from each demo. -### What it means +Meaning: -GDB helps you see how C code maps to runtime behavior. -This is essential for understanding memory layout, variable lifetimes, and debugging unsafe behavior. +- The lab is now regression-tested, not just buildable. diff --git a/project.md b/project.md index cd6ca37..d61b650 100644 --- a/project.md +++ b/project.md @@ -1,223 +1,30 @@ -# ๐Ÿ’ฃ Exploit Lab (C/C++) - -A hands-on, low-level security lab designed to demonstrate classic memory corruption vulnerabilities and exploitation techniques such as buffer overflows, stack smashing, and basic shellcode execution. - -This project focuses on understanding how vulnerabilities arise in unsafe programs and how attackers can exploit them at the memory level. - ---- - -## ๐Ÿ“Œ Overview - -Modern systems implement several protections (ASLR, NX, stack canaries), but many real-world vulnerabilities still stem from unsafe memory handling. - -This lab recreates vulnerable environments to: - -* Understand how memory is structured (stack, heap) -* Learn how overflows overwrite control flow -* Observe exploitation using debugging tools - ---- - -## ๐Ÿš€ Features - -* ๐Ÿง  Stack-based buffer overflow demonstrations -* ๐Ÿ’ฅ Return address overwrite (stack smashing) -* ๐Ÿš Basic shellcode execution (controlled environment) -* ๐Ÿ” Step-by-step debugging using GDB -* ๐Ÿ“Š Memory visualization (stack layout, registers) - ---- - -## ๐Ÿ›  Tech Stack - -* **Language:** C / C++ -* **Compiler:** GCC -* **Debugger:** GDB -* **OS:** Linux (recommended: Kali / Ubuntu) - ---- - -## ๐Ÿ“‚ Project Structure - -exploit-lab-cpp/ -โ”‚โ”€โ”€ src/ -โ”‚ โ”œโ”€โ”€ vuln_buffer_overflow.c -โ”‚ โ”œโ”€โ”€ stack_smash.c -โ”‚ โ”œโ”€โ”€ shellcode_demo.c -โ”‚ -โ”‚โ”€โ”€ exploits/ -โ”‚ โ”œโ”€โ”€ exploit_buffer.py -โ”‚ โ”œโ”€โ”€ exploit_stack.py -โ”‚ -โ”‚โ”€โ”€ docs/ -โ”‚ โ”œโ”€โ”€ memory-layout.md -โ”‚ โ”œโ”€โ”€ gdb-guide.md -โ”‚ -โ”‚โ”€โ”€ screenshots/ -โ”‚ โ”œโ”€โ”€ gdb-analysis.png -โ”‚ โ”œโ”€โ”€ exploit-success.png -โ”‚ -โ”‚โ”€โ”€ README.md - ---- - -## ๐Ÿ” Core Concepts Covered - -### 1. Buffer Overflow - -Occurs when input exceeds allocated buffer size. - -```c -char buffer[16]; -gets(buffer); // unsafe -``` - -๐Ÿ’ฅ Result: - -* Overwrites adjacent memory -* Can modify return address - ---- - -### 2. Stack Smashing - -Manipulating stack memory to control program execution. - -* Overwrite saved return pointer (EIP/RIP) -* Redirect execution flow - ---- - -### 3. Shellcode Injection - -Injecting and executing malicious instructions in memory. - -Example: - -* Spawn a shell -* Execute arbitrary commands - ---- - -## ๐Ÿงช Lab Exercises - -### ๐Ÿ”น Lab 1: Basic Buffer Overflow - -* Identify vulnerable input -* Overflow buffer -* Crash program - ---- - -### ๐Ÿ”น Lab 2: Control Instruction Pointer - -* Use GDB to locate offset -* Overwrite return address -* Redirect execution - ---- - -### ๐Ÿ”น Lab 3: Shellcode Execution - -* Inject shellcode into memory -* Execute payload -* Observe behavior - ---- - -## ๐Ÿงช Compilation & Execution - -โš ๏ธ Disable protections for learning purposes: - -```bash -gcc vuln_buffer_overflow.c -o vuln -fno-stack-protector -z execstack -no-pie -``` - -Run: - -```bash -./vuln -``` - ---- - -## ๐Ÿž Debugging with GDB - -Start debugging: - -```bash -gdb ./vuln -``` - -Useful commands: - -```bash -run -info registers -x/20x $rsp -disassemble main -``` - ---- - -## ๐Ÿ“Š Example Workflow - -1. Run program with long input -2. Observe crash -3. Open in GDB -4. Identify offset -5. Overwrite return address -6. Redirect execution - ---- - -## ๐Ÿ” Security Mitigations (Important) - -This lab disables protections intentionally. In real systems: - -* โœ… Stack Canaries prevent overflow detection bypass -* โœ… ASLR randomizes memory addresses -* โœ… NX bit prevents execution on stack -* โœ… Safe functions (`fgets`, `gets_s`) replace unsafe ones - ---- - -## โš ๏ธ Disclaimer - -This project is strictly for **educational purposes only**. - -Do NOT use these techniques on systems you do not own or have permission to test. - ---- - -## ๐ŸŽฏ Learning Outcomes - -After completing this lab, you will: - -* Understand stack memory structure -* Identify unsafe code patterns -* Perform basic exploitation -* Use debugging tools effectively -* Understand real-world mitigation techniques - ---- - -## ๐Ÿš€ Future Improvements - -* Heap exploitation examples -* Format string vulnerabilities -* Return-Oriented Programming (ROP) -* Automated exploit scripts - ---- - -## ๐Ÿค Contributing - -Contributions are welcome! -Feel free to open issues or submit pull requests. - ---- - -## โญ Acknowledgment - -Inspired by real-world exploitation techniques and classic vulnerability research. +# Project Overview + +Exploit Lab is a small C teaching repo focused on memory-safety fundamentals. + +## Current Direction + +The project is intentionally educational and defensive: + +- compare unsafe and safe input handling +- inspect stack layout and nearby addresses +- explain overflow side effects without depending on real undefined behavior +- illustrate conceptual control-flow changes safely + +## Quality Bar + +The repo now has three layers of verification: + +- `make` builds all demos +- `make verify` recompiles with `-Werror` +- `make check` runs compile and runtime smoke tests + +## Key Implementation Notes + +- Shared demo entry points live in [`src/demo_programs.h`](/d:/GitHub%20Repo/exploit-lab-cpp/src/demo_programs.h:1). +- Runtime checks live in [`tests/demo_runtime_checks.c`](/d:/GitHub%20Repo/exploit-lab-cpp/tests/demo_runtime_checks.c:1). +- [`src/overflow_behavior_demo.c`](/d:/GitHub%20Repo/exploit-lab-cpp/src/overflow_behavior_demo.c:1) now uses a deterministic simulation so contributors see the same learning signal across environments. + +## Maintenance Goal + +Keep the repo beginner-friendly, reproducible, and safe to run while still showing why unsafe C patterns matter. diff --git a/src/control_flow_simulation.c b/src/control_flow_simulation.c index d142b84..8d0a352 100644 --- a/src/control_flow_simulation.c +++ b/src/control_flow_simulation.c @@ -1,11 +1,13 @@ #include +#include "demo_programs.h" + /* * safe_function: * Default control-flow target in this demo. */ -static void safe_function(void) { - printf("safe_function(): normal control flow path.\n"); +static void safe_function(FILE *output) { + fprintf(output, "safe_function(): normal control flow path.\n"); } /* @@ -13,25 +15,25 @@ static void safe_function(void) { * Alternate function used to show how changing a function pointer * changes which code executes. */ -static void target_function(void) { - printf("target_function(): alternate control flow path.\n"); +static void target_function(FILE *output) { + fprintf(output, "target_function(): alternate control flow path.\n"); } -int main(void) { +int run_control_flow_simulation(FILE *output) { /* * A function pointer stores an address of executable code. * Calling through this pointer transfers control to the function * currently stored in it. */ - void (*func_ptr)(void) = safe_function; + void (*func_ptr)(FILE *output_stream) = safe_function; - printf("[control_flow_simulation] Conceptual control-flow demo\n"); - printf("Address of safe_function: %p\n", (void *)safe_function); - printf("Address of target_function: %p\n", (void *)target_function); - printf("Address of func_ptr var: %p\n", (void *)&func_ptr); + fprintf(output, "[control_flow_simulation] Conceptual control-flow demo\n"); + fprintf(output, "Address of safe_function: %p\n", (void *)safe_function); + fprintf(output, "Address of target_function: %p\n", (void *)target_function); + fprintf(output, "Address of func_ptr var: %p\n", (void *)&func_ptr); - printf("\nCalling through function pointer (before change):\n"); - func_ptr(); + fprintf(output, "\nCalling through function pointer (before change):\n"); + func_ptr(output); /* * Conceptual simulation: @@ -42,11 +44,18 @@ int main(void) { * redirect execution unexpectedly. This demo only illustrates the idea * of control-flow redirection without exploit code. */ - printf("\nSimulating conceptual pointer corruption by manual reassignment...\n"); + fprintf(output, + "\nSimulating conceptual pointer corruption by manual reassignment...\n"); func_ptr = target_function; - printf("Calling through function pointer (after change):\n"); - func_ptr(); + fprintf(output, "Calling through function pointer (after change):\n"); + func_ptr(output); return 0; } + +#ifndef DEMO_NO_MAIN +int main(void) { + return run_control_flow_simulation(stdout); +} +#endif diff --git a/src/demo_programs.h b/src/demo_programs.h new file mode 100644 index 0000000..13be4b4 --- /dev/null +++ b/src/demo_programs.h @@ -0,0 +1,12 @@ +#ifndef DEMO_PROGRAMS_H +#define DEMO_PROGRAMS_H + +#include + +int run_vuln_buffer_overflow(FILE *input, FILE *output); +int run_safe_input_demo(FILE *input, FILE *output); +int run_stack_layout_demo(FILE *output); +int run_overflow_behavior_demo(FILE *input, FILE *output); +int run_control_flow_simulation(FILE *output); + +#endif diff --git a/src/overflow_behavior_demo.c b/src/overflow_behavior_demo.c index e3816dc..808ea8c 100644 --- a/src/overflow_behavior_demo.c +++ b/src/overflow_behavior_demo.c @@ -1,42 +1,137 @@ +#include #include #include +#include "demo_programs.h" + +enum { + OVERFLOW_DEMO_BUFFER_SIZE = 16, + OVERFLOW_DEMO_MAX_INPUT = 96 +}; + +struct overflow_demo_layout { + char buffer[OVERFLOW_DEMO_BUFFER_SIZE]; + unsigned char x_bytes[sizeof(int)]; +}; + +static size_t trim_newline(char *text) { + size_t len = strcspn(text, "\n"); + + text[len] = '\0'; + return len; +} + +static void print_buffer_preview(FILE *output, const char *buffer, size_t buffer_size) { + size_t index; + + fprintf(output, "Buffer preview: "); + for (index = 0; index < buffer_size; ++index) { + unsigned char byte = (unsigned char)buffer[index]; + + if (byte == '\0') { + break; + } + + fputc(isprint(byte) ? (int)byte : '.', output); + } + fputc('\n', output); +} + +static void print_hex_bytes(FILE *output, const unsigned char *bytes, size_t byte_count) { + size_t index; + + for (index = 0; index < byte_count; ++index) { + fprintf(output, "%02X%s", bytes[index], index + 1 == byte_count ? "" : " "); + } + fputc('\n', output); +} + +static size_t simulate_unbounded_copy(struct overflow_demo_layout *layout, + const char *input) { + unsigned char *raw_bytes = (unsigned char *)layout; + size_t input_len = strlen(input); + size_t index = 0; + + for (index = 0; index < input_len && index < sizeof(*layout); ++index) { + raw_bytes[index] = (unsigned char)input[index]; + } + + if (index < sizeof(*layout)) { + raw_bytes[index++] = '\0'; + } + + return index; +} + /* * Overflow behavior observation demo (educational only). * - * This intentionally keeps an unsafe read to demonstrate that - * out-of-bounds writes can lead to undefined behavior. - * No exploit logic is included. + * This version demonstrates overflow impact deterministically. + * It reads the input safely, then simulates how an unbounded copy + * would walk across adjacent bytes in a small stack-like layout. */ -int main(void) { - char buffer[16]; +int run_overflow_behavior_demo(FILE *input, FILE *output) { + char input_buffer[OVERFLOW_DEMO_MAX_INPUT]; + struct overflow_demo_layout layout; int x = 10; size_t input_len = 0; + size_t bytes_written = 0; + size_t bytes_past_buffer = 0; + size_t bytes_into_x = 0; + + memset(&layout, 0, sizeof(layout)); + memcpy(layout.x_bytes, &x, sizeof(x)); - printf("[overflow_behavior_demo] Observe behavior with long input\n"); - printf("Value of x before input: %d\n", x); - printf("Enter input: "); - - /* - * Unsafe: no width limit is provided. - * If input exceeds buffer capacity, overflow may happen before - * the length check below can run. - */ - if (scanf("%s", buffer) != 1) { - printf("Input error.\n"); + fprintf(output, "[overflow_behavior_demo] Deterministic overflow impact demo\n"); + fprintf(output, "Value of x before input: %d\n", x); + fprintf(output, "Enter input: "); + + if (fgets(input_buffer, sizeof(input_buffer), input) == NULL) { + fprintf(output, "Input error.\n"); return 1; } - input_len = strlen(buffer); - if (input_len >= sizeof(buffer)) { - printf("WARNING: Input length (%lu) exceeds buffer capacity (%lu).\n", - (unsigned long)input_len, - (unsigned long)(sizeof(buffer) - 1)); - printf("Behavior may be unstable (undefined behavior).\n"); + input_len = trim_newline(input_buffer); + bytes_written = simulate_unbounded_copy(&layout, input_buffer); + + if (bytes_written > sizeof(layout.buffer)) { + bytes_past_buffer = bytes_written - sizeof(layout.buffer); + if (bytes_past_buffer > sizeof(layout.x_bytes)) { + bytes_past_buffer = sizeof(layout.x_bytes); + } } - printf("Value of x after input: %d\n", x); - printf("Buffer content: %s\n", buffer); + if (bytes_past_buffer > 0) { + bytes_into_x = bytes_past_buffer; + } + + memcpy(&x, layout.x_bytes, sizeof(x)); + + fprintf(output, "Input length: %lu\n", (unsigned long)input_len); + if (input_len >= sizeof(layout.buffer)) { + fprintf(output, + "WARNING: Input length (%lu) exceeds buffer capacity (%lu).\n", + (unsigned long)input_len, + (unsigned long)(sizeof(layout.buffer) - 1)); + fprintf(output, "Simulated bytes written past buffer: %lu\n", + (unsigned long)bytes_past_buffer); + fprintf(output, "Bytes that reached adjacent int: %lu of %lu\n", + (unsigned long)bytes_into_x, + (unsigned long)sizeof(layout.x_bytes)); + fprintf(output, "Adjacent int bytes after simulation: "); + print_hex_bytes(output, layout.x_bytes, sizeof(layout.x_bytes)); + } else { + fprintf(output, "Input fits inside the buffer in this run.\n"); + } + + fprintf(output, "Value of x after simulated copy: %d\n", x); + print_buffer_preview(output, layout.buffer, sizeof(layout.buffer)); return 0; } + +#ifndef DEMO_NO_MAIN +int main(void) { + return run_overflow_behavior_demo(stdin, stdout); +} +#endif diff --git a/src/safe_input_demo.c b/src/safe_input_demo.c index 0c8de82..197d330 100644 --- a/src/safe_input_demo.c +++ b/src/safe_input_demo.c @@ -1,6 +1,8 @@ #include #include +#include "demo_programs.h" + /* * Safe input demo. * @@ -8,20 +10,26 @@ * sizeof(buffer) - 1 characters and prevents buffer overflow * from this input operation. */ -int main(void) { +int run_safe_input_demo(FILE *input, FILE *output) { char buffer[16]; - printf("[safe_input_demo] Safe input demo\n"); - printf("Enter text: "); + fprintf(output, "[safe_input_demo] Safe input demo\n"); + fprintf(output, "Enter text: "); - if (fgets(buffer, sizeof(buffer), stdin) == NULL) { - printf("Input error.\n"); + if (fgets(buffer, sizeof(buffer), input) == NULL) { + fprintf(output, "Input error.\n"); return 1; } /* Remove trailing newline for cleaner output. */ buffer[strcspn(buffer, "\n")] = '\0'; - printf("You entered safely: %s\n", buffer); + fprintf(output, "You entered safely: %s\n", buffer); return 0; } + +#ifndef DEMO_NO_MAIN +int main(void) { + return run_safe_input_demo(stdin, stdout); +} +#endif diff --git a/src/stack_layout_demo.c b/src/stack_layout_demo.c index e6b2ffe..015c431 100644 --- a/src/stack_layout_demo.c +++ b/src/stack_layout_demo.c @@ -1,12 +1,14 @@ #include +#include "demo_programs.h" + /* * Stack layout demo. * * Prints addresses of local variables and a function parameter * to help visualize how function-call memory is arranged. */ -static void print_stack_layout(int demo_id) { +static void print_stack_layout(FILE *output, int demo_id) { char buffer[16]; int x = 10; @@ -15,17 +17,23 @@ static void print_stack_layout(int demo_id) { * On many systems, the stack often grows downward * (from higher addresses toward lower addresses). */ - printf("Address of buffer: %p\n", (void *)buffer); - printf("Address of x: %p\n", (void *)&x); - printf("Address of parameter demo_id: %p\n", (void *)&demo_id); + fprintf(output, "Address of buffer: %p\n", (void *)buffer); + fprintf(output, "Address of x: %p\n", (void *)&x); + fprintf(output, "Address of parameter demo_id: %p\n", (void *)&demo_id); } -int main(void) { +int run_stack_layout_demo(FILE *output) { int main_local = 1; - printf("[stack_layout_demo] Stack address observation\n"); - printf("Address of main_local: %p\n", (void *)&main_local); - print_stack_layout(42); + fprintf(output, "[stack_layout_demo] Stack address observation\n"); + fprintf(output, "Address of main_local: %p\n", (void *)&main_local); + print_stack_layout(output, 42); return 0; } + +#ifndef DEMO_NO_MAIN +int main(void) { + return run_stack_layout_demo(stdout); +} +#endif diff --git a/src/vuln_buffer_overflow.c b/src/vuln_buffer_overflow.c index a1044c0..f31830d 100644 --- a/src/vuln_buffer_overflow.c +++ b/src/vuln_buffer_overflow.c @@ -1,5 +1,7 @@ #include +#include "demo_programs.h" + /* * Unsafe buffer input demo (educational only). * @@ -8,17 +10,23 @@ * If input is longer than the buffer, memory past the buffer * may be overwritten. */ -int main(void) { +int run_vuln_buffer_overflow(FILE *input, FILE *output) { char buffer[16]; - printf("[vuln_buffer_overflow] Unsafe input demo\n"); - printf("Enter a word: "); + fprintf(output, "[vuln_buffer_overflow] Unsafe input demo\n"); + fprintf(output, "Enter a word: "); - if (scanf("%s", buffer) != 1) { - printf("Input error.\n"); + if (fscanf(input, "%s", buffer) != 1) { + fprintf(output, "Input error.\n"); return 1; } - printf("You entered: %s\n", buffer); + fprintf(output, "You entered: %s\n", buffer); return 0; } + +#ifndef DEMO_NO_MAIN +int main(void) { + return run_vuln_buffer_overflow(stdin, stdout); +} +#endif diff --git a/tests/demo_runtime_checks.c b/tests/demo_runtime_checks.c new file mode 100644 index 0000000..d452f7b --- /dev/null +++ b/tests/demo_runtime_checks.c @@ -0,0 +1,294 @@ +#include +#include +#include +#include + +#include "demo_programs.h" + +static int failure_count = 0; + +struct temp_file { + FILE *stream; + char path[128]; +}; + +static int open_temp_file(struct temp_file *temp_file) { + static unsigned int counter = 0; + + temp_file->stream = NULL; + temp_file->path[0] = '\0'; + + if (snprintf(temp_file->path, + sizeof(temp_file->path), + "tests/runtime_check_%lu_%lu_%u.tmp", + (unsigned long)time(NULL), + (unsigned long)clock(), + counter++) < 0) { + return 0; + } + + temp_file->stream = fopen(temp_file->path, "w+b"); + return temp_file->stream != NULL; +} + +static void close_temp_file(struct temp_file *temp_file) { + if (temp_file->stream != NULL) { + fclose(temp_file->stream); + temp_file->stream = NULL; + } + + if (temp_file->path[0] != '\0') { + remove(temp_file->path); + temp_file->path[0] = '\0'; + } +} + +static char *read_stream(FILE *stream) { + long length = 0; + char *buffer = NULL; + + if (fflush(stream) != 0) { + return NULL; + } + + if (fseek(stream, 0L, SEEK_END) != 0) { + return NULL; + } + + length = ftell(stream); + if (length < 0) { + return NULL; + } + + if (fseek(stream, 0L, SEEK_SET) != 0) { + return NULL; + } + + buffer = (char *)malloc((size_t)length + 1U); + if (buffer == NULL) { + return NULL; + } + + if (length > 0 && fread(buffer, 1U, (size_t)length, stream) != (size_t)length) { + free(buffer); + return NULL; + } + + buffer[length] = '\0'; + return buffer; +} + +static int open_input_stream(struct temp_file *temp_file, const char *text) { + if (!open_temp_file(temp_file)) { + return 0; + } + + if (fputs(text, temp_file->stream) == EOF) { + close_temp_file(temp_file); + return 0; + } + + if (ferror(temp_file->stream)) { + close_temp_file(temp_file); + return 0; + } + + rewind(temp_file->stream); + return 1; +} + +static void expect_contains(const char *test_name, + const char *output, + const char *needle) { + if (strstr(output, needle) == NULL) { + fprintf(stderr, + "[FAIL] %s missing expected text: %s\n", + test_name, + needle); + failure_count++; + } +} + +static void expect_success(const char *test_name, int result) { + if (result != 0) { + fprintf(stderr, "[FAIL] %s returned %d\n", test_name, result); + failure_count++; + } +} + +static void test_safe_input_demo(void) { + const char *test_name = "safe_input_demo"; + struct temp_file input = {0}; + struct temp_file output = {0}; + char *text = NULL; + int result = 0; + + if (!open_input_stream(&input, "hello\n") || !open_temp_file(&output)) { + fprintf(stderr, "[FAIL] %s could not create temp files\n", test_name); + failure_count++; + goto cleanup; + } + + result = run_safe_input_demo(input.stream, output.stream); + text = read_stream(output.stream); + if (text == NULL) { + fprintf(stderr, "[FAIL] %s could not read captured output\n", test_name); + failure_count++; + goto cleanup; + } + + expect_success(test_name, result); + expect_contains(test_name, text, "[safe_input_demo] Safe input demo"); + expect_contains(test_name, text, "You entered safely: hello"); + +cleanup: + free(text); + close_temp_file(&input); + close_temp_file(&output); +} + +static void test_vuln_buffer_overflow(void) { + const char *test_name = "vuln_buffer_overflow"; + struct temp_file input = {0}; + struct temp_file output = {0}; + char *text = NULL; + int result = 0; + + if (!open_input_stream(&input, "hello\n") || !open_temp_file(&output)) { + fprintf(stderr, "[FAIL] %s could not create temp files\n", test_name); + failure_count++; + goto cleanup; + } + + result = run_vuln_buffer_overflow(input.stream, output.stream); + text = read_stream(output.stream); + if (text == NULL) { + fprintf(stderr, "[FAIL] %s could not read captured output\n", test_name); + failure_count++; + goto cleanup; + } + + expect_success(test_name, result); + expect_contains(test_name, text, "[vuln_buffer_overflow] Unsafe input demo"); + expect_contains(test_name, text, "You entered: hello"); + +cleanup: + free(text); + close_temp_file(&input); + close_temp_file(&output); +} + +static void test_stack_layout_demo(void) { + const char *test_name = "stack_layout_demo"; + struct temp_file output = {0}; + char *text = NULL; + int result = 0; + + if (!open_temp_file(&output)) { + fprintf(stderr, "[FAIL] %s could not create temp file\n", test_name); + failure_count++; + return; + } + + result = run_stack_layout_demo(output.stream); + text = read_stream(output.stream); + if (text == NULL) { + fprintf(stderr, "[FAIL] %s could not read captured output\n", test_name); + failure_count++; + close_temp_file(&output); + return; + } + + expect_success(test_name, result); + expect_contains(test_name, text, "[stack_layout_demo] Stack address observation"); + expect_contains(test_name, text, "Address of main_local:"); + expect_contains(test_name, text, "Address of buffer:"); + expect_contains(test_name, text, "Address of x:"); + expect_contains(test_name, text, "Address of parameter demo_id:"); + + free(text); + close_temp_file(&output); +} + +static void test_overflow_behavior_demo(void) { + const char *test_name = "overflow_behavior_demo"; + struct temp_file input = {0}; + struct temp_file output = {0}; + char *text = NULL; + int result = 0; + + if (!open_input_stream(&input, "AAAAAAAAAAAAAAAAAAAAAA\n") || + !open_temp_file(&output)) { + fprintf(stderr, "[FAIL] %s could not create temp files\n", test_name); + failure_count++; + goto cleanup; + } + + result = run_overflow_behavior_demo(input.stream, output.stream); + text = read_stream(output.stream); + if (text == NULL) { + fprintf(stderr, "[FAIL] %s could not read captured output\n", test_name); + failure_count++; + goto cleanup; + } + + expect_success(test_name, result); + expect_contains(test_name, text, + "[overflow_behavior_demo] Deterministic overflow impact demo"); + expect_contains(test_name, text, + "WARNING: Input length (22) exceeds buffer capacity (15)."); + expect_contains(test_name, text, "Bytes that reached adjacent int: 4 of 4"); + expect_contains(test_name, text, "Adjacent int bytes after simulation: 41 41 41 41"); + +cleanup: + free(text); + close_temp_file(&input); + close_temp_file(&output); +} + +static void test_control_flow_simulation(void) { + const char *test_name = "control_flow_simulation"; + struct temp_file output = {0}; + char *text = NULL; + int result = 0; + + if (!open_temp_file(&output)) { + fprintf(stderr, "[FAIL] %s could not create temp file\n", test_name); + failure_count++; + return; + } + + result = run_control_flow_simulation(output.stream); + text = read_stream(output.stream); + if (text == NULL) { + fprintf(stderr, "[FAIL] %s could not read captured output\n", test_name); + failure_count++; + close_temp_file(&output); + return; + } + + expect_success(test_name, result); + expect_contains(test_name, text, + "[control_flow_simulation] Conceptual control-flow demo"); + expect_contains(test_name, text, "safe_function(): normal control flow path."); + expect_contains(test_name, text, "target_function(): alternate control flow path."); + + free(text); + close_temp_file(&output); +} + +int main(void) { + test_safe_input_demo(); + test_vuln_buffer_overflow(); + test_stack_layout_demo(); + test_overflow_behavior_demo(); + test_control_flow_simulation(); + + if (failure_count != 0) { + fprintf(stderr, "\n%d runtime check(s) failed.\n", failure_count); + return 1; + } + + printf("All runtime checks passed.\n"); + return 0; +} diff --git a/tests/runtime_check_1776156560_0.tmp b/tests/runtime_check_1776156560_0.tmp new file mode 100644 index 0000000..ce01362 --- /dev/null +++ b/tests/runtime_check_1776156560_0.tmp @@ -0,0 +1 @@ +hello diff --git a/tests/runtime_check_1776156560_1.tmp b/tests/runtime_check_1776156560_1.tmp new file mode 100644 index 0000000..949ec06 --- /dev/null +++ b/tests/runtime_check_1776156560_1.tmp @@ -0,0 +1,2 @@ +[safe_input_demo] Safe input demo +Enter text: You entered safely: hello diff --git a/tests/runtime_check_1776156560_2.tmp b/tests/runtime_check_1776156560_2.tmp new file mode 100644 index 0000000..ce01362 --- /dev/null +++ b/tests/runtime_check_1776156560_2.tmp @@ -0,0 +1 @@ +hello diff --git a/tests/runtime_check_1776156560_3.tmp b/tests/runtime_check_1776156560_3.tmp new file mode 100644 index 0000000..c30b5b8 --- /dev/null +++ b/tests/runtime_check_1776156560_3.tmp @@ -0,0 +1,2 @@ +[vuln_buffer_overflow] Unsafe input demo +Enter a word: You entered: hello diff --git a/tests/runtime_check_1776156560_4.tmp b/tests/runtime_check_1776156560_4.tmp new file mode 100644 index 0000000..7ac5ad7 --- /dev/null +++ b/tests/runtime_check_1776156560_4.tmp @@ -0,0 +1,5 @@ +[stack_layout_demo] Stack address observation +Address of main_local: 0061FE4C +Address of buffer: 0061FE10 +Address of x: 0061FE0C +Address of parameter demo_id: 0061FE34 diff --git a/tests/runtime_check_1776156560_5.tmp b/tests/runtime_check_1776156560_5.tmp new file mode 100644 index 0000000..b20553a --- /dev/null +++ b/tests/runtime_check_1776156560_5.tmp @@ -0,0 +1 @@ +AAAAAAAAAAAAAAAAAAAAAA diff --git a/tests/runtime_check_1776156560_6.tmp b/tests/runtime_check_1776156560_6.tmp new file mode 100644 index 0000000..963a84d --- /dev/null +++ b/tests/runtime_check_1776156560_6.tmp @@ -0,0 +1,9 @@ +[overflow_behavior_demo] Deterministic overflow impact demo +Value of x before input: 10 +Enter input: Input length: 22 +WARNING: Input length (22) exceeds buffer capacity (15). +Simulated bytes written past buffer: 4 +Bytes that reached adjacent int: 4 of 4 +Adjacent int bytes after simulation: 41 41 41 41 +Value of x after simulated copy: 1094795585 +Buffer preview: AAAAAAAAAAAAAAAA diff --git a/tests/runtime_check_1776156560_7.tmp b/tests/runtime_check_1776156560_7.tmp new file mode 100644 index 0000000..9f3e342 --- /dev/null +++ b/tests/runtime_check_1776156560_7.tmp @@ -0,0 +1,11 @@ +[control_flow_simulation] Conceptual control-flow demo +Address of safe_function: 004025CC +Address of target_function: 004025F8 +Address of func_ptr var: 0061FE4C + +Calling through function pointer (before change): +safe_function(): normal control flow path. + +Simulating conceptual pointer corruption by manual reassignment... +Calling through function pointer (after change): +target_function(): alternate control flow path. diff --git a/tests/runtime_check_1776156908_1_0.tmp b/tests/runtime_check_1776156908_1_0.tmp new file mode 100644 index 0000000..ce01362 --- /dev/null +++ b/tests/runtime_check_1776156908_1_0.tmp @@ -0,0 +1 @@ +hello diff --git a/tests/runtime_check_1776156908_1_1.tmp b/tests/runtime_check_1776156908_1_1.tmp new file mode 100644 index 0000000..949ec06 --- /dev/null +++ b/tests/runtime_check_1776156908_1_1.tmp @@ -0,0 +1,2 @@ +[safe_input_demo] Safe input demo +Enter text: You entered safely: hello diff --git a/tests/runtime_check_1776156908_1_2.tmp b/tests/runtime_check_1776156908_1_2.tmp new file mode 100644 index 0000000..ce01362 --- /dev/null +++ b/tests/runtime_check_1776156908_1_2.tmp @@ -0,0 +1 @@ +hello diff --git a/tests/runtime_check_1776156908_1_3.tmp b/tests/runtime_check_1776156908_1_3.tmp new file mode 100644 index 0000000..c30b5b8 --- /dev/null +++ b/tests/runtime_check_1776156908_1_3.tmp @@ -0,0 +1,2 @@ +[vuln_buffer_overflow] Unsafe input demo +Enter a word: You entered: hello diff --git a/tests/runtime_check_1776156908_2_4.tmp b/tests/runtime_check_1776156908_2_4.tmp new file mode 100644 index 0000000..7ac5ad7 --- /dev/null +++ b/tests/runtime_check_1776156908_2_4.tmp @@ -0,0 +1,5 @@ +[stack_layout_demo] Stack address observation +Address of main_local: 0061FE4C +Address of buffer: 0061FE10 +Address of x: 0061FE0C +Address of parameter demo_id: 0061FE34 diff --git a/tests/runtime_check_1776156908_2_5.tmp b/tests/runtime_check_1776156908_2_5.tmp new file mode 100644 index 0000000..b20553a --- /dev/null +++ b/tests/runtime_check_1776156908_2_5.tmp @@ -0,0 +1 @@ +AAAAAAAAAAAAAAAAAAAAAA diff --git a/tests/runtime_check_1776156908_2_6.tmp b/tests/runtime_check_1776156908_2_6.tmp new file mode 100644 index 0000000..963a84d --- /dev/null +++ b/tests/runtime_check_1776156908_2_6.tmp @@ -0,0 +1,9 @@ +[overflow_behavior_demo] Deterministic overflow impact demo +Value of x before input: 10 +Enter input: Input length: 22 +WARNING: Input length (22) exceeds buffer capacity (15). +Simulated bytes written past buffer: 4 +Bytes that reached adjacent int: 4 of 4 +Adjacent int bytes after simulation: 41 41 41 41 +Value of x after simulated copy: 1094795585 +Buffer preview: AAAAAAAAAAAAAAAA diff --git a/tests/runtime_check_1776156908_3_7.tmp b/tests/runtime_check_1776156908_3_7.tmp new file mode 100644 index 0000000..bc77e48 --- /dev/null +++ b/tests/runtime_check_1776156908_3_7.tmp @@ -0,0 +1,11 @@ +[control_flow_simulation] Conceptual control-flow demo +Address of safe_function: 004025D8 +Address of target_function: 00402604 +Address of func_ptr var: 0061FE4C + +Calling through function pointer (before change): +safe_function(): normal control flow path. + +Simulating conceptual pointer corruption by manual reassignment... +Calling through function pointer (after change): +target_function(): alternate control flow path.