Architecture Overview
Rune Editor follows a hybrid architecture: a modern React web interface communicates with a lightweight C++ HTTP server that performs the actual memory operations. This separation allows for a polished UI while maintaining direct hardware access required for game modification.
Backend: C++ Memory Server
Win32 Process API
The backend uses Windows native APIs for process manipulation:
OpenProcesswithPROCESS_ALL_ACCESSto attach to ELDEN RINGReadProcessMemory/WriteProcessMemoryfor data operationsVirtualQueryExfor memory region enumerationGetModuleBaseAddressto locate game modules
PROCESS_ALL_ACCESS
on protected processes. The application requests UAC elevation at launch.
HTTP Server (cpp-httplib)
Instead of a custom protocol, the backend exposes a REST API using cpp-httplib for simplicity:
POST /api/read
{
"address": "0x7FF123456000",
"size": 4,
"type": "int32"
}
POST /api/write
{
"address": "0x7FF123456000",
"value": 999999,
"type": "int32"
}
GET /api/status
{
"attached": true,
"process_id": 12345,
"module_base": "0x7FF123400000"
}
Pointer Chain Resolution
Game values aren't at static addresses. Rune Editor resolves multi-level pointer chains to locate rune values dynamically across game restarts:
base = GetModuleBase("eldenring.exe")
ptr1 = ReadMemory(base + 0x12345678)
ptr2 = ReadMemory(ptr1 + 0xA0)
ptr3 = ReadMemory(ptr2 + 0x18)
runes = ReadMemory(ptr3 + 0x8C) // Final value
Frontend: React + Vite
UI Architecture
The frontend is a standard React 18 application built with Vite:
src/
├── components/
│ ├── RuneEditor.tsx # Main value editor
│ ├── PointerChain.tsx # Chain visualization
│ ├── StatusBar.tsx # Connection state
│ └── StatsPanel.tsx # Character stats
├── hooks/
│ ├── useMemory.ts # Backend communication
│ └── useProcess.ts # Process detection
└── api/
└── client.ts # HTTP client wrapper
Real-Time Synchronization
The frontend polls the backend for value changes while also supporting direct manipulation:
- Polling every 500ms for rune value updates
- Optimistic UI for write operations
- Auto-retry with exponential backoff on disconnect
- Process lifecycle detection (auto-reattach)
Standalone Packaging
Build Process
The application packages into a single distributable folder:
- Vite builds the React frontend to
dist/ - C++ backend compiles to
dist/RuneEditor.exe - Backend serves static files from
dist/assets/ - Launch opens default browser to
http://localhost:8765
Development vs Production
Development uses Vite's dev server with proxy configuration:
// vite.config.ts
server: {
proxy: {
'/api': 'http://127.0.0.1:8765'
}
}
Technical Challenges
Process Elevation
Modern games run with elevated integrity levels. The tool must:
- Embed a UAC manifest requesting administrator privileges
- Handle access denied errors gracefully
- Detect if game is running before elevation attempt
Pointer Chain Stability
Game updates break pointer chains. The tool implements:
- Signature scanning as fallback (AOB patterns)
- Version detection to load appropriate chain definitions
- User-configurable offsets for custom versions
What I Learned
Building Rune Editor deepened my understanding of Windows process architecture and the practical challenges of cross-language development. Managing the boundary between a managed React app and raw memory access taught me about API design for security-sensitive operations.
Project Status
Rune Editor is closed-source and used privately. The architecture could extend to other games by swapping pointer chains and process names.