A blazingly fast, memory-safe, entirely Vibe Coded, GPU-accelerated terminal emulator written in Rust, with an advanced configuration system powered by exploiting memory vulnerabilities in a virtual machine using a dedicated opensource Lua-like scripting language called Segfault Lang.
Spaghetty is a monorepo containing:
- spaghetty-term - A GPU-accelerated terminal emulator built with wgpu
- segfault-vm - An educational VM with intentional memory vulnerabilities
- segfault-cli - CLI tool to run
.segscripts - segfault-config - Parser that reads terminal config from VM memory dumps
The terminal runs a .seg script at startup, and the script must "exploit" the VM's memory vulnerabilities to write configuration values (colors, font size, etc.) into specific memory regions.
cargo build --releasecargo run -p spaghetty-termWe spent an mass amount of effort choosing the perfect default configuration. Black background, white text, 12pt font -- perfection. Nobody should ever need to change it.
But if you insist on customizing things, we're not going to make it easy. There is no config file. No settings menu. No --theme flag. Instead, at startup, the terminal runs a script inside a deliberately vulnerable virtual machine called the Segfault VM. Your configuration lives somewhere in the VM's memory. If you can figure out where your config variables landed and manage to overwrite them by exploiting memory vulnerabilities, congratulations -- you've earned your custom color scheme. You can write your exploit in our brand new Segfault Lang (.seg files).
Here's what you're working with:
strcpy doesn't check bounds. Allocate a variable, figure out how far it is from the config variable you want to change, and overflow right into it:
exploit = "XXXXX"
strcpy(exploit, "AAAA...enough padding to reach bg_color...00FF00")There's a system secret hidden at address 0xFF. We put %m in printf because we thought it would be funny:
printf("The secret is: %m") -- Prints: "The secret is: 0xDE"Reading from address 0x00 triggers a kernel panic. Don't do this. Or do. We're not your parents:
peek(0) -- KERNEL PANIC!- Run
--show-fingerprintormemdump()to figure out where your config variables ended up - Find a gap in memory that ends right before the config variable you want to overwrite
- Allocate a variable that lands in that gap (first-fit allocation)
- Use
strcpyto overflow past your variable and into the config
-- In deterministic mode, bg_color lands at 0xC7
-- Our variable starts at 0x01, so we need 198 bytes of padding
exploit = "XXXXX"
strcpy(exploit, "AAAAAA...198 A's...00FF00")
printf("bg_color is now: %sbg_color")Every device gets a different memory layout. Use
--deterministicfor a fixed layout while you're learning. Then try your own device's layout, because copying someone else's exploit is cheating and also literally won't work.
-- examples/default.seg
-- Set config using bounded variable assignment (no exploit needed)
bg_color = "000000" -- Black background
fg_color = "FFFFFF" -- White foreground
font_size = "12" -- 12pt font
opacity = "255" -- Full opacity
printf("bg_color = %sbg_color")-- examples/exploit.seg
-- Run with: cargo run -p segfault-cli -- --deterministic -v -l examples/exploit.seg
-- Leak the system secret
printf("System Secret: %m")
-- Allocate exploit variable (first-fit, lands at 0x01)
exploit = "XXXXX"
-- Overflow 198 bytes of padding + new bg_color "00FF00" (green)
strcpy(exploit, "AAAAAA...198 A's...00FF00")
-- Verify
printf("bg_color: %sbg_color")-- examples/panic.seg
bg_color = "FF0000" -- Set red background first
fg_color = "FFFFFF" -- White foreground
printf("Attempting to read from null page...")
peek(0) -- KERNEL PANIC!
-- This line will never executeSegfault Lang is a simple scripting language (.seg files) designed for the VM:
-- Comments start with --
name = "value" -- Variable assignment (allocates in first available gap)
bg_color = "FF0000" -- Config variable assignment (bounded write)
peek(addr) -- Read a byte from memory
strcpy(dest_var, source) -- Copy string to variable (VULNERABLE - no bounds check!)
printf(value) -- Print with format strings (VULNERABLE - %m leaks secret)
memdump(start, len) -- Dump memory regionpayload = "\x41\x42" -- Hex escape sequences
msg = "line1\nline2" -- Newline, tab (\t), carriage return (\r)printf("Secret: %m") -- %m leaks system secret at 0xFF
printf("bg = %sbg_color") -- %s<varname> reads variable value inline# Run a script
cargo run -p segfault-cli -- examples/exploit.seg
# Run with verbose output and config display
cargo run -p segfault-cli -- -v -c examples/exploit.seg
# Run with deterministic memory layout (for testing/development)
cargo run -p segfault-cli -- --deterministic -v -l examples/exploit.seg
# Show your device fingerprint and derived memory layout
cargo run -p segfault-cli -- --show-fingerprint
# Show help
cargo run -p segfault-cli -- --helpThe VM implements an ASLR-like mechanism that scatters config variables at different addresses on every device. This means exploit scripts are device-specific and cannot be shared directly between machines.
The memory layout is derived from a SHA-256 hash of a device fingerprint:
seed = SHA-256(machine_id + hostname + username)
- machine_id: from
/etc/machine-id(Linux) - hostname: from
/etc/hostnameor$HOSTNAME - username: from
$USER
Each byte of the hash determines the gap size before the corresponding config variable, distributing them pseudo-randomly across the 254-byte allocatable space (0x01-0xFE).
| Mode | Flag | Seed | Use Case |
|---|---|---|---|
| Fingerprint (default) | (none) | Device-specific hash | Normal usage, unique per machine |
| Deterministic | --deterministic |
SHA-256("debug") |
Testing, tutorials, reproducible results |
Use --show-fingerprint or -l to inspect your device's memory layout and find the gaps between config variables.
The VM has 1024 bytes of memory. Config variables are stored as strings and scattered across the allocatable space.
| Address | Description |
|---|---|
| 0x00 | Null page (read/write triggers kernel panic) |
| 0xFF | System secret (0xDE) |
| Variable | Size | Default | Description |
|---|---|---|---|
| bg_color | 7 bytes | "000000" | Background color (RRGGBB hex string) |
| fg_color | 7 bytes | "FFFFFF" | Foreground color (RRGGBB hex string) |
| font_size | 3 bytes | "12" | Font size in points |
| font_weight | 4 bytes | "400" | CSS font weight (100-900) |
| cursor_style | 2 bytes | "1" | Cursor style (0-5) |
| opacity | 4 bytes | "255" | Opacity (0-255) |
Config variables are not adjacent -- there are gaps between them where user variables can be allocated.
When you assign a new variable (myvar = "value"), it is allocated using first-fit in the gaps between config regions:
- The allocator finds the first gap large enough to hold your variable
- Your variable is placed at the start of that gap
- Strategic sizing lets you control where your variable lands relative to config variables
spaghetty/
├── Cargo.toml # Workspace root
├── crates/
│ ├── spaghetty-term/ # Terminal emulator
│ │ └── src/
│ │ ├── main.rs # App entry, splash screen
│ │ ├── renderer.rs # wgpu rendering
│ │ ├── terminal.rs # Terminal state
│ │ ├── pty.rs # PTY handling
│ │ ├── input.rs # Keyboard input
│ │ └── shader.wgsl # GPU shaders
│ ├── segfault-vm/ # Virtual machine
│ │ └── src/
│ │ ├── lib.rs
│ │ ├── vm.rs # VM implementation
│ │ ├── lexer.rs # Tokenizer
│ │ ├── parser.rs # Parser
│ │ └── memory.rs # Memory layout
│ ├── segfault-cli/ # CLI tool
│ │ └── src/main.rs
│ └── segfault-config/ # Config parser
│ └── src/lib.rs
└── examples/
├── default.seg # Safe config
├── exploit.seg # Full exploit demo
├── cyberpunk.seg # Cyberpunk theme
└── panic.seg # Kernel panic demo
GLWTS(Good Luck With That Shit) Public License
