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,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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue