mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-03-22 15:20:15 +00:00
Update docs to reflect current project state
- Update README: date, Warden complete with Unicorn Engine, add trainers/nonbinary to features, add Unicorn Engine to deps - Update status.md: date, mark quests/trainers/Warden as working, keep transports as in-progress - Rewrite Warden docs (QUICK_REFERENCE and IMPLEMENTATION) to match actual implementation - Remove dev-note docs (WARDEN_COMPLETE, WARDEN_MODULE_ARCHITECTURE) and stray .txt files - Update ATTRIBUTION: add Unicorn Engine, miniaudio, AzerothCore
This commit is contained in:
parent
42e7e1ce7e
commit
e29b67dad9
9 changed files with 205 additions and 12062 deletions
|
|
@ -28,6 +28,11 @@ https://github.com/cmangos/mangos-wotlk
|
|||
|
||||
Open-source WoW server emulator. Referenced for protocol documentation and authentication flow.
|
||||
|
||||
### AzerothCore
|
||||
https://github.com/azerothcore/azerothcore-wotlk
|
||||
|
||||
Open-source WoW 3.3.5a server. Referenced for SRP6 authentication details, update field indices, and packet structures.
|
||||
|
||||
## Libraries
|
||||
|
||||
This project uses the following open-source libraries:
|
||||
|
|
@ -37,7 +42,9 @@ This project uses the following open-source libraries:
|
|||
| [SDL2](https://libsdl.org/) | zlib | Window management, input handling |
|
||||
| [GLEW](http://glew.sourceforge.net/) | BSD/MIT | OpenGL extension loading |
|
||||
| [GLM](https://github.com/g-truc/glm) | MIT | Mathematics library |
|
||||
| [OpenSSL](https://www.openssl.org/) | Apache 2.0 | Cryptographic functions (SRP6) |
|
||||
| [OpenSSL](https://www.openssl.org/) | Apache 2.0 | Cryptographic functions (SRP6, RC4, RSA) |
|
||||
| [Unicorn Engine](https://www.unicorn-engine.org/) | LGPL 2 | x86 CPU emulation for Warden module execution |
|
||||
| [miniaudio](https://miniaud.io/) | MIT/Unlicense | Audio playback |
|
||||
| [StormLib](https://github.com/ladislav-zezula/StormLib) | MIT | MPQ archive extraction |
|
||||
| [Dear ImGui](https://github.com/ocornut/imgui) | MIT | Immediate mode GUI |
|
||||
|
||||
|
|
|
|||
31
README.md
31
README.md
|
|
@ -14,12 +14,12 @@ Primary target today is **WotLK 3.3.5a**, with active work to broaden compatibil
|
|||
|
||||
> **Legal Disclaimer**: This is an educational/research project. It does not include any Blizzard Entertainment assets, data files, or proprietary code. World of Warcraft and all related assets are the property of Blizzard Entertainment, Inc. This project is not affiliated with or endorsed by Blizzard Entertainment. Users are responsible for supplying their own legally obtained game data files and for ensuring compliance with all applicable laws in their jurisdiction.
|
||||
|
||||
## Status & Direction (2026-02-15)
|
||||
## Status & Direction (2026-02-17)
|
||||
|
||||
- **Compatibility direction**: support **Vanilla (Classic) + TBC + WotLK** by selecting an expansion profile and using opcode/parser variants (`src/game/packet_parsers_classic.cpp`, `src/game/packet_parsers_tbc.cpp`).
|
||||
- **Primary target**: WoW **WotLK 3.3.5a (build 12340)** online client, tested mainly against WotLK emulator cores (AzerothCore/TrinityCore variants).
|
||||
- **Current focus**: protocol correctness (chat, spell casting results, transports) and visuals accuracy (M2/WMO edge cases, equipment textures).
|
||||
- **Warden**: crypto + module plumbing are implemented; full module execution is still in progress (see Warden docs).
|
||||
- **Compatibility**: **Vanilla (Classic) + TBC + WotLK** via expansion profiles and opcode/parser variants (`src/game/packet_parsers_classic.cpp`, `src/game/packet_parsers_tbc.cpp`). Turtle WoW (1.17) is also supported.
|
||||
- **Primary target**: WoW **WotLK 3.3.5a (build 12340)** online client, tested against AzerothCore/TrinityCore variants and Turtle WoW.
|
||||
- **Current focus**: protocol correctness across server variants, visual accuracy (M2/WMO edge cases, equipment textures), and multi-expansion coverage.
|
||||
- **Warden**: Full module execution via Unicorn Engine CPU emulation. Decrypts (RC4→RSA→zlib), parses and relocates the PE module, executes via x86 emulation with Windows API interception. Module cache at `~/.local/share/wowee/warden_cache/`.
|
||||
|
||||
## Features
|
||||
|
||||
|
|
@ -46,20 +46,22 @@ Primary target today is **WotLK 3.3.5a**, with active work to broaden compatibil
|
|||
|
||||
### Gameplay Systems
|
||||
- **Authentication** -- Full SRP6a implementation with RC4 header encryption
|
||||
- **Character System** -- Creation, selection, 3D preview, stats panel, race/class support
|
||||
- **Character System** -- Creation (with nonbinary gender option), selection, 3D preview, stats panel, race/class support
|
||||
- **Movement** -- WASD movement, camera orbit, spline path following
|
||||
- **Combat** -- Auto-attack, spell casting with cooldowns, damage calculation, death handling
|
||||
- **Targeting** -- Tab-cycling, click-to-target, faction-based hostility (using Faction.dbc)
|
||||
- **Inventory** -- 23 equipment slots, 16 backpack slots, drag-drop, auto-equip
|
||||
- **Spells** -- Spellbook with class specialty tabs, drag-drop to action bar, spell icons
|
||||
- **Action Bar** -- 12 slots, drag-drop from spellbook/inventory, click-to-cast, keybindings
|
||||
- **Trainers** -- Spell trainer UI, buy spells, known/available/unavailable states
|
||||
- **Quests** -- Quest markers (! and ?) on NPCs and minimap, quest log, quest details, turn-in flow
|
||||
- **Vendors** -- Buy and sell items, gold tracking, inventory sync
|
||||
- **Loot** -- Loot window, gold looting, item pickup
|
||||
- **Gossip** -- NPC interaction, dialogue options
|
||||
- **Chat** -- Tabs/channels, emotes, chat bubbles, clickable URLs, clickable item links with tooltips
|
||||
- **Party** -- Group invites, party list
|
||||
- **UI** -- Loading screens with progress bar, settings window with opacity slider
|
||||
- **Warden** -- Warden anti-cheat module execution via Unicorn Engine x86 emulation (cross-platform, no Wine)
|
||||
- **UI** -- Loading screens with progress bar, settings window, minimap with zoom/rotation/square mode
|
||||
|
||||
## Building
|
||||
|
||||
|
|
@ -69,16 +71,19 @@ Primary target today is **WotLK 3.3.5a**, with active work to broaden compatibil
|
|||
# Ubuntu/Debian
|
||||
sudo apt install libsdl2-dev libglew-dev libglm-dev \
|
||||
libssl-dev cmake build-essential \
|
||||
libstorm-dev # for asset_extract
|
||||
libunicorn-dev \ # for Warden module execution
|
||||
libstorm-dev # for asset_extract
|
||||
|
||||
# Fedora
|
||||
sudo dnf install SDL2-devel glew-devel glm-devel \
|
||||
openssl-devel cmake gcc-c++ \
|
||||
StormLib-devel # for asset_extract
|
||||
unicorn-devel \ # for Warden module execution
|
||||
StormLib-devel # for asset_extract
|
||||
|
||||
# Arch
|
||||
sudo pacman -S sdl2 glew glm openssl cmake base-devel \
|
||||
stormlib # for asset_extract
|
||||
unicorn \ # for Warden module execution
|
||||
stormlib # for asset_extract
|
||||
```
|
||||
|
||||
### Game Data
|
||||
|
|
@ -189,15 +194,15 @@ make -j$(nproc)
|
|||
- [SRP Implementation](docs/srp-implementation.md) -- Cryptographic details
|
||||
- [Packet Framing](docs/packet-framing.md) -- Network protocol framing
|
||||
- [Realm List](docs/realm-list.md) -- Realm selection system
|
||||
- [Warden Quick Reference](docs/WARDEN_QUICK_REFERENCE.md) -- Testing notes and common fixes
|
||||
- [Warden Implementation](docs/WARDEN_IMPLEMENTATION.md) -- What works today and what remains
|
||||
- [Warden Quick Reference](docs/WARDEN_QUICK_REFERENCE.md) -- Warden module execution overview and testing
|
||||
- [Warden Implementation](docs/WARDEN_IMPLEMENTATION.md) -- Technical details of the implementation
|
||||
|
||||
## Technical Details
|
||||
|
||||
- **Graphics**: OpenGL 3.3 Core, GLSL 330, forward rendering with post-processing
|
||||
- **Performance**: 60 FPS (vsync), ~50k triangles/frame, ~30 draw calls, <10% GPU
|
||||
- **Platform**: Linux (primary), C++20, CMake 3.15+
|
||||
- **Dependencies**: SDL2, OpenGL/GLEW, GLM, OpenSSL, ImGui, FFmpeg (StormLib for asset extraction tooling; Unicorn optional for Warden emulation)
|
||||
- **Dependencies**: SDL2, OpenGL/GLEW, GLM, OpenSSL, ImGui, FFmpeg, Unicorn Engine (StormLib for asset extraction tooling)
|
||||
- **Architecture**: Modular design with clear separation (core, rendering, networking, game logic, asset pipeline, UI, audio)
|
||||
- **Networking**: Non-blocking TCP, SRP6a authentication, RC4 encryption, WoW 3.3.5a protocol
|
||||
- **Asset Loading**: Extracted loose-file tree + `manifest.json` indexing, async terrain streaming, overlay layers
|
||||
|
|
|
|||
|
|
@ -1,462 +0,0 @@
|
|||
# Warden Anti-Cheat: Complete Implementation
|
||||
|
||||
**Status**: ✅ PRODUCTION READY
|
||||
**Date**: 2026-02-12
|
||||
**Version**: WoW 3.3.5a (build 12340)
|
||||
**Platform**: Cross-platform (Linux/macOS/Windows/ARM)
|
||||
|
||||
---
|
||||
|
||||
## Executive Summary
|
||||
|
||||
We have implemented a **complete, cross-platform Warden anti-cheat emulation system** capable of:
|
||||
|
||||
1. ✅ Receiving encrypted Warden modules from WoW servers
|
||||
2. ✅ Validating and decrypting modules (MD5, RC4, RSA, zlib)
|
||||
3. ✅ Loading modules into executable memory
|
||||
4. ✅ Executing Windows x86 code on any platform (via Unicorn Engine)
|
||||
5. ✅ Intercepting Windows API calls with custom implementations
|
||||
6. ✅ Processing anti-cheat checks with authentic module responses
|
||||
|
||||
**This solves the fundamental problem**: Strict servers like Warmane require actual module execution, not faked responses. We can now execute real modules without Wine!
|
||||
|
||||
---
|
||||
|
||||
## Architecture Overview
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ GameHandler │
|
||||
│ Receives SMSG_WARDEN_DATA from server │
|
||||
└────────────────────┬────────────────────────────────────────┘
|
||||
│
|
||||
┌────────────────────▼────────────────────────────────────────┐
|
||||
│ WardenModuleManager │
|
||||
│ - Module caching (~/.local/share/wowee/warden_cache/) │
|
||||
│ - Lifecycle management │
|
||||
│ - Multiple module support │
|
||||
└────────────────────┬────────────────────────────────────────┘
|
||||
│
|
||||
┌────────────────────▼────────────────────────────────────────┐
|
||||
│ WardenModule │
|
||||
│ 8-Step Loading Pipeline: │
|
||||
│ 1. MD5 Verification ✅ Working │
|
||||
│ 2. RC4 Decryption ✅ Working │
|
||||
│ 3. RSA Signature ✅ Working (placeholder key) │
|
||||
│ 4. zlib Decompression ✅ Working │
|
||||
│ 5. Executable Parsing ✅ Working │
|
||||
│ 6. Relocations ⚠️ Stub (needs real module) │
|
||||
│ 7. API Binding ✅ Ready │
|
||||
│ 8. Initialization ✅ Working │
|
||||
└────────────────────┬────────────────────────────────────────┘
|
||||
│
|
||||
┌────────────────────▼────────────────────────────────────────┐
|
||||
│ WardenEmulator │
|
||||
│ Cross-Platform x86 Emulation (Unicorn Engine) │
|
||||
│ │
|
||||
│ Memory Layout: │
|
||||
│ 0x00400000 Module Code (loaded x86 binary) │
|
||||
│ 0x00100000 Stack (1MB, grows down) │
|
||||
│ 0x00200000 Heap (16MB, dynamic allocation) │
|
||||
│ 0x70000000 API Stubs (hooked Windows functions) │
|
||||
│ │
|
||||
│ Windows API Hooks: │
|
||||
│ ✅ VirtualAlloc / VirtualFree │
|
||||
│ ✅ GetTickCount, Sleep │
|
||||
│ ✅ GetCurrentThreadId / GetCurrentProcessId │
|
||||
│ ✅ ReadProcessMemory │
|
||||
│ │
|
||||
│ Execution: │
|
||||
│ → Call module entry point with ClientCallbacks │
|
||||
│ → Module returns WardenFuncList │
|
||||
│ → Call PacketHandler for check processing │
|
||||
│ → Generate authentic responses │
|
||||
└──────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Complete Feature Matrix
|
||||
|
||||
| Feature | Status | Notes |
|
||||
|---------|--------|-------|
|
||||
| **Module Reception** | ✅ Complete | Handles multi-packet downloads |
|
||||
| **Crypto Pipeline** | ✅ Complete | MD5, RC4, RSA, zlib |
|
||||
| **Module Parsing** | ✅ Complete | Skip/copy executable format |
|
||||
| **Memory Allocation** | ✅ Complete | mmap (Linux), VirtualAlloc (Windows) |
|
||||
| **Cross-Platform Exec** | ✅ Complete | Unicorn Engine emulation |
|
||||
| **Windows API Hooks** | ✅ Complete | 7+ common APIs hooked |
|
||||
| **Entry Point Calling** | ✅ Complete | ClientCallbacks structure |
|
||||
| **Check Processing** | ✅ Complete | PacketHandler framework |
|
||||
| **Module Caching** | ✅ Complete | Persistent disk cache |
|
||||
| **Sandboxing** | ✅ Complete | Emulated environment isolation |
|
||||
|
||||
---
|
||||
|
||||
## How It Works
|
||||
|
||||
### 1. Module Download
|
||||
|
||||
```
|
||||
Server → SMSG_WARDEN_DATA (opcode 0x2E6)
|
||||
[1 byte] Module opcode
|
||||
[16 bytes] RC4 seed
|
||||
[20 bytes] Trailing data (SHA1?)
|
||||
[N bytes] Encrypted module data (may span multiple packets)
|
||||
```
|
||||
|
||||
**Our Response:**
|
||||
- Initialize WardenCrypto with seed
|
||||
- Decrypt module data with RC4
|
||||
- Send CMSG_WARDEN_DATA acknowledgment
|
||||
|
||||
### 2. Module Validation
|
||||
|
||||
```cpp
|
||||
// Step 1: Verify MD5 hash
|
||||
bool md5Valid = verifyMD5(moduleData, expectedHash);
|
||||
|
||||
// Step 2: Decrypt with RC4
|
||||
std::vector<uint8_t> decrypted = decryptRC4(moduleData, rc4Key);
|
||||
|
||||
// Step 3: Verify RSA signature
|
||||
bool sigValid = verifyRSASignature(decrypted);
|
||||
// SHA1(module_data + "MAIEV.MOD") with 256-byte RSA-2048 signature
|
||||
|
||||
// Step 4: Decompress zlib
|
||||
std::vector<uint8_t> decompressed = decompressZlib(decrypted);
|
||||
```
|
||||
|
||||
### 3. Module Loading
|
||||
|
||||
```cpp
|
||||
// Step 5: Parse executable format
|
||||
// Format: [4-byte size][alternating skip/copy sections]
|
||||
parseExecutableFormat(decompressed);
|
||||
|
||||
// Allocate executable memory
|
||||
#ifdef _WIN32
|
||||
moduleMemory_ = VirtualAlloc(..., PAGE_EXECUTE_READWRITE);
|
||||
#else
|
||||
moduleMemory_ = mmap(..., PROT_READ | PROT_WRITE | PROT_EXEC);
|
||||
#endif
|
||||
|
||||
// Copy code sections (skip sections are ignored)
|
||||
for (auto section : copySections) {
|
||||
memcpy(moduleMemory_ + offset, section.data, section.size);
|
||||
}
|
||||
```
|
||||
|
||||
### 4. Emulator Initialization
|
||||
|
||||
```cpp
|
||||
#ifdef HAVE_UNICORN
|
||||
// Create x86 emulator
|
||||
emulator_ = std::make_unique<WardenEmulator>();
|
||||
emulator_->initialize(moduleMemory_, moduleSize_, 0x400000);
|
||||
|
||||
// Map memory regions
|
||||
// - Module code: 0x400000
|
||||
// - Stack: 0x100000 (1MB)
|
||||
// - Heap: 0x200000 (16MB)
|
||||
|
||||
// Hook Windows APIs
|
||||
emulator_->setupCommonAPIHooks();
|
||||
#endif
|
||||
```
|
||||
|
||||
### 5. Module Initialization
|
||||
|
||||
```cpp
|
||||
// Create ClientCallbacks structure
|
||||
struct ClientCallbacks {
|
||||
void (*sendPacket)(uint8_t*, size_t);
|
||||
void (*validateModule)(uint8_t*);
|
||||
void* (*allocMemory)(size_t);
|
||||
void (*freeMemory)(void*);
|
||||
void (*generateRC4)(uint8_t*);
|
||||
uint32_t (*getTime)();
|
||||
void (*logMessage)(const char*);
|
||||
};
|
||||
|
||||
// Write to emulated memory
|
||||
uint32_t callbackAddr = emulator_->writeData(&callbacks, sizeof(callbacks));
|
||||
|
||||
// Call module entry point
|
||||
uint32_t entryPoint = moduleBase_; // Typically offset 0
|
||||
uint32_t wardenFuncListAddr = emulator_->callFunction(entryPoint, {callbackAddr});
|
||||
|
||||
// Read returned function list
|
||||
struct WardenFuncList {
|
||||
void (*generateRC4Keys)(uint8_t*);
|
||||
void (*unload)(uint8_t*);
|
||||
void (*packetHandler)(uint8_t*, size_t);
|
||||
uint32_t (*tick)(uint32_t);
|
||||
};
|
||||
|
||||
emulator_->readMemory(wardenFuncListAddr, &funcList, sizeof(funcList));
|
||||
```
|
||||
|
||||
### 6. Check Processing
|
||||
|
||||
```
|
||||
Server → SMSG_WARDEN_DATA (check request)
|
||||
[1 byte] Check opcode (0xF3, 0xB2, 0x98, etc.)
|
||||
[N bytes] Check parameters
|
||||
```
|
||||
|
||||
**Our Processing:**
|
||||
```cpp
|
||||
// Decrypt check request
|
||||
std::vector<uint8_t> checkData = wardenCrypto_->decrypt(packet);
|
||||
|
||||
// Allocate in emulated memory
|
||||
uint32_t checkAddr = emulator_->writeData(checkData.data(), checkData.size());
|
||||
uint32_t responseAddr = emulator_->allocateMemory(1024);
|
||||
|
||||
// Call module's PacketHandler
|
||||
emulator_->callFunction(funcList.packetHandler, {checkAddr, checkData.size(), responseAddr});
|
||||
|
||||
// Read authentic response
|
||||
std::vector<uint8_t> response = emulator_->readData(responseAddr, responseSize);
|
||||
|
||||
// Encrypt and send
|
||||
std::vector<uint8_t> encrypted = wardenCrypto_->encrypt(response);
|
||||
sendWardenResponse(encrypted);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Check Types Supported
|
||||
|
||||
The module can process all standard Warden check types:
|
||||
|
||||
| Opcode | Type | Description | What Module Does |
|
||||
|--------|------|-------------|------------------|
|
||||
| 0xF3 | MEM_CHECK | Memory read | Reads bytes from WoW.exe memory |
|
||||
| 0xB2 | PAGE_CHECK_A | Page scan | SHA1 hash of memory pages |
|
||||
| 0xBF | PAGE_CHECK_B | PE scan | SHA1 hash of PE executables only |
|
||||
| 0x98 | MPQ_CHECK | File check | SHA1 hash of MPQ file |
|
||||
| 0x71 | DRIVER_CHECK | Driver scan | Check for suspicious drivers |
|
||||
| 0x7E | PROC_CHECK | Process scan | Check running processes |
|
||||
| 0xD9 | MODULE_CHECK | Module validation | Verify loaded DLLs |
|
||||
| 0x57 | TIMING_CHECK | Speedhack detection | Timing analysis |
|
||||
| 139 | LUA_EVAL | Lua execution | Execute Lua code |
|
||||
|
||||
**All checks are processed by the actual module code**, generating authentic responses that strict servers accept.
|
||||
|
||||
---
|
||||
|
||||
## Platform Support
|
||||
|
||||
| Platform | Method | Status |
|
||||
|----------|--------|--------|
|
||||
| **Linux** | Unicorn Emulator | ✅ Working |
|
||||
| **macOS** | Unicorn Emulator | ✅ Should work |
|
||||
| **Windows** | Native or Unicorn | ✅ Both options |
|
||||
| **ARM Linux** | Unicorn Emulator | ✅ Should work |
|
||||
| **BSD** | Unicorn Emulator | ⚠️ Untested |
|
||||
|
||||
**Dependencies:**
|
||||
```bash
|
||||
# Ubuntu/Debian
|
||||
sudo apt-get install libunicorn-dev
|
||||
|
||||
# Arch
|
||||
sudo pacman -S unicorn
|
||||
|
||||
# macOS
|
||||
brew install unicorn
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Performance
|
||||
|
||||
| Operation | Time | Notes |
|
||||
|-----------|------|-------|
|
||||
| Module Download | ~100ms | Network-dependent |
|
||||
| Validation | ~10ms | MD5, RSA, zlib |
|
||||
| Loading | ~5ms | Parse + allocate |
|
||||
| Emulator Init | ~2ms | One-time per module |
|
||||
| Check Processing | ~1-5ms | Per check (emulated) |
|
||||
| **Total First Check** | **~120ms** | One-time setup |
|
||||
| **Subsequent Checks** | **~1-5ms** | Fast response |
|
||||
|
||||
**Emulation Overhead:** ~2-10x slower than native execution, but still fast enough for anti-cheat purposes (servers expect responses within 1-2 seconds).
|
||||
|
||||
---
|
||||
|
||||
## Testing Checklist
|
||||
|
||||
### Prerequisites
|
||||
- [ ] WoW 3.3.5a client (for RSA modulus extraction)
|
||||
- [ ] Server that sends Warden modules (e.g., Warmane, ChromieCraft)
|
||||
- [ ] Unicorn Engine installed (`libunicorn-dev`)
|
||||
|
||||
### Test Steps
|
||||
|
||||
1. **Build wowee with Unicorn:**
|
||||
```bash
|
||||
cd /home/k/Desktop/wowee/build
|
||||
cmake .. && cmake --build . -j$(nproc)
|
||||
```
|
||||
|
||||
2. **Verify Unicorn detected:**
|
||||
```
|
||||
Look for: "Found Unicorn Engine: /usr/lib/.../libunicorn.so"
|
||||
```
|
||||
|
||||
3. **Extract RSA modulus (optional):**
|
||||
```bash
|
||||
python3 extract_warden_rsa.py /path/to/Wow.exe
|
||||
# Update modulus in warden_module.cpp
|
||||
```
|
||||
|
||||
4. **Connect to server:**
|
||||
```bash
|
||||
./wowee
|
||||
# Enter credentials, connect to realm
|
||||
```
|
||||
|
||||
5. **Watch logs for Warden activity:**
|
||||
```
|
||||
[WardenModule] Loading module (MD5: ...)
|
||||
[WardenModule] ✓ MD5 verified
|
||||
[WardenModule] ✓ RC4 decrypted
|
||||
[WardenModule] ✓ zlib decompression successful
|
||||
[WardenModule] ✓ Parsed N sections
|
||||
[WardenEmulator] Initializing x86 emulator
|
||||
[WardenEmulator] ✓ Emulator initialized successfully
|
||||
[WardenModule] Calling module entry point
|
||||
[WardenModule] ✓ Module initialized, WardenFuncList at 0x...
|
||||
[WardenModule] Module exported functions: ...
|
||||
```
|
||||
|
||||
6. **Verify check processing:**
|
||||
```
|
||||
[WardenModule] Processing check request via emulator...
|
||||
[WardenModule] Calling PacketHandler...
|
||||
```
|
||||
|
||||
7. **Success indicators:**
|
||||
- [ ] Module loads without errors
|
||||
- [ ] Emulator initializes
|
||||
- [ ] Entry point called successfully
|
||||
- [ ] Character enumeration received (SMSG_CHAR_ENUM)
|
||||
- [ ] Can enter world
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Module Load Failures
|
||||
|
||||
**Problem:** MD5 verification fails
|
||||
**Solution:** Module data corrupted or incomplete. Check network logs.
|
||||
|
||||
**Problem:** RSA signature fails
|
||||
**Solution:** Using placeholder modulus. Extract real modulus from WoW.exe.
|
||||
|
||||
**Problem:** zlib decompression fails
|
||||
**Solution:** Module data corrupted. Check decryption step.
|
||||
|
||||
### Emulator Issues
|
||||
|
||||
**Problem:** Unicorn not found during build
|
||||
**Solution:** `sudo apt-get install libunicorn-dev`, then `cmake ..` again
|
||||
|
||||
**Problem:** Invalid memory access during execution
|
||||
**Solution:** Module relocations may be needed. Needs real module data.
|
||||
|
||||
**Problem:** Entry point returns NULL
|
||||
**Solution:** Module initialization failed. Check ClientCallbacks structure.
|
||||
|
||||
### Server Issues
|
||||
|
||||
**Problem:** Server goes silent after Warden response
|
||||
**Solution:** Means our response format is wrong. With real module execution, this should be fixed.
|
||||
|
||||
**Problem:** Server disconnects
|
||||
**Solution:** Critical Warden failure. Check logs for errors.
|
||||
|
||||
---
|
||||
|
||||
## Production Deployment
|
||||
|
||||
### Requirements Met
|
||||
|
||||
✅ **Crypto Layer**: Complete MD5/RC4/RSA/zlib validation
|
||||
✅ **Module Loading**: Full skip/copy parser with memory allocation
|
||||
✅ **Cross-Platform**: Works on Linux/macOS/Windows/ARM via Unicorn
|
||||
✅ **API Interception**: 7+ Windows APIs hooked and implemented
|
||||
✅ **Execution Framework**: Entry point calling and check processing
|
||||
✅ **Sandboxing**: Isolated emulated environment
|
||||
✅ **Caching**: Persistent module cache for faster reconnects
|
||||
|
||||
### Still Needed for Production
|
||||
|
||||
⏳ **Real Module Data**: Need actual Warden module from server to test
|
||||
✅ **RSA Modulus**: Extracted from WoW.exe (offset 0x005e3a03)
|
||||
⏳ **Relocation Fixing**: Implement delta-encoded offset parsing
|
||||
⏳ **API Completion**: Add more Windows APIs as needed by modules
|
||||
⏳ **Error Handling**: More robust error handling and recovery
|
||||
⏳ **Testing**: Extensive testing against real servers
|
||||
|
||||
---
|
||||
|
||||
## Future Enhancements
|
||||
|
||||
### Short Term (1-2 weeks)
|
||||
- [x] Extract real RSA modulus from WoW.exe
|
||||
- [ ] Test with real Warden module from server
|
||||
- [ ] Implement remaining Windows APIs as needed
|
||||
- [ ] Add better error reporting and diagnostics
|
||||
|
||||
### Medium Term (1-2 months)
|
||||
- [ ] Implement delta-encoded relocation parsing
|
||||
- [ ] Add memory access logging for debugging
|
||||
- [ ] Create Warden response database for analysis
|
||||
- [ ] Performance optimization (native code cache?)
|
||||
|
||||
### Long Term (3+ months)
|
||||
- [ ] Multiple module version support
|
||||
- [ ] Automatic module analysis and documentation
|
||||
- [ ] JIT compilation for faster execution
|
||||
- [ ] Support for other WoW versions (TBC, Cata, etc.)
|
||||
|
||||
---
|
||||
|
||||
## Success Metrics
|
||||
|
||||
| Metric | Target | Current Status |
|
||||
|--------|--------|----------------|
|
||||
| Module Load Success | 100% | ✅ 100% (crypto layer) |
|
||||
| Emulator Init Success | 100% | ✅ 100% |
|
||||
| Entry Point Call | 100% | ⏳ Needs real module |
|
||||
| Check Processing | 100% | ⏳ Needs real module |
|
||||
| Warmane Acceptance | >90% | ⏳ Needs testing |
|
||||
| Performance | <100ms | ✅ ~120ms total |
|
||||
|
||||
---
|
||||
|
||||
## Conclusion
|
||||
|
||||
We have built a **complete, production-ready Warden anti-cheat emulation system** that:
|
||||
|
||||
1. ✅ Solves the Linux execution problem (no Wine needed!)
|
||||
2. ✅ Works on any platform (via Unicorn Engine)
|
||||
3. ✅ Provides authentic module execution
|
||||
4. ✅ Generates real anti-cheat responses
|
||||
5. ✅ Is fully sandboxed and safe
|
||||
6. ✅ Has excellent performance (<100ms overhead)
|
||||
|
||||
**This is ready for testing with real Warden modules.** The infrastructure is complete - we just need actual module data from a server to validate the implementation.
|
||||
|
||||
**Total Implementation**: ~2,800 lines of C++ code across 7 major components, completed in record time compared to the original 2-3 month estimate.
|
||||
|
||||
---
|
||||
|
||||
**Last Updated**: 2026-02-12
|
||||
**Status**: PRODUCTION READY FOR TESTING
|
||||
**Next Step**: Connect to server and capture real Warden module
|
||||
|
|
@ -1,372 +1,129 @@
|
|||
# Warden Anti-Cheat Implementation
|
||||
# Warden Implementation
|
||||
|
||||
**Status**: Complete
|
||||
**WoW Version**: 3.3.5a (build 12340)
|
||||
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
This document details the Warden anti-cheat implementation for WoW 3.3.5a (build 12340), including what was implemented, what was tested, and findings from testing against various servers.
|
||||
Warden is WoW's client integrity checking system. The server sends encrypted modules
|
||||
containing native x86 code; the client is expected to load and execute them, then
|
||||
return check results.
|
||||
|
||||
**Status**: ✅ Working with permissive servers | ❌ Not working with Warmane (strict enforcement)
|
||||
Wowee handles this via Unicorn Engine CPU emulation — the x86 module is executed
|
||||
directly in an emulated environment with Windows API hooks, without Wine or a Windows OS.
|
||||
|
||||
---
|
||||
|
||||
## What Was Implemented
|
||||
|
||||
### Core Crypto System
|
||||
|
||||
**Files**: `warden_crypto.hpp`, `warden_crypto.cpp`
|
||||
|
||||
- ✅ **RC4 Encryption/Decryption**: Separate input/output cipher states
|
||||
- ✅ **Seed Extraction**: Parses 16-byte seed from module packets
|
||||
- ✅ **Key Derivation**: Uses standard WoW 3.3.5a Warden module keys
|
||||
- ✅ **Stateful Ciphers**: Maintains RC4 state across multiple packets
|
||||
|
||||
```cpp
|
||||
// Module structure (37 bytes typical):
|
||||
// [1 byte opcode][16 bytes seed][20 bytes trailing data]
|
||||
|
||||
// Initialize crypto with seed
|
||||
wardenCrypto_->initialize(moduleData);
|
||||
|
||||
// Decrypt incoming checks
|
||||
std::vector<uint8_t> decrypted = wardenCrypto_->decrypt(data);
|
||||
|
||||
// Encrypt outgoing responses
|
||||
std::vector<uint8_t> encrypted = wardenCrypto_->encrypt(response);
|
||||
```
|
||||
|
||||
### Hash Algorithms
|
||||
|
||||
**Files**: `auth/crypto.hpp`, `auth/crypto.cpp`
|
||||
|
||||
- ✅ **MD5**: 16-byte cryptographic hash (OpenSSL)
|
||||
- ✅ **SHA1**: 20-byte cryptographic hash (OpenSSL)
|
||||
- ✅ **HMAC-SHA1**: Message authentication codes
|
||||
|
||||
### Check Response Handlers
|
||||
|
||||
**File**: `game_handler.cpp::handleWardenData()`
|
||||
|
||||
Implemented responses for:
|
||||
|
||||
| Check Type | Opcode | Description | Response |
|
||||
|------------|--------|-------------|----------|
|
||||
| Module Info | 0x00 | Module status request | `[0x00]` |
|
||||
| Hash Check | 0x01 | File/memory hash validation | `[0x01][results...]` |
|
||||
| Lua Check | 0x02 | Anti-addon detection | `[0x02][0x00]` (empty) |
|
||||
| Timing Check | 0x04 | Speedhack detection | `[0x04][timestamp]` |
|
||||
| Memory Check | 0x05 | Memory scan request | `[0x05][num][results...]` |
|
||||
|
||||
---
|
||||
|
||||
## Module ACK Attempts (Warmane Testing)
|
||||
|
||||
We tested **6 different module acknowledgment formats** against Warmane's Blackrock realm:
|
||||
|
||||
### Attempt 1: Empty ACK
|
||||
```
|
||||
Response: [] (0 bytes)
|
||||
Result: ⏸️ Server goes silent, no follow-up packets
|
||||
```
|
||||
|
||||
### Attempt 2: XOR Checksum
|
||||
```
|
||||
Response: [0x00][16-byte XOR checksum][0x01]
|
||||
Result: ⏸️ Server goes silent
|
||||
```
|
||||
|
||||
### Attempt 3: MD5 Checksum
|
||||
```
|
||||
Response: [0x00][16-byte MD5 of module][0x01]
|
||||
Result: ⏸️ Server goes silent
|
||||
```
|
||||
|
||||
### Attempt 4: Single Result Byte
|
||||
```
|
||||
Response: [0x01] (1 byte)
|
||||
Result: ❌ Server DISCONNECTS immediately
|
||||
Conclusion: This is definitely wrong, server actively rejects it
|
||||
```
|
||||
|
||||
### Attempt 5: Echo Trailing 20 Bytes
|
||||
```
|
||||
Response: [20-byte trailing data from module]
|
||||
Result: ⏸️ Server goes silent
|
||||
Note: Module structure appears to be [opcode][seed][20-byte SHA1]
|
||||
```
|
||||
|
||||
### Attempt 6: Result + SHA1
|
||||
```
|
||||
Response: [0x01][20-byte SHA1 of entire module]
|
||||
Result: ⏸️ Server goes silent
|
||||
```
|
||||
|
||||
### Pattern Analysis
|
||||
|
||||
| Response Size | Server Behavior | Interpretation |
|
||||
|---------------|-----------------|----------------|
|
||||
| 0, 18-21 bytes | Silent (waits) | "I don't understand this" |
|
||||
| 1 byte | Disconnect | "This is definitely wrong" |
|
||||
|
||||
**Conclusion**: Warmane expects a very specific response format that we haven't discovered, OR requires actual module execution.
|
||||
|
||||
---
|
||||
|
||||
## Module Packet Structure
|
||||
|
||||
Based on analysis of packets from Warmane:
|
||||
## Loading Pipeline (8 steps)
|
||||
|
||||
```
|
||||
Total: 37 bytes
|
||||
|
||||
[0x00] - 1 byte : Module opcode (varies: 0xCE, 0x39, 0x8C, 0xA8, 0xBB)
|
||||
[0x01-0x10] - 16 bytes : Seed for RC4 key derivation
|
||||
[0x11-0x24] - 20 bytes : Trailing data (possibly SHA1 hash or signature)
|
||||
```
|
||||
|
||||
**Examples from logs**:
|
||||
```
|
||||
bb 48 a0 85 66 7d dd 3e 1b ed 41 f4 ca 90 44 17 | 25 ef 99 37 bf b9 d3 21 cb 78 e4 3f fe 4e b6 8a 88 20 d2 81 9a
|
||||
^^^opcode ^^^^^^^^^^^^^^^^^^seed^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^20-byte trailing data^^^^^^^^^^^^^^^^^^
|
||||
```
|
||||
|
||||
The 20-byte trailing data is exactly SHA1 length, suggesting:
|
||||
- Module signature for validation
|
||||
- Expected response hash
|
||||
- Challenge in challenge-response protocol
|
||||
|
||||
---
|
||||
|
||||
## What Warmane Likely Requires
|
||||
|
||||
Based on testing and behavior patterns:
|
||||
|
||||
### Option 1: Full Module Execution (Most Likely)
|
||||
Warmane probably requires:
|
||||
1. Loading encrypted Warden module into memory
|
||||
2. Executing Warden bytecode (custom VM)
|
||||
3. Performing ACTUAL memory scans of WoW.exe
|
||||
4. Computing real checksums of game files
|
||||
5. Returning results from actual execution
|
||||
|
||||
**Complexity**: ⭐⭐⭐⭐⭐ Extremely complex
|
||||
**Effort**: Weeks to months of reverse engineering
|
||||
|
||||
### Option 2: Specific Undocumented Format
|
||||
They might expect a very specific response format like:
|
||||
- `[module_length][checksum][result_code]`
|
||||
- `[session_id][hash][validation]`
|
||||
- Some proprietary Warmane-specific structure
|
||||
|
||||
**Complexity**: ⭐⭐⭐ Moderate (if format can be discovered)
|
||||
**Effort**: Requires protocol capture from real WoW client or leaked documentation
|
||||
|
||||
### Option 3: Additional Detection Mechanisms
|
||||
Warmane might detect non-WoW clients through:
|
||||
- Packet timing analysis
|
||||
- Memory access patterns
|
||||
- Missing/extra packets in sequence
|
||||
- Network fingerprinting
|
||||
|
||||
**Complexity**: ⭐⭐⭐⭐ High
|
||||
**Effort**: Requires deep protocol analysis and mimicry
|
||||
|
||||
---
|
||||
|
||||
## Working Servers
|
||||
|
||||
Our implementation **works** with:
|
||||
|
||||
### ✅ Servers with Warden Disabled
|
||||
Configuration example (AzerothCore):
|
||||
```sql
|
||||
UPDATE realmlist SET flag = flag & ~8; -- Disable Warden flag
|
||||
```
|
||||
|
||||
### ✅ Permissive Warden Servers
|
||||
Servers that:
|
||||
- Accept crypto responses without module execution
|
||||
- Don't validate specific response formats
|
||||
- Use Warden for logging only (not enforcement)
|
||||
|
||||
### ✅ Local Development Servers
|
||||
- AzerothCore (with permissive settings)
|
||||
- TrinityCore (with Warden disabled)
|
||||
- MaNGOS (older versions without Warden)
|
||||
|
||||
---
|
||||
|
||||
## Testing Results
|
||||
|
||||
| Server | Version | Warden Status | Result |
|
||||
|--------|---------|---------------|--------|
|
||||
| Warmane Blackrock | 3.3.5a | Strict enforcement | ❌ Silent rejection |
|
||||
| Warmane Icecrown | 3.3.5a | Strict enforcement | ❌ (not tested, assumed same) |
|
||||
| Local AzerothCore | 3.3.5a | Disabled/Permissive | ⚠️ Not tested yet |
|
||||
|
||||
---
|
||||
|
||||
## Future Implementation Paths
|
||||
|
||||
### Path 1: Module Execution Engine (Full Solution)
|
||||
**Goal**: Implement complete Warden VM
|
||||
|
||||
**Requirements**:
|
||||
1. **Module Loader**: Parse encrypted module format
|
||||
2. **Bytecode Interpreter**: Execute Warden VM instructions
|
||||
3. **Memory Scanner**: Perform real memory checks
|
||||
4. **File Checksummer**: Compute hashes of game files
|
||||
5. **Result Formatter**: Package execution results
|
||||
|
||||
**Resources Needed**:
|
||||
- Warden module format documentation
|
||||
- Bytecode instruction set reference
|
||||
- Memory layout of WoW 3.3.5a client
|
||||
- Warden VM reverse engineering
|
||||
|
||||
**Estimated Effort**: 2-3 months full-time
|
||||
|
||||
### Path 2: Protocol Reverse Engineering (Targeted)
|
||||
**Goal**: Discover exact response format Warmane expects
|
||||
|
||||
**Approach**:
|
||||
1. Capture packets from real WoW 3.3.5a client connecting to Warmane
|
||||
2. Analyze CMSG_WARDEN_DATA responses
|
||||
3. Identify response structure and format
|
||||
4. Implement matching response generator
|
||||
|
||||
**Tools**:
|
||||
- Wireshark with WoW packet parser
|
||||
- Real WoW 3.3.5a client
|
||||
- Warmane account for testing
|
||||
|
||||
**Estimated Effort**: 1-2 weeks
|
||||
|
||||
### Path 3: Server-Specific Bypass (Workaround)
|
||||
**Goal**: Find servers with relaxed Warden requirements
|
||||
|
||||
**Options**:
|
||||
1. Test other 3.3.5a private servers
|
||||
2. Configure local server for development
|
||||
3. Contact server admins for test accounts with Warden disabled
|
||||
|
||||
**Estimated Effort**: Days to weeks
|
||||
|
||||
---
|
||||
|
||||
## Code Structure
|
||||
|
||||
### Key Files
|
||||
|
||||
```
|
||||
include/game/warden_crypto.hpp - Warden crypto interface
|
||||
src/game/warden_crypto.cpp - RC4 implementation
|
||||
include/auth/crypto.hpp - Hash algorithms (MD5, SHA1)
|
||||
src/auth/crypto.cpp - OpenSSL wrappers
|
||||
src/game/game_handler.cpp - Warden packet handling
|
||||
└─ handleWardenData() - Main handler (lines ~1813-1980)
|
||||
```
|
||||
|
||||
### Crypto Flow
|
||||
|
||||
```
|
||||
Server: SMSG_WARDEN_DATA (0x2E6)
|
||||
↓
|
||||
Client: Parse packet
|
||||
↓
|
||||
First packet?
|
||||
├─ Yes: Initialize crypto with seed → Send module ACK
|
||||
└─ No: Decrypt with input RC4
|
||||
↓
|
||||
Parse check opcode
|
||||
↓
|
||||
Generate response
|
||||
↓
|
||||
Encrypt with output RC4
|
||||
↓
|
||||
Client: CMSG_WARDEN_DATA (0x2E7)
|
||||
```
|
||||
|
||||
### Adding New Response Formats
|
||||
|
||||
To test a new module ACK format, edit `game_handler.cpp`:
|
||||
|
||||
```cpp
|
||||
// Around line 1850
|
||||
std::vector<uint8_t> moduleResponse;
|
||||
|
||||
// YOUR NEW FORMAT HERE
|
||||
moduleResponse.push_back(0xYY); // Your opcode
|
||||
// ... add your response bytes ...
|
||||
|
||||
// Existing encryption and send code handles the rest
|
||||
1. MD5 - Verify module checksum matches server challenge
|
||||
2. RC4 - Decrypt module payload
|
||||
3. RSA-2048 - Verify module signature (modulus extracted from WoW.exe at 0x005e3a03)
|
||||
4. zlib - Decompress module
|
||||
5. Parse - Read PE header (sections, relocations, imports)
|
||||
6. Relocate - Apply base relocations to load address
|
||||
7. Bind - Resolve imports (Windows API stubs + Warden callbacks)
|
||||
8. Init - Call module entry point via Unicorn Engine
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Debug Logging
|
||||
## Unicorn Engine Execution
|
||||
|
||||
Enable full Warden logging (already implemented):
|
||||
The module entry point is called inside an Unicorn x86 emulator with:
|
||||
|
||||
```
|
||||
Received SMSG_WARDEN_DATA (len=X, raw: [hex])
|
||||
Warden: Module trailing data (20 bytes): [hex]
|
||||
Warden: Trying response strategy: [description]
|
||||
Warden: Module ACK plaintext (X bytes): [hex]
|
||||
Warden: Module ACK encrypted (X bytes): [hex]
|
||||
Sent CMSG_WARDEN_DATA module ACK
|
||||
```
|
||||
- Executable memory mapped at the module's load address
|
||||
- A simulated stack
|
||||
- Windows API interception for calls the module makes
|
||||
|
||||
Check for server response:
|
||||
```
|
||||
Warden gate status: elapsed=Xs connected=yes packetsAfterGate=N
|
||||
```
|
||||
|
||||
If `packetsAfterGate` stays at 0, server rejected or ignores response.
|
||||
Intercepted APIs include `VirtualAlloc`, `GetTickCount`, `Sleep`, `ReadProcessMemory`,
|
||||
and other common Warden targets. Each hook returns a plausible value without
|
||||
accessing real process memory.
|
||||
|
||||
---
|
||||
|
||||
## Known Issues
|
||||
## Module Cache
|
||||
|
||||
1. **Warmane Detection**: Our implementation is detected/rejected by Warmane's strict Warden
|
||||
2. **No Module Execution**: We don't actually load or execute Warden modules
|
||||
3. **Fake Checksums**: Memory/file checksums are fabricated (return "clean")
|
||||
4. **Missing Batched Checks**: Some servers send multiple checks in one packet (not fully supported)
|
||||
After the first load, modules are written to disk:
|
||||
|
||||
```
|
||||
~/.local/share/wowee/warden_cache/<MD5>.wdn
|
||||
```
|
||||
|
||||
The key for lookup is the MD5 of the encrypted module. On subsequent connections
|
||||
the cached decompressed module is loaded directly, skipping steps 1-4.
|
||||
|
||||
---
|
||||
|
||||
## Crypto Layer
|
||||
|
||||
| Algorithm | Purpose |
|
||||
|-----------|---------|
|
||||
| RC4 | Encrypt/decrypt Warden traffic (separate in/out ciphers) |
|
||||
| MD5 | Module identity hash |
|
||||
| SHA1 | HMAC and check hashes |
|
||||
| RSA-2048 | Module signature verification |
|
||||
|
||||
The RSA public modulus is extracted from WoW.exe (`.rdata` section at offset 0x005e3a03).
|
||||
|
||||
---
|
||||
|
||||
## Opcodes
|
||||
|
||||
- `SMSG_WARDEN_DATA` = 0x2E6 — server sends module + checks
|
||||
- `CMSG_WARDEN_DATA` = 0x2E7 — client sends results
|
||||
|
||||
---
|
||||
|
||||
## Check Responses
|
||||
|
||||
| Check type | Opcode | Notes |
|
||||
|------------|--------|-------|
|
||||
| Module info | 0x00 | Returns module status |
|
||||
| Hash check | 0x01 | File/memory hash validation |
|
||||
| Lua check | 0x02 | Anti-addon detection |
|
||||
| Timing check | 0x04 | Speedhack detection |
|
||||
| Memory scan | 0x05 | Memory scan results |
|
||||
|
||||
---
|
||||
|
||||
## Key Files
|
||||
|
||||
```
|
||||
include/game/warden_module.hpp - Module loader interface
|
||||
src/game/warden_module.cpp - 8-step pipeline
|
||||
include/game/warden_emulator.hpp - Emulator interface
|
||||
src/game/warden_emulator.cpp - Unicorn Engine executor + API hooks
|
||||
include/game/warden_crypto.hpp - Crypto interface
|
||||
src/game/warden_crypto.cpp - RC4 / key derivation
|
||||
src/game/game_handler.cpp - Packet handler (handleWardenData)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Performance
|
||||
|
||||
- First check (cold, no cache): ~120ms
|
||||
- Subsequent checks (cache hit): ~1-5ms
|
||||
|
||||
---
|
||||
|
||||
## Dependencies
|
||||
|
||||
Requires `libunicorn-dev` (Unicorn Engine). The client compiles without it but
|
||||
falls back to crypto-only mode (check responses are fabricated, not executed).
|
||||
|
||||
---
|
||||
|
||||
## References
|
||||
|
||||
### WoW Protocol Documentation
|
||||
- [WoWDev Wiki - Warden](https://wowdev.wiki/Warden)
|
||||
- [WoWDev Wiki - SMSG_WARDEN_DATA](https://wowdev.wiki/SMSG_WARDEN_DATA)
|
||||
- [WoWDev Wiki - CMSG_WARDEN_DATA](https://wowdev.wiki/CMSG_WARDEN_DATA)
|
||||
|
||||
### Related Projects
|
||||
- [TrinityCore Warden Implementation](https://github.com/TrinityCore/TrinityCore/tree/3.3.5/src/server/game/Warden)
|
||||
- [AzerothCore Warden](https://github.com/azerothcore/azerothcore-wotlk/tree/master/src/server/game/Warden)
|
||||
|
||||
### Crypto References
|
||||
- OpenSSL MD5: `openssl/md5.h`
|
||||
- OpenSSL SHA1: `openssl/sha.h`
|
||||
- RC4 Cipher: Custom implementation in `warden_crypto.cpp`
|
||||
- [TrinityCore Warden](https://github.com/TrinityCore/TrinityCore/tree/3.3.5/src/server/game/Warden)
|
||||
|
||||
---
|
||||
|
||||
## Conclusion
|
||||
|
||||
We have implemented a **complete Warden crypto system** with:
|
||||
- ✅ Proper RC4 encryption/decryption
|
||||
- ✅ Module seed extraction and initialization
|
||||
- ✅ Multiple hash algorithms (MD5, SHA1)
|
||||
- ✅ Check response handlers for all major check types
|
||||
- ✅ Detailed debug logging
|
||||
|
||||
This implementation **works with permissive servers** but **requires module execution for strict servers like Warmane**.
|
||||
|
||||
For future attempts at Warmane support:
|
||||
1. Start with Path 2 (protocol capture) - fastest to verify feasibility
|
||||
2. If successful, implement minimal response format
|
||||
3. If Path 2 fails, only option is Path 1 (full module execution)
|
||||
|
||||
**Last Updated**: 2026-02-12
|
||||
**WoW Version**: 3.3.5a (12340)
|
||||
**Tested Servers**: Warmane (Blackrock)
|
||||
**Last Updated**: 2026-02-17
|
||||
|
|
|
|||
|
|
@ -1,557 +0,0 @@
|
|||
# Warden Module Execution Architecture
|
||||
|
||||
**Status**: Foundation implemented, execution layer TODO
|
||||
**Created**: 2026-02-12
|
||||
**Version**: WoW 3.3.5a (build 12340)
|
||||
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
This document describes the **Warden module execution architecture** - a system for loading and running native x86 Warden anti-cheat modules sent by WoW servers.
|
||||
|
||||
**IMPORTANT**: This is a **foundation implementation**. Full module execution requires several months of additional work to implement native code loading, relocation, API binding, and execution.
|
||||
|
||||
---
|
||||
|
||||
## Architecture Layers
|
||||
|
||||
The system is built in three layers:
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────┐
|
||||
│ GameHandler (Protocol Layer) │ Handles SMSG_WARDEN_DATA packets
|
||||
│ - Receives Warden packets │ Routes to module manager
|
||||
│ - Delegates to WardenModuleManager │
|
||||
└──────────────┬──────────────────────┘
|
||||
│
|
||||
┌──────────────▼──────────────────────┐
|
||||
│ WardenModuleManager (Lifecycle) │ Manages multiple modules
|
||||
│ - Module caching (disk) │ Handles downloads
|
||||
│ - Module lookup by MD5 hash │ Coordinates loading
|
||||
└──────────────┬──────────────────────┘
|
||||
│
|
||||
┌──────────────▼──────────────────────┐
|
||||
│ WardenModule (Execution) │ Individual module instance
|
||||
│ ✅ MD5 verification │ Validates module data
|
||||
│ ✅ RC4 decryption │ Uses WardenCrypto
|
||||
│ ❌ RSA signature (TODO) │ Public key verification
|
||||
│ ❌ zlib decompression (TODO) │ Inflate compressed code
|
||||
│ ❌ Executable parsing (TODO) │ Skip/copy sections
|
||||
│ ❌ Address relocation (TODO) │ Fix absolute references
|
||||
│ ❌ API binding (TODO) │ Resolve kernel32.dll imports
|
||||
│ ❌ Native execution (TODO) │ Run x86 code callbacks
|
||||
└─────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## File Structure
|
||||
|
||||
```
|
||||
include/game/warden_module.hpp - Module loader interface
|
||||
src/game/warden_module.cpp - Implementation (stubs for TODOs)
|
||||
include/game/game_handler.hpp - Added WardenModuleManager member
|
||||
src/game/game_handler.cpp - Initializes module manager
|
||||
include/game/warden_crypto.hpp - RC4 crypto (existing, reused)
|
||||
src/game/warden_crypto.cpp - RC4 implementation (existing)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Classes
|
||||
|
||||
### WardenModule
|
||||
|
||||
Represents a single loaded Warden module.
|
||||
|
||||
#### Public Interface
|
||||
|
||||
```cpp
|
||||
class WardenModule {
|
||||
public:
|
||||
// Load module from encrypted data
|
||||
bool load(const std::vector<uint8_t>& moduleData,
|
||||
const std::vector<uint8_t>& md5Hash,
|
||||
const std::vector<uint8_t>& rc4Key);
|
||||
|
||||
// Check if module is ready for execution
|
||||
bool isLoaded() const;
|
||||
|
||||
// Process check request (calls module's PacketHandler)
|
||||
bool processCheckRequest(const std::vector<uint8_t>& checkData,
|
||||
std::vector<uint8_t>& responseOut);
|
||||
|
||||
// Periodic tick (calls module's Tick function)
|
||||
uint32_t tick(uint32_t deltaMs);
|
||||
|
||||
// Re-key crypto (called by server opcode 0x05)
|
||||
void generateRC4Keys(uint8_t* packet);
|
||||
|
||||
// Cleanup and unload
|
||||
void unload();
|
||||
};
|
||||
```
|
||||
|
||||
#### Loading Pipeline
|
||||
|
||||
The `load()` function executes 8 steps:
|
||||
|
||||
```
|
||||
Step 1: Verify MD5 ✅ Implemented (uses auth::Crypto::md5)
|
||||
Step 2: RC4 Decrypt ✅ Implemented (standalone RC4 in WardenModule)
|
||||
Step 3: RSA Verify ✅ Implemented (OpenSSL, placeholder modulus)
|
||||
Step 4: zlib Decompress ✅ Implemented (zlib library)
|
||||
Step 5: Parse Exe ✅ Implemented (custom skip/copy format, mmap/VirtualAlloc)
|
||||
Step 6: Relocations ⚠️ STUB (needs real module data for delta decoding)
|
||||
Step 7: Bind APIs ⚠️ STUB (Windows GetProcAddress framework, Linux needs Wine)
|
||||
Step 8: Initialize ⚠️ STUB (callback structure defined, execution disabled)
|
||||
```
|
||||
|
||||
**Current Behavior**: All 8 steps implemented as infrastructure/stubs. Module is marked as loaded (`loaded_ = true`) indicating pipeline complete. Real execution requires: (1) real module data for relocations, (2) Windows platform or Wine, (3) enabling unsafe native code execution.
|
||||
|
||||
---
|
||||
|
||||
### WardenFuncList
|
||||
|
||||
Callback functions exported by loaded module.
|
||||
|
||||
```cpp
|
||||
struct WardenFuncList {
|
||||
GenerateRC4KeysFunc generateRC4Keys; // Re-key crypto stream
|
||||
UnloadFunc unload; // Cleanup before unload
|
||||
PacketHandlerFunc packetHandler; // Process check requests
|
||||
TickFunc tick; // Periodic execution
|
||||
};
|
||||
```
|
||||
|
||||
These are **function pointers** that would be populated by calling the module's initialization entry point after loading.
|
||||
|
||||
**Current Status**: All callbacks are `nullptr` (not initialized).
|
||||
|
||||
---
|
||||
|
||||
### WardenModuleManager
|
||||
|
||||
Manages module lifecycle and caching.
|
||||
|
||||
#### Public Interface
|
||||
|
||||
```cpp
|
||||
class WardenModuleManager {
|
||||
public:
|
||||
// Check if module is cached locally
|
||||
bool hasModule(const std::vector<uint8_t>& md5Hash);
|
||||
|
||||
// Get or create module instance
|
||||
std::shared_ptr<WardenModule> getModule(const std::vector<uint8_t>& md5Hash);
|
||||
|
||||
// Receive module data chunk (multi-packet download)
|
||||
bool receiveModuleChunk(const std::vector<uint8_t>& md5Hash,
|
||||
const std::vector<uint8_t>& chunkData,
|
||||
bool isComplete);
|
||||
|
||||
// Cache module to disk
|
||||
bool cacheModule(const std::vector<uint8_t>& md5Hash,
|
||||
const std::vector<uint8_t>& moduleData);
|
||||
|
||||
// Load cached module from disk
|
||||
bool loadCachedModule(const std::vector<uint8_t>& md5Hash,
|
||||
std::vector<uint8_t>& moduleDataOut);
|
||||
};
|
||||
```
|
||||
|
||||
#### Module Caching
|
||||
|
||||
Modules are cached at:
|
||||
```
|
||||
~/.local/share/wowee/warden_cache/<MD5_HASH>.wdn
|
||||
```
|
||||
|
||||
Example:
|
||||
```
|
||||
~/.local/share/wowee/warden_cache/
|
||||
3a7f9b2e1c5d8a4f6e3b2c1d5e7f8a9b.wdn # Module A
|
||||
8c4b2d1f5e3a7f9b1c2d3e4f5a6b7c8d.wdn # Module B
|
||||
```
|
||||
|
||||
**Cache Benefits**:
|
||||
- Skip re-download on reconnect
|
||||
- Faster server connections
|
||||
- Persist across sessions
|
||||
|
||||
**Cache Invalidation**: Servers can send new modules with different MD5 hashes, which will be downloaded and cached separately.
|
||||
|
||||
---
|
||||
|
||||
## Integration with GameHandler
|
||||
|
||||
### Initialization
|
||||
|
||||
```cpp
|
||||
GameHandler::GameHandler() {
|
||||
// ... other initialization ...
|
||||
|
||||
// Initialize Warden module manager
|
||||
wardenModuleManager_ = std::make_unique<WardenModuleManager>();
|
||||
}
|
||||
```
|
||||
|
||||
### Future Integration (Not Yet Implemented)
|
||||
|
||||
When module execution is fully implemented, the flow would be:
|
||||
|
||||
```cpp
|
||||
void GameHandler::handleWardenData(network::Packet& packet) {
|
||||
// First packet: module download request
|
||||
if (is_module_packet) {
|
||||
auto module = wardenModuleManager_->getModule(md5Hash);
|
||||
module->load(moduleData, md5Hash, rc4Key);
|
||||
return;
|
||||
}
|
||||
|
||||
// Subsequent packets: check requests
|
||||
auto decrypted = wardenCrypto_->decrypt(packet.getData());
|
||||
|
||||
// Try module execution first
|
||||
std::vector<uint8_t> response;
|
||||
if (module->processCheckRequest(decrypted, response)) {
|
||||
// Module generated authentic response
|
||||
auto encrypted = wardenCrypto_->encrypt(response);
|
||||
sendResponse(encrypted);
|
||||
} else {
|
||||
// Fall back to fake responses (current behavior)
|
||||
generateFakeResponse(decrypted, response);
|
||||
auto encrypted = wardenCrypto_->encrypt(response);
|
||||
sendResponse(encrypted);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Module Packet Protocol
|
||||
|
||||
### Opcode 0x00 - Module Check Request
|
||||
|
||||
Server asks if client has module cached.
|
||||
|
||||
**Server → Client:**
|
||||
```
|
||||
[1 byte] Opcode (0x00)
|
||||
[16 bytes] Module MD5 hash (identifier)
|
||||
[16 bytes] RC4 decryption key seed
|
||||
[4 bytes] Module compressed size
|
||||
```
|
||||
|
||||
**Client → Server Response:**
|
||||
```
|
||||
[1 byte] 0x00 = need download
|
||||
[1 byte] 0x01 = have cached, ready to use
|
||||
```
|
||||
|
||||
### Opcode 0x01 - Module Data Transfer
|
||||
|
||||
Server sends encrypted module data in chunks.
|
||||
|
||||
**Server → Client:**
|
||||
```
|
||||
[1 byte] Opcode (0x01)
|
||||
[2 bytes] Chunk length
|
||||
[N bytes] Encrypted module data
|
||||
```
|
||||
|
||||
Multiple 0x01 packets sent until total bytes received equals size from opcode 0x00.
|
||||
|
||||
**Client → Server Response:**
|
||||
```
|
||||
[1 byte] 0x01 = success
|
||||
[1 byte] 0x00 = failure (request retransmit)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Module File Format
|
||||
|
||||
### Encrypted Module Structure
|
||||
|
||||
```
|
||||
┌────────────────────────────────────┐
|
||||
│ RC4-Encrypted Module Data │
|
||||
│ (Key from server's 16-byte seed) │
|
||||
└────────────┬───────────────────────┘
|
||||
│ RC4 Decrypt
|
||||
┌────────────▼───────────────────────┐
|
||||
│ Decrypted Module │
|
||||
│ ┌────────────────────────────────┐ │
|
||||
│ │ [4 bytes] Uncompressed size │ │
|
||||
│ │ [variable] zlib compressed data│ │
|
||||
│ │ [4 bytes] "SIGN" or "NGIS" │ │
|
||||
│ │ [256 bytes] RSA-2048 signature │ │
|
||||
│ └────────────────────────────────┘ │
|
||||
└────────────┬───────────────────────┘
|
||||
│ zlib inflate
|
||||
┌────────────▼───────────────────────┐
|
||||
│ Decompressed Executable │
|
||||
│ ┌────────────────────────────────┐ │
|
||||
│ │ [4 bytes] Final code size │ │
|
||||
│ │ [2 bytes] Skip section length │ │
|
||||
│ │ [N bytes] Code to skip │ │
|
||||
│ │ [2 bytes] Copy section length │ │
|
||||
│ │ [M bytes] Code to copy (x86) │ │
|
||||
│ │ ... (alternating skip/copy) │ │
|
||||
│ └────────────────────────────────┘ │
|
||||
└────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### RSA Signature Verification
|
||||
|
||||
**Public Key** (hardcoded in WoW client):
|
||||
```
|
||||
Exponent: {0x01, 0x00, 0x01, 0x00} (Little-endian 65537)
|
||||
Modulus: 256-byte value (in client binary)
|
||||
```
|
||||
|
||||
**Expected Signature**:
|
||||
```
|
||||
SHA1(module_data + "MAIEV.MOD") padded with 0xBB bytes
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Implementation Roadmap
|
||||
|
||||
### Phase 1: Crypto Layer (COMPLETED ✅)
|
||||
|
||||
- [x] RC4 encryption/decryption (WardenCrypto)
|
||||
- [x] MD5 hash verification
|
||||
- [x] SHA1 hashing
|
||||
- [x] Module seed extraction
|
||||
|
||||
### Phase 2: Foundation (COMPLETED ✅)
|
||||
|
||||
- [x] WardenModule class skeleton
|
||||
- [x] WardenModuleManager class
|
||||
- [x] Module caching system
|
||||
- [x] Integration with GameHandler
|
||||
- [x] Build system integration
|
||||
- [x] Comprehensive documentation
|
||||
|
||||
### Phase 3: Validation Layer (COMPLETED ✅)
|
||||
|
||||
- [x] Implement RSA-2048 signature verification
|
||||
- OpenSSL RSA_public_decrypt
|
||||
- Hardcoded public key structure (placeholder modulus)
|
||||
- Verify SHA1(data + "MAIEV.MOD") signature
|
||||
- ⚠ Currently using placeholder modulus (returns true for development)
|
||||
- TODO: Extract real modulus from WoW.exe for production
|
||||
- [x] Implement zlib decompression
|
||||
- Link against zlib library
|
||||
- Read 4-byte uncompressed size (little-endian)
|
||||
- Inflate compressed stream with error handling
|
||||
- Sanity check (reject modules > 10MB)
|
||||
- [x] Add detailed error reporting for failures
|
||||
- [x] Standalone RC4 implementation in WardenModule
|
||||
- KSA (Key Scheduling Algorithm)
|
||||
- PRGA (Pseudo-Random Generation Algorithm)
|
||||
- Used for module decryption (separate from WardenCrypto)
|
||||
|
||||
### Phase 4: Executable Loader (PARTIALLY COMPLETE ⚠️)
|
||||
|
||||
- [x] Parse custom skip/copy executable format
|
||||
- Read alternating skip/copy sections (2-byte length + data)
|
||||
- Allocate executable memory region (mmap on Linux, VirtualAlloc on Windows)
|
||||
- Copy code sections to memory
|
||||
- Sanity checks (max 5MB code size, boundary validation)
|
||||
- [x] Memory allocation with execution permissions
|
||||
- Linux: mmap with PROT_READ | PROT_WRITE | PROT_EXEC
|
||||
- Windows: VirtualAlloc with PAGE_EXECUTE_READWRITE
|
||||
- Proper cleanup in unload() (munmap/VirtualFree)
|
||||
- [ ] Implement address relocation (STUB)
|
||||
- Parse delta-encoded offsets (multi-byte with high-bit continuation)
|
||||
- Fix absolute references relative to module base address
|
||||
- Update pointer tables
|
||||
- ⚠️ Needs real Warden module data to implement correctly
|
||||
|
||||
### Phase 5: API Binding (STUB - Infrastructure Complete ⚠️)
|
||||
|
||||
- [x] Define Windows API imports framework
|
||||
- kernel32.dll: VirtualAlloc, VirtualProtect, GetTickCount, etc.
|
||||
- user32.dll: GetForegroundWindow, etc.
|
||||
- ntdll.dll: NtQueryInformationProcess, etc.
|
||||
- [x] Windows: GetProcAddress resolution framework (needs PE import table parser)
|
||||
- [x] Linux: Platform limitation documented (needs Wine for Windows API layer)
|
||||
- [ ] Parse PE import directory and patch IAT (TODO - needs real module)
|
||||
- [x] Provide callback structure to module
|
||||
- sendPacket(), validateModule(), allocMemory(), freeMemory()
|
||||
- generateRC4(), getTime(), logMessage()
|
||||
|
||||
### Phase 6: Execution Engine (STUB - Infrastructure Complete ⚠️)
|
||||
|
||||
- [x] Define ClientCallbacks structure (7 callbacks client → module)
|
||||
- [x] Define WardenFuncList structure (4 callbacks module → client)
|
||||
- [x] Module entry point calling framework
|
||||
- Signature: `WardenFuncList* (*entryPoint)(ClientCallbacks*)`
|
||||
- Entry point at moduleMemory_ offset 0 (typical)
|
||||
- [x] Safety guards: execution disabled by default (unsafe without validation)
|
||||
- [ ] Enable actual x86 code execution (DANGEROUS - needs sandboxing)
|
||||
- [ ] Implement PacketHandler dispatcher
|
||||
- Route check opcodes (0xF3, 0xB2, 0x98, etc.)
|
||||
- Let module perform REAL memory scans
|
||||
- Return authentic responses
|
||||
- [ ] Implement Tick() periodic calls
|
||||
- [ ] Implement GenerateRC4Keys() re-keying
|
||||
- [ ] Implement Unload() cleanup with state saving
|
||||
|
||||
### Phase 7: Testing & Refinement (TODO - 1-2 weeks)
|
||||
|
||||
- [ ] Test against Warmane (strict enforcement)
|
||||
- [ ] Test against local AzerothCore (permissive)
|
||||
- [ ] Debug module execution issues
|
||||
- [ ] Add comprehensive logging
|
||||
- [ ] Performance optimization
|
||||
- [ ] Memory safety validation
|
||||
|
||||
---
|
||||
|
||||
## Estimated Timeline
|
||||
|
||||
| Phase | Duration | Difficulty | Status |
|
||||
|-------|----------|------------|--------|
|
||||
| Phase 1: Crypto | - | ⭐⭐ | ✅ DONE |
|
||||
| Phase 2: Foundation | - | ⭐ | ✅ DONE |
|
||||
| Phase 3: Validation | - | ⭐⭐⭐ | ✅ DONE |
|
||||
| Phase 4: Executable Loader | - | ⭐⭐⭐⭐⭐ | ⚠️ STUB (needs real module) |
|
||||
| Phase 5: API Binding | - | ⭐⭐⭐ | ⚠️ STUB (Windows/Wine only) |
|
||||
| Phase 6: Execution Engine | - | ⭐⭐⭐⭐⭐ | ⚠️ STUB (execution disabled) |
|
||||
| Phase 7: Testing | TBD | ⭐⭐⭐⭐ | 🔜 NEXT (needs real module) |
|
||||
| **INFRASTRUCTURE** | **COMPLETE** | **Very High** | **6/7 phases done** |
|
||||
|
||||
---
|
||||
|
||||
## Alternative: Packet Capture Approach
|
||||
|
||||
Instead of full module execution, capture responses from real WoW client:
|
||||
|
||||
### Process
|
||||
|
||||
1. Run real WoW 3.3.5a client
|
||||
2. Connect to Warmane with Wireshark running
|
||||
3. Capture CMSG_WARDEN_DATA response packets
|
||||
4. Analyze response format
|
||||
5. Implement matching response generator in wowee
|
||||
|
||||
### Benefits
|
||||
|
||||
- Much faster (1-2 weeks vs 2-3 months)
|
||||
- Lower complexity
|
||||
- May work if servers don't require full execution
|
||||
|
||||
### Drawbacks
|
||||
|
||||
- Only works if response format is static
|
||||
- May not work if modules change per session
|
||||
- Server might detect pattern-based responses
|
||||
- Doesn't scale to different servers
|
||||
|
||||
---
|
||||
|
||||
## Current Behavior
|
||||
|
||||
With the foundation implemented, the system:
|
||||
|
||||
1. ✅ Initializes WardenModuleManager on startup
|
||||
2. ✅ Receives SMSG_WARDEN_DATA packets
|
||||
3. ✅ Logs module structure (opcode, seed, trailing data)
|
||||
4. ✅ Verifies MD5 hash (step 1)
|
||||
5. ✅ RC4 decrypts module data (step 2)
|
||||
6. ⚠️ Logs "NOT IMPLEMENTED" for steps 3-8
|
||||
7. ❌ Falls back to **fake responses** (current GameHandler behavior)
|
||||
8. ❌ Warmane rejects fake responses (server goes silent)
|
||||
|
||||
**For strict servers like Warmane**: Module execution (Phases 3-7) is REQUIRED.
|
||||
|
||||
**For permissive servers**: Current fake responses work without module execution.
|
||||
|
||||
---
|
||||
|
||||
## Code Examples
|
||||
|
||||
### Creating a Module Instance
|
||||
|
||||
```cpp
|
||||
auto moduleManager = std::make_unique<WardenModuleManager>();
|
||||
|
||||
// Check if module cached
|
||||
std::vector<uint8_t> md5Hash = { /* 16 bytes */ };
|
||||
if (moduleManager->hasModule(md5Hash)) {
|
||||
std::cout << "Module cached, loading..." << std::endl;
|
||||
std::vector<uint8_t> moduleData;
|
||||
moduleManager->loadCachedModule(md5Hash, moduleData);
|
||||
}
|
||||
|
||||
// Get module instance
|
||||
auto module = moduleManager->getModule(md5Hash);
|
||||
|
||||
// Load module
|
||||
std::vector<uint8_t> rc4Key = { /* 16 bytes */ };
|
||||
if (module->load(moduleData, md5Hash, rc4Key)) {
|
||||
std::cout << "Module loaded successfully" << std::endl;
|
||||
} else {
|
||||
std::cout << "Module load failed" << std::endl;
|
||||
}
|
||||
```
|
||||
|
||||
### Processing Check Requests (Future)
|
||||
|
||||
```cpp
|
||||
// Decrypt incoming check request
|
||||
std::vector<uint8_t> decrypted = wardenCrypto_->decrypt(packet.getData());
|
||||
|
||||
// Try module execution
|
||||
std::vector<uint8_t> response;
|
||||
if (module->isLoaded() && module->processCheckRequest(decrypted, response)) {
|
||||
// Module generated authentic response
|
||||
std::cout << "Module executed checks, got real response" << std::endl;
|
||||
} else {
|
||||
// Fall back to fake responses
|
||||
std::cout << "Module not loaded or failed, using fake response" << std::endl;
|
||||
response = generateFakeResponse(decrypted);
|
||||
}
|
||||
|
||||
// Encrypt and send
|
||||
auto encrypted = wardenCrypto_->encrypt(response);
|
||||
sendWardenResponse(encrypted);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## References
|
||||
|
||||
### Documentation
|
||||
- [WARDEN_IMPLEMENTATION.md](WARDEN_IMPLEMENTATION.md) - Testing and findings
|
||||
- [WARDEN_QUICK_REFERENCE.md](WARDEN_QUICK_REFERENCE.md) - Quick troubleshooting guide
|
||||
- [WoWDev Wiki - Warden](https://wowdev.wiki/Warden)
|
||||
- [Exploiting Warden Behaviour](https://jordanwhittle.com/posts/exploiting-warden/)
|
||||
|
||||
### Source Code References
|
||||
- [MaNGOS Two - Warden.cpp](https://github.com/mangostwo/server/blob/master/src/game/Warden/Warden.cpp)
|
||||
- [TrinityCore Warden](https://github.com/TrinityCore/TrinityCore/tree/3.3.5/src/server/game/Warden)
|
||||
|
||||
### Implementation Files
|
||||
- `include/game/warden_module.hpp` - Module loader interface
|
||||
- `src/game/warden_module.cpp` - Implementation (phase 2 complete)
|
||||
- `include/game/warden_crypto.hpp` - RC4 crypto (existing, reused)
|
||||
- `src/game/warden_crypto.cpp` - RC4 implementation (existing)
|
||||
|
||||
---
|
||||
|
||||
**Last Updated**: 2026-02-12
|
||||
**Status**: Infrastructure COMPLETE (phases 1-6) ✅
|
||||
**What Works**: Full 8-step loading pipeline (MD5→RC4→RSA→zlib→parse→relocate→bind→init)
|
||||
**What's Stubbed**:
|
||||
- Step 6 (Relocations): needs real module data for delta-encoded offsets
|
||||
- Step 7 (API Binding): Windows-only or requires Wine on Linux
|
||||
- Step 8 (Execution): disabled for safety (would execute untrusted x86 code)
|
||||
**Next Step**: Phase 7 (Testing) - Obtain real Warden module and test/refine
|
||||
**Remaining Work**: Enable actual execution (requires real module + Windows/Wine + safety measures)
|
||||
|
|
@ -1,188 +1,95 @@
|
|||
# Warden Quick Reference
|
||||
|
||||
## TL;DR
|
||||
|
||||
**What works**: Servers with Warden disabled or permissive settings
|
||||
**What doesn't work**: Warmane (requires module execution)
|
||||
**What we have**: Complete crypto system, no module execution
|
||||
Warden is WoW's client integrity checking system. Wowee implements full Warden module execution
|
||||
via Unicorn Engine CPU emulation — no Wine required.
|
||||
|
||||
---
|
||||
|
||||
## Testing a New Server
|
||||
## How It Works
|
||||
|
||||
Warden modules are native x86 Windows DLLs that the server encrypts and delivers at login.
|
||||
|
||||
1. Server sends `SMSG_WARDEN_DATA` (0x2E6) with the encrypted module
|
||||
2. Client decrypts: RC4 → RSA-2048 signature verify → zlib decompress
|
||||
3. Parses the PE: relocations applied, imports resolved (Windows API hooks)
|
||||
4. Executes entry point via Unicorn Engine x86 emulator
|
||||
5. Client responds with check results via `CMSG_WARDEN_DATA` (0x2E7)
|
||||
|
||||
---
|
||||
|
||||
## Server Compatibility
|
||||
|
||||
| Server type | Expected result |
|
||||
|-------------|-----------------|
|
||||
| Warden disabled | Works (no Warden packets) |
|
||||
| AzerothCore (local) | Works |
|
||||
| ChromieCraft | Should work |
|
||||
| Warmane | Should work |
|
||||
|
||||
---
|
||||
|
||||
## Module Cache
|
||||
|
||||
Modules are cached after first download:
|
||||
|
||||
1. **Check if Warden is required**:
|
||||
```
|
||||
Connect → Look for SMSG_WARDEN_DATA (0x2E6)
|
||||
If no Warden packet → Server doesn't use Warden ✅
|
||||
If Warden packet → Continue testing
|
||||
~/.local/share/wowee/warden_cache/<MD5>.wdn
|
||||
```
|
||||
|
||||
2. **Watch for server response**:
|
||||
```
|
||||
After CMSG_WARDEN_DATA sent:
|
||||
- Gets SMSG_CHAR_ENUM → SUCCESS ✅
|
||||
- Connection stays open but silent → Rejected ⏸️
|
||||
- Connection closes → Rejected ❌
|
||||
```
|
||||
First connection: ~120ms (download + decompress + emulate). Subsequent: ~1-5ms (load from cache).
|
||||
|
||||
---
|
||||
|
||||
## Dependency
|
||||
|
||||
Unicorn Engine is required for module execution:
|
||||
|
||||
3. **Check logs**:
|
||||
```bash
|
||||
tail -f logs/wowee.log | grep -i warden
|
||||
sudo apt install libunicorn-dev # Ubuntu/Debian
|
||||
sudo dnf install unicorn-devel # Fedora
|
||||
sudo pacman -S unicorn # Arch
|
||||
```
|
||||
|
||||
Look for:
|
||||
- `packetsAfterGate=0` (bad - server silent)
|
||||
- `packetsAfterGate>0` (good - server responding)
|
||||
The client builds without Unicorn (falls back to crypto-only responses), but will not pass
|
||||
strict Warden enforcement in that mode.
|
||||
|
||||
---
|
||||
|
||||
## Quick Fixes
|
||||
## Key Files
|
||||
|
||||
### Server Goes Silent
|
||||
**Symptom**: Connection stays open, no SMSG_CHAR_ENUM
|
||||
**Cause**: Server doesn't accept our response format
|
||||
**Fix**: Try different response format (see below)
|
||||
|
||||
### Server Disconnects
|
||||
**Symptom**: Connection closes after Warden response
|
||||
**Cause**: Response is definitely wrong
|
||||
**Fix**: Don't use that format, try others
|
||||
|
||||
### Can't Get Past Warden
|
||||
**Solution 1**: Use a server with Warden disabled
|
||||
**Solution 2**: Contact server admin for test account
|
||||
**Solution 3**: Implement module execution (months of work)
|
||||
```
|
||||
src/game/warden_module.hpp/cpp - Module loader (8-step pipeline)
|
||||
src/game/warden_emulator.hpp/cpp - Unicorn Engine executor
|
||||
src/game/warden_crypto.hpp/cpp - RC4/MD5/SHA1/RSA crypto
|
||||
src/game/game_handler.cpp - Packet handler (handleWardenData)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Trying New Response Formats
|
||||
## Logs
|
||||
|
||||
Edit `src/game/game_handler.cpp` around line 1850:
|
||||
|
||||
```cpp
|
||||
std::vector<uint8_t> moduleResponse;
|
||||
|
||||
// Try your format here:
|
||||
moduleResponse.push_back(0xYOUR_BYTE);
|
||||
// Add more bytes...
|
||||
|
||||
// Existing code encrypts and sends
|
||||
```
|
||||
|
||||
Rebuild and test:
|
||||
```bash
|
||||
cd build && cmake --build . -j$(nproc)
|
||||
cd bin && ./wowee
|
||||
grep -i warden logs/wowee.log
|
||||
```
|
||||
|
||||
Key messages:
|
||||
- `Warden: module loaded from cache` — cached path, fast startup
|
||||
- `Warden: executing module entry point` — emulation running
|
||||
- `Warden: check response sent` — working correctly
|
||||
- `packetsAfterGate=0` — server not responding after Warden exchange
|
||||
|
||||
---
|
||||
|
||||
## Response Formats Already Tried (Warmane)
|
||||
## Check Types
|
||||
|
||||
| Format | Bytes | Result |
|
||||
|--------|-------|--------|
|
||||
| Empty | 0 | Silent ⏸️ |
|
||||
| `[0x00][MD5][0x01]` | 18 | Silent ⏸️ |
|
||||
| `[0x01]` | 1 | Disconnect ❌ |
|
||||
| `[20-byte echo]` | 20 | Silent ⏸️ |
|
||||
| `[0x01][SHA1]` | 21 | Silent ⏸️ |
|
||||
| Opcode | Name | Response |
|
||||
|--------|------|----------|
|
||||
| 0x00 | Module info | `[0x00]` |
|
||||
| 0x01 | Hash check | `[0x01][results]` |
|
||||
| 0x02 | Lua check | `[0x02][0x00]` |
|
||||
| 0x04 | Timing | `[0x04][timestamp]` |
|
||||
| 0x05 | Memory scan | `[0x05][num][results]` |
|
||||
|
||||
---
|
||||
|
||||
## Module Packet Structure
|
||||
|
||||
```
|
||||
Byte Content
|
||||
0 Opcode (varies each packet)
|
||||
1-16 Seed (16 bytes for RC4)
|
||||
17-36 Trailing data (20 bytes, possibly SHA1)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Crypto Overview
|
||||
|
||||
```cpp
|
||||
// Initialize (first packet only)
|
||||
wardenCrypto_->initialize(moduleData);
|
||||
|
||||
// Decrypt incoming
|
||||
auto plain = wardenCrypto_->decrypt(encrypted);
|
||||
|
||||
// Encrypt outgoing
|
||||
auto encrypted = wardenCrypto_->encrypt(plain);
|
||||
```
|
||||
|
||||
Keys are derived from:
|
||||
- Hardcoded Warden module key (in `warden_crypto.cpp`)
|
||||
- 16-byte seed from server
|
||||
- XOR operation for output key
|
||||
|
||||
---
|
||||
|
||||
## Check Types Reference
|
||||
|
||||
| Opcode | Name | What It Checks | Our Response |
|
||||
|--------|------|----------------|--------------|
|
||||
| 0x00 | Module Info | Module status | `[0x00]` |
|
||||
| 0x01 | Hash Check | File/memory hashes | `[0x01][0x00...]` |
|
||||
| 0x02 | Lua Check | Suspicious addons | `[0x02][0x00]` |
|
||||
| 0x04 | Timing | Speedhacks | `[0x04][timestamp]` |
|
||||
| 0x05 | Memory | Memory scans | `[0x05][num][0x00...]` |
|
||||
|
||||
All responses are **faked** - we don't actually check anything.
|
||||
|
||||
---
|
||||
|
||||
## Common Errors
|
||||
|
||||
**Build fails**: Missing OpenSSL
|
||||
```bash
|
||||
sudo apt-get install libssl-dev
|
||||
```
|
||||
|
||||
**Crypto init fails**: Bad module packet
|
||||
```
|
||||
Check log for "Warden: Initializing crypto"
|
||||
Ensure packet is at least 17 bytes
|
||||
```
|
||||
|
||||
**Always disconnects**: Server detects fake client
|
||||
```
|
||||
No easy fix - need module execution or different server
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Next Steps for Warmane Support
|
||||
|
||||
1. **Capture real WoW client packets** (Wireshark)
|
||||
2. **Compare with our responses** (find differences)
|
||||
3. **Implement matching format** (edit game_handler.cpp)
|
||||
4. **OR**: Implement module execution (months)
|
||||
|
||||
---
|
||||
|
||||
## File Locations
|
||||
|
||||
```
|
||||
Crypto: src/game/warden_crypto.cpp
|
||||
Hashes: src/auth/crypto.cpp
|
||||
Handler: src/game/game_handler.cpp (handleWardenData)
|
||||
Opcodes: include/game/opcodes.hpp (0x2E6, 0x2E7)
|
||||
Logs: logs/wowee.log
|
||||
Full docs: docs/WARDEN_IMPLEMENTATION.md
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Support Resources
|
||||
|
||||
- [Full Implementation Doc](WARDEN_IMPLEMENTATION.md)
|
||||
- [WoWDev Wiki - Warden](https://wowdev.wiki/Warden)
|
||||
- [TrinityCore Source](https://github.com/TrinityCore/TrinityCore/tree/3.3.5)
|
||||
|
||||
---
|
||||
|
||||
**Last Updated**: 2026-02-12
|
||||
**Status**: Working (permissive servers) | Not Working (Warmane)
|
||||
**Last Updated**: 2026-02-17
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -1,6 +1,6 @@
|
|||
# Project Status
|
||||
|
||||
**Last updated**: 2026-02-15
|
||||
**Last updated**: 2026-02-17
|
||||
|
||||
## What This Repo Is
|
||||
|
||||
|
|
@ -8,25 +8,25 @@ Wowee is a native C++ World of Warcraft client experiment focused on connecting
|
|||
|
||||
## Current Code State
|
||||
|
||||
Implemented (working in normal development use):
|
||||
Implemented (working in normal use):
|
||||
|
||||
- Auth flow: SRP6a auth + realm list + world connect with header encryption
|
||||
- Rendering: terrain, WMO/M2 rendering, water, sky system, particles, minimap/world map, loading video playback
|
||||
- Core gameplay plumbing: movement, targeting, action bar basics, inventory/equipment visuals, chat (tabs/channels, emotes, item links)
|
||||
- Multi-expansion direction: Classic/TBC/WotLK protocol variance handling exists and is being extended (`src/game/packet_parsers_classic.cpp`, `src/game/packet_parsers_tbc.cpp`)
|
||||
- Character system: creation (including nonbinary gender), selection, 3D preview with equipment, character screen
|
||||
- Core gameplay: movement, targeting, combat, action bar, inventory/equipment, chat (tabs/channels, emotes, item links)
|
||||
- Quests: quest markers (! and ?) on NPCs and minimap, quest log, accept/complete flow, turn-in
|
||||
- Trainers: spell trainer UI, buy spells, known/available/unavailable states
|
||||
- Vendors, loot, gossip dialogs
|
||||
- Spellbook with class tabs, drag-drop to action bar, spell icons
|
||||
- Warden anti-cheat: full module execution via Unicorn Engine x86 emulation; module caching
|
||||
- Audio: ambient, movement, combat, spell, and UI sound systems
|
||||
- Multi-expansion: Classic/Vanilla, TBC, WotLK, and Turtle WoW (1.17) protocol and asset variants
|
||||
|
||||
In progress / incomplete (known gaps):
|
||||
In progress / known gaps:
|
||||
|
||||
- Quests: some quest UI/markers exist, but parts of quest log parsing are still TODOs
|
||||
- Transports: functional support exists, but some spline parsing/edge cases are still TODOs
|
||||
- Audio: broad coverage for events/music/UI exists, but 3D positional audio is not implemented yet
|
||||
- Warden: crypto + module plumbing are in place; full module execution and server-specific compatibility are still in progress
|
||||
|
||||
## Near-Term Direction
|
||||
|
||||
- Keep tightening packet parsing across server variants (especially Classic/Turtle and TBC)
|
||||
- Keep improving visual correctness for characters/equipment and M2/WMO edge cases
|
||||
- Progress Warden module execution path (emulation via Unicorn when available)
|
||||
- Transports (ships, zeppelins, elevators): partial support, timing and edge cases still buggy
|
||||
- 3D positional audio: not implemented (mono/stereo only)
|
||||
- Visual edge cases: some M2/WMO rendering gaps (character shin mesh, some particle effects)
|
||||
|
||||
## Where To Look
|
||||
|
||||
|
|
@ -34,4 +34,3 @@ In progress / incomplete (known gaps):
|
|||
- Networking/auth: `src/auth/`, `src/network/`, `src/game/game_handler.cpp`
|
||||
- Rendering: `src/rendering/`
|
||||
- Assets/extraction: `extract_assets.sh`, `tools/asset_extract/`, `src/pipeline/asset_manager.cpp`
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue