mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-03-22 23:30:14 +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
|
|
@ -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