# WardenScanner **Repository Path**: bluew11/WardenScanner ## Basic Information - **Project Name**: WardenScanner - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-07-14 - **Last Updated**: 2026-07-14 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # WardenScanner v3.3 ![WardenScanner war](war.png) A monitoring tool that watches Blizzard's **Warden** anti-cheat system from outside the game process. Built for WoW 3.3.5a (build 12340) on private servers. It doesn't inject anything, doesn't hook anything, and doesn't modify the game. It just reads memory and reports what Warden is doing. --- ## Why this exists If you're working on a bot or tool for 3.3.5a, you need to understand what Warden checks for and when. This scanner tells you: - Whether Warden is loaded, active, or idle - Where it allocated executable memory - When it loads its scanning module - What encryption keys it's using - Whether the server has installed custom packet handlers (Warmane's RCE trick) - If Warden's own code has been tampered with (VTable redirects, function hooks) - Whether the server is using hunting techniques to find external tools - The SHA1 hash of each Warden module that gets loaded - What each scan check targets (address, module, Lua string) and whether it hits known bot surfaces - All offsets are configurable via an external INI file — no recompile needed Think of it as a security camera pointed at the anti-cheat — not at the game. --- ## How it works ### Passive mode (default) Completely read-only. Opens a handle to `Wow.exe` and periodically scans: - **Executable memory pages** — Flags any committed memory with read-write-execute permissions. Warden modules and injected code both show up here. - **Hidden PE modules** — Scans heap memory for PE images that weren't loaded through the normal Windows loader. This is how Warden's module appears — it's unpacked directly into heap memory. - **Warden state** — Reads known structure pointers to determine if the Warden module is loaded (structure allocated) or fully active (virtual function table populated). - **Handler integrity** — Checks whether a specific network handler has been tampered with. On Warmane, the server sends malformed packets to hijack this handler and run custom code inside the client. No admin required. No writes to WoW's memory. Same risk level as having Task Manager open. ### Hardware breakpoint mode (`--hwbp`) Attaches as a debugger and sets x86 hardware breakpoints (DR0–DR3) on four key Warden functions. Every time one of them executes, the scanner captures the full register state and function arguments: - **Module loader** — Catches the moment Warden unpacks its scanning module. Logs the module data pointer, size, and first 64 bytes. - **Initialization** — Captures Warden's startup parameters. - **Message handler registration** — Logs when new packet handlers are installed. This is how you see Warmane's custom scanner being set up in real time. - **Encryption setup** — Captures the exact RC4 key bytes used to encrypt Warden traffic. The scanner hides the debugger by patching several debug indicators (PEB flags, heap flags, NtGlobalFlag). These are re-patched periodically since Warden can reset them. **Requires admin.** Run as Administrator. ### Session key extraction Reads the 40-byte session key from the game's connection structure and derives the Warden RC4 encryption keys using the same HMAC-SHA1 algorithm as the server. This gives you the keys needed to decrypt Warden protocol traffic (both server-to-client and client-to-server). The key is automatically re-read if the game reconnects. > The session key memory offset is marked as unverified in the code. Cross-validate against captured ARC4::Init key data when possible. ### Warden integrity monitoring Every scan cycle (when Warden is active), the scanner checks for signs that Warden itself has been modified: - **VTable snapshot** — Captures the 14-entry virtual function table on first sight, then compares every scan. If any pointer changes, something redirected a Warden function. - **Hook detection** — Reads the first bytes of 6 key Warden functions, looking for JMP/CALL/PUSH+RET patterns that indicate inline hooks. - **Prologue tracking** — Detects any byte-level changes in function prologues compared to baseline. ### Anti-detection canary Reads the prologues of sensitive system functions inside WoW's address space (ntdll, kernel32) every scan cycle: - `NtQuerySystemInformation` — used for handle/process enumeration - `NtQueryInformationProcess` — used for debug port detection - `NtGetContextThread` — used to read debug registers (detects HWBP) - `CreateToolhelp32Snapshot` — used to enumerate processes - `IsDebuggerPresent` / `CheckRemoteDebuggerPresent` — basic debug checks If any of these get hooked by a Warden module (JMP patch, etc.), the scanner raises an alert. Baselines are captured at startup and compared every cycle. This tells you when the server starts actively hunting for external tools. ### Warden lifecycle tracking (HWBP mode) In hardware breakpoint mode, the scanner classifies every captured event into a Warden lifecycle timeline: - **Module loads** — SHA1 hash of the module header. If the hash changes between loads, Warmane pushed a new scanning module. - **Initialization** — Tracks Warden startup parameters. - **Key exchanges** — Counts ARC4 key setups (indicates Warden communication cycles). - **Handler registrations** — Logs when new packet handlers are installed. ### Scan request decoder (HWBP mode) When DR3 captures a Warden scan batch (raw bytes from the `WardenData` handler), the scanner decodes it into individual check requests: - Parses the binary Warden protocol: opcode byte → check count → per-check type/address/length - Supports all known check types: MemCheck, PageCheckA/B, ModuleCheck, DriverCheck, LuaStrCheck, TimingCheck, ProcCheck, MpqCheck - Shows each check in a formatted table with type, target address, check length, and classification ### Scan classifier Each decoded check is classified into a risk zone with color coding: - **BOT_SURFACE** (red) — address falls inside known bot-related memory (EndScene hooks, Lua state, D3D pointers) - **INJECT** (red) — address targets heap-allocated code or RWX memory regions - **SYSTEM** (gray) — address points to Windows DLLs or game code sections - **UNKNOWN** (yellow) — address doesn't match any known range The classifier dynamically updates its RWX range list each scan cycle. Known bot addresses (D3D_PTR, LUA_STATE) are configurable via `warden.ini`. ### DR3 rotation (HWBP mode) The scanner uses all four hardware debug registers strategically: - DR0: `LoadWardenModule` — module loading - DR1: `WardenClientInitialize` — initialization - DR2: `NetClient::SetMessageHandler` — handler registration - DR3: starts on `ARC4::Init` (captures encryption keys), then **auto-rotates** to `WardenData` after 2+ key exchanges to capture scan batches On module reload (Warden re-sent by server), DR3 rotates back to `ARC4::Init` to capture the new keys, then rotates again once keys are established. ### Reconnection detection Monitors the `ClientConnection` base pointer every scan cycle. If it changes (server reconnect, disconnect/reconnect), the scanner: - Re-reads the session key automatically - Resets anti-detection canary baselines (system function prologues may differ) - Logs a notice in the next scan box ### External configuration (`warden.ini`) All memory offsets can be overridden without recompiling. Place `warden.ini` next to the executable: ```ini [Warden] WardenStructurePTR = 0x00C79CE0 [WardenVTable] VT_CheckFunctions = 0x28 VT_MemoryCheck = 0x04 [WardenFunctions] LoadWardenModule = 0x006D0E80 WardenData = 0x006D1680 [Network] ClientConnection = 0x00C79CE8 [KnownAddresses] D3D_PTR = 0x00C5DF88 LUA_STATE = 0x00D3F78C [Crypto] ARC4Init = 0x0012FE90 SessionKeyOffset = 0x508 ``` Sections map to offset groups. Values must be valid 32-bit user-mode addresses (0x10000–0x7FFFFFFF) or they're silently skipped. Supports `0x` prefix and bare hex with A-F digits. Comments with `;` or `#`. --- ## WPF Dashboard The scanner runs as a Windows desktop application with a dark-themed single-window dashboard: - **Title bar** — Application name and version, plus Start/Stop buttons to control the scan engine. - **Settings bar** — Before starting: editable interval (seconds) and HWBP mode checkbox. During scan: live stats showing PID, mode (Passive/HWBP), scan number with pulse indicator, interval, uptime, and clock. - **Warden Status panel** — Current Warden state (Active/Loaded/Not loaded/Unknown) with color indicators, RWX page count, hidden module count, and detail text. - **Protection panel** — Background handler integrity, anti-detection canary status, and code integrity check results — all with green/red status indicators. - **Decoder panel** — Cumulative decoded check count, unique target addresses, danger alerts (bot-surface hits in red), logged events, and last batch summary. - **HWBP Monitor panel** — Hardware breakpoint event counts, captured keys, module loads, last event detail, and lifecycle summary. Shows "Disabled — Passive mode" when HWBP is off. - **Session Key panel** — Captured session key and derived server RC4 key displayed in monospaced hex. - **Log panel** — Auto-scrolling log with color-coded entries (green info, yellow warnings, red errors, magenta lifecycle events). Fills all remaining vertical space. All output (including errors from the debug engine and WardenLog) is routed through `Output.cs`, which marshals everything to the UI thread via `Dispatcher.BeginInvoke`. The scan engine runs on a dedicated background thread. --- ## Usage ``` dotnet build dotnet run ``` Launch the app, configure settings in the info bar (interval, HWBP mode), and click **Start**. The scanner searches for `Wow.exe` on startup (retries for up to 60 seconds). Click **Stop** or close the window to end the scan. | Setting | Default | Description | |---------|---------|-------------| | Interval | 10s | Seconds between scans (editable in the settings bar) | | HWBP | off | Enable hardware breakpoint tracing (checkbox in settings bar, requires admin) | | Log dir | logs | Where `.log` files are written | Logs are plain text with ISO 8601 timestamps — one file per session. --- ## What Warden actually checks Warden sends encrypted check requests to the client. Each check type looks for something specific: | Check | What it does | |-------|-------------| | Memory read | Reads bytes at a given address — detects function hooks (JMP patches) | | Page hash | SHA1 of a memory page — detects any code modifications | | Module check | Enumerates loaded DLLs and hashes them — detects injected modules | | Driver check | Looks for specific kernel drivers | | Lua evaluation | Runs Lua code and checks the result — scans for bot globals and frame registrations | | File integrity | Verifies game data files haven't been tampered with | | Timing check | Measures response time — detects slow interception or single-step debugging | On Warmane specifically, the server also deploys custom scanning code via a packet exploit. This isn't standard Warden — it's additional server-side code injected into the client through a known RCE vector. The scanner detects the initial stage of this attack. --- ## Detection risk ### Passive mode — low risk External memory reads don't trigger any Warden check type. The only exposure is if the server's custom code enumerates open process handles — the same risk as having any system tool open. ### HWBP mode — research use only The debug attachment is detectable through kernel-level queries that can't be blocked from userspace. Additionally, the hardware breakpoint addresses are visible to any code running inside WoW that reads its own thread context. **Practical recommendation:** Use passive mode on live servers. Use HWBP mode on a local TrinityCore instance to study Warden behavior, then apply that knowledge without the debugger attached. --- ## Project structure ``` WardenScanner/ App.xaml / App.xaml.cs WPF entry point, dark theme resources Output.cs Static facade routing output to WPF ViewModel warden.ini External offset configuration (optional) Views/ MainWindow.xaml/.cs Dashboard layout + scan engine wiring ViewModels/ MainViewModel.cs All dashboard state (INotifyPropertyChanged) ViewModelBase.cs MVVM infrastructure RelayCommand.cs ICommand implementation Services/ ScanEngine.cs Background scan thread (ported from old Program.cs) Core/ ProcessAttacher.cs Finds and attaches to Wow.exe MemoryReader.cs ReadProcessMemory wrapper ScanCoordinator.cs Orchestrates each scan cycle OffsetsConfig.cs INI parser for warden.ini Warden/ WardenOffsets.cs All known memory addresses (compiled defaults) Detector.cs Passive scanning logic IntegrityChecker.cs VTable snapshot + hook detection AntiDetectionCanary.cs System function prologue monitoring WardenLifecycleTracker.cs HWBP event classifier (module hash, key count) SessionKeyReader.cs Session key extraction + RC4 key derivation ScanRequestDecoder.cs Binary Warden protocol decoder ScanClassifier.cs Risk zone classifier (BOT_SURFACE, INJECT, SYSTEM) Hwbp/ BreakpointConfig.cs DR register → function mapping + DR3 rotation BreakpointManager.cs Sets/clears breakpoints on all threads DebugEngine.cs Debug loop, anti-debug patching, event capture BreakpointEvent.cs Event data types RegisterCapture.cs Per-function argument extraction Database/ WardenLog.cs Plain-text session logger (file-only) Platform/ NativeMethods.cs Win32 P/Invoke declarations PeHeader.cs PE header parsing ``` All addresses and patterns are in the source code ([WardenOffsets.cs](Warden/WardenOffsets.cs), [BreakpointConfig.cs](Hwbp/BreakpointConfig.cs)) with compiled defaults. Override any value at runtime via [`warden.ini`](#external-configuration-wardenini). No NuGet dependencies — P/Invoke only. --- ## Requirements - .NET 10 SDK (with WPF workload) - Windows (x86 target — WoW 3.3.5a is 32-bit) - WoW 3.3.5a build 12340 - Administrator for HWBP mode --- ## Security - **No plaintext keys in logs** — Session keys are logged as truncated SHA-256 hashes only. Raw key bytes are never written to disk. - **Path validation** — Log directory is validated to stay within the application root. Path traversal attempts are rejected. - **Memory safety** — Address arithmetic includes overflow guards to prevent infinite loops during memory scans. INI offsets are range-checked (0x10000–0x7FFFFFFF). - **Anti-debug patching** — WriteProcessMemory calls for PEB flag patching are error-checked and logged on failure. - **Console isolation** — All console output is routed through a single class (`Output.cs`). No component writes to the console directly, preventing cursor corruption from the debug thread. --- ## Credits Offset research and Warden protocol knowledge from the OwnedCore community and TrinityCore source code. - DarkLinux - Warden RC4 key derivation seeds: TrinityCore WardenWin.cpp - Makkah(Warden-Export) : [Wow-Private-Server/Warden-Export](https://github.com/Wow-Private-Server/Warden-Export)