AACGUARD Technical Report
AACGUARD Technical Report TR-2026-01 · Revision 2 · Client v0.0.10

AACGUARD: Evidence-Weighted, User-Mode Forensic Cheat Detection for Community Game Servers

The AACGUARD Project
aacguard.com · September 2026

Abstract

Community-run servers for competitive shooters such as Counter-Strike have no access to the kernel-level anti-cheat that protects official matchmaking. Their administrators often decide on suspected cheaters with little more than spectator footage. We present AACGUARD, a user-mode forensic scanner that a player runs on request, together with the web platform used to review its reports. The client examines 22 evidence sources: Windows execution history (Prefetch, BAM, MUICache, AmCache, ShimCache), file-system and autostart locations, removable-media history, browser history, game configuration files, virtualization and RAM-disk indicators, anti-forensic tooling, and the live state of the game process and kernel. Each finding is recorded as a weighted item of evidence, and a two-dimensional decision rule over total score and number of findings produces a verdict of CLEAN, SUSPICIOUS or CHEAT DETECTED.

Version 0.0.10 adds automatic game identification for six titles and attributes the game server a player is connected to, using header-only packet observation, the Source/GoldSrc A2S query protocol and DNS verification. It also inspects the 32-bit processes that were previously invisible to the 64-bit client, detects manually mapped code, and applies a three-stage trust model against false positives caused by legitimate system components. In a documented case study, the trust model reduced a clean player's score from 395 to 130 and corrected the verdict from CHEAT DETECTED to CLEAN. A complete scan takes about 17 seconds and performs about 1.9 × 105 individual checks. The public deployment had recorded 11,181 scans at the time of writing.

Keywords: anti-cheat · digital forensics · Windows artifacts · evidence scoring · false-positive reduction · process memory inspection · A2S protocol · Counter-Strike · community game servers

1Introduction

Cheating in online games undermines fair competition and drives honest players away. Large publishers respond with commercial anti-cheat systems that run kernel drivers, monitor continuously and are tied to official matchmaking. A large part of the Counter-Strike ecosystem, however, is played on community servers: independently hosted servers with their own rules, plugins and moderation teams. These servers are often built on older engines (GoldSrc for CS 1.6, Source for CS:GO), where the only built-in protection is Valve Anti-Cheat (VAC), and VAC bans are delayed and not visible to server staff.

In this setting a common moderation practice has formed. When a player is suspected, an administrator asks them to run a scanner and share the result. The scanner has to answer a narrow forensic question: does this machine show credible traces of cheat software, and how strong is that evidence? The answer has to be produced without a kernel driver, within seconds, on hardware the scanner has never seen, and in a form that another person can check.

AACGUARD is built for this workflow. Its design follows three principles:

This report makes the following contributions:

  1. A description of a complete user-mode forensic pipeline for cheat detection with 22 evidence sources, together with its full detection catalogue and weights (Sections 5–7, Appendix A).
  2. A two-dimensional verdict rule that requires either one decisive finding or several corroborating ones, and an analysis of its properties (Section 7).
  3. A method to attribute the connected game server from user mode for UDP-based games, combining header-only packet observation, A2S queries and DNS verification, with a history-based fallback (Section 9).
  4. A three-stage trust model that removes a class of high-scoring false positives, with a documented case study (Section 11).
  5. A description of the review platform that turns scan data into moderation decisions, including privacy measures (Sections 12 and 14).

2.1Cheating and its classification

Yan and Randell give a systematic classification of cheating in online games by vulnerability, consequence and cheater [1]. The cheats that matter for AACGUARD fall into their category of exploiting a lack of secrecy or integrity on the client: internal cheats that run inside the game process (typically an injected DLL that reads entity data and draws an overlay or adjusts aim) and external cheats that run as a separate process and read or write game memory through the operating system. Both have to be delivered, usually by a loader or injector, and both leave traces on the machine they ran on.

2.2Client-side anti-cheat

Commercial systems move detection into the kernel to see what user-mode code cannot. Dorner and Klausner examine kernel-level anti-cheat critically and compare its capabilities and risks with rootkits [2]. Collins et al. evaluate client-side defences against a range of attacks and show that user-mode protections can be bypassed by attackers who control the machine [3]. AACGUARD accepts this limit. It does not try to prevent cheating while the game runs. It performs a post-hoc examination designed to catch the traces that delivery and use of a cheat leave behind, which a cheater has to remove completely and in advance to stay hidden.

2.3Windows forensic artifacts

Many of AACGUARD's evidence sources are standard in digital forensics. The Windows registry records program execution and user activity in several places [4]. Prefetch files record the executables the system has launched. The AmCache hive stores metadata about programs that have been present or executed, and its interpretation has been analysed in detail by ANSSI [5]. Memory forensics tools identify injected code by looking for executable memory that no file on disk backs [6]. The internal structures AACGUARD relies on (process address spaces, module lists, WOW64 redirection) are documented in Windows Internals [7] and the Win32 API reference [8–12]. AACGUARD's contribution is not a new artifact but an automated, weighted combination of these artifacts, tuned to one domain and exposed for human review.

3Threat model and design goals

We assume a player who may have used cheat software on the machine being scanned and who controls that machine, including administrator access. The scan is started voluntarily, usually at an administrator's request. The player may run the scanner on a machine that has been cleaned, may close the cheat before scanning, and may rename files. We assume the player cannot tamper with the server side (API, database, panel).

Table 1. Cheat life-cycle stages and the evidence each stage can leave behind.
StageTypical activityEvidence surfaces examined
AcquisitionVisiting a cheat forum or shop, downloading an archiveBrowser history, Downloads/Desktop, Recycle Bin, shortcuts
StagingExtracting, keeping files on USB, RAM disks or in a VMAppData, USB history, RAM-disk and VM indicators
ExecutionRunning a loader or external cheatPrefetch, BAM, MUICache, AmCache, ShimCache, running processes
InjectionLoading code into the game, possibly via a vulnerable driverGame modules, private executable memory, loaded drivers
Persistence and useAutostart, cheat-specific configsRun keys, game .cfg files
ConcealmentCleaners, deleting tracesAnti-forensic tool indicators, Recycle Bin

The design goals follow from this model:

  1. Coverage across the life cycle. A cheater who hides one stage should still be exposed by another.
  2. Precision over recall. A false accusation damages a player and the scanner's credibility. Weak signals may raise suspicion but must not produce a cheat verdict on their own.
  3. Updatability. Cheat names, sites and whitelists change weekly, so they are loaded from the server at scan time, not compiled into the client.
  4. Explainability. Every contribution to the score is logged in plain language, with its source and path.
  5. Low friction. One click, no installation, results in under half a minute.

4System architecture

AACGUARD has three tiers (Figure 1): a Windows desktop client (.NET 10, WPF), an HTTPS API that accepts scan reports, and a PHP web panel backed by MariaDB.

Three-tier architecture: desktop client, API, database and web panel Desktop client WPF · runs as administrator ScannerEngine (22 checks) Game + server detection Report + upload Scan API version gate POST /api/scan MariaDB scans · users · cfg files · AI notes Web panel players · scans · lookup · bans JSON INSERT SELECT remote scan config (names, sites, whitelist)
Figure 1. System architecture. Detection lists are downloaded at scan time, so they can be updated without releasing a new client.

4.1Scan life cycle

Figure 2 shows the sequence of one scan. The client loads the remote configuration and identifies the running game. It then runs the checks in a fixed order, derives the verdict, and uploads the report only if its version exactly matches the minimum version published by the server. This version gate keeps reports from outdated detection logic out of the database. The client then shows a local report window, and the scan becomes visible in the panel. An automated interpretation of the log is attached to the scan asynchronously (Section 12.3).

Sequence of one scan between player, client, config server, API, database and panel PlayerClientConfig APIDatabasePanel Start scan GET scanconfig.json names · sites · whitelist detect game 22 checks → verdict GET minimum version must match exactly POST /api/scan INSERT report window SELECT
Figure 2. Life cycle of one scan. Dashed arrows are responses. The administrator's panel reads the stored scan at any later time.

4.2Client structure

The engine is a single orchestrator that owns the shared state: configuration, metrics, the list of findings and the per-check status. Each evidence source is implemented as a separate class with an Execute(token) method. A check never decides a verdict. It calls a single registration method, which logs the finding, updates the totals and notifies the user interface (Listing 1). This keeps all checks accountable to the same scoring and logging path.

Listing 1. Single registration path for all evidence ScannerEngine.cs
internal void RegisterDetection(string description, EvidenceStrength strength,
                                int scoreDelta, string? filePath = null, string? source = null)
{
    Log($"DETECTION ({strength}): {description}");
    _metrics.TotalDetections++;
    _metrics.Score += scoreDelta;
    _detections.Add(new DetectionItem { Description = description, Strength = strength,
                                      ScoreDelta = scoreDelta, FilePath = filePath,
                                      Source = source ?? "Unknown" });
    UpdateMetrics();                                    // live UI counters
}

5Forensic artifact analysis

This section describes each evidence source, what it records, and how AACGUARD interprets it. Table 2 gives an overview. The weights for every finding are listed in Appendix A.

Table 2. Evidence sources in the v0.0.10 pipeline, in execution order. † marks sources new in this version.
#SourceWhat it recordsSurvives deletion of the cheat?
1PrefetchExecutables launched, with last-run timeYes
2BAMPer-user executable paths with last-execution timeYes
3MUICacheDisplay names of executed programsYes
4AppDataFiles in the user's application-data foldersNo
5Recycle BinDeleted files with original path and deletion timeUntil emptied
6Downloads / DesktopCheat-like files, loaders, archivesNo
7CS directoryForeign DLLs inside the game folderNo
8USB historyStorage devices seen, last connection, recent executablesPartly
9Browser historyVisits to cheat sites and cheat-related searchesUntil cleared
10AmCachePrograms present or executed, with metadataYes
11ShimCacheExecutables seen by the compatibility engineYes
12Run keysPrograms set to start with WindowsNo
13Shortcuts.lnk files and their targetsOften
14Processes and modulesRunning tools, DLLs loaded into the gameNo (live)
15 †InjectionExecutable private memory holding a PE imageNo (live)
16 †DriversLoaded kernel driversNo (live)
17–19Virtualization, VM history, VM registryVM software, hardware markers, installer eventsYes
20RAM diskRAM drives and softwarePartly
21Anti-forensicsCleaner and trace-removal toolsYes
22CFG scanNon-default game configs with cheat-specific contentNo

5.1Execution history

Prefetch. Windows keeps a .pf file per launched executable in C:\Windows\Prefetch. The file name contains the executable name, and its modification time approximates the last execution. AACGUARD weights Prefetch findings by recency, because a trace from the last 24 hours is far more relevant to a match played today than one from months ago. The weight of a finding is the sum of a base value that depends on the type of match and a recency term r(Δt):

w = b + r(Δt),   b = 1000 (exact) or 30 (fuzzy),   r ∈ {40, 25, 10, 5} (1)
Table 3. Prefetch recency weighting.
Approx. last executionr(Δt)Strength (exact / fuzzy)w exactw fuzzy
Within 24 hours40Strong / Medium104070
Within 7 days25Medium / Medium102555
Older10Medium / Weak101040
Timestamp unavailable5Medium / Weak100535

BAM. The Background Activity Moderator service records, per user, the full path of executables and their last execution time in the registry. It survives deletion of the executable and gives a full path, which helps reviewers. MUICache stores the display names of programs the user has run. AmCache and ShimCache are compatibility databases that record programs present on or executed by the system; their exact semantics depend on the Windows version [5]. AACGUARD uses all five sources for the same test (exact or fuzzy cheat-name match, Section 6), because each can survive a clean-up that misses the others.

5.2File system and persistence

The AppData, Downloads and Desktop checks look for files with cheat-like names and, if configured, compare hashes against known cheat binaries. The Downloads and Desktop check also looks for generic loader and injector patterns. The Recycle Bin check parses the metadata of deleted items, so it recovers the original path and the deletion time; the time of the most recent deletion is always logged, because deleting shortly before a scan is informative. The Run keys check examines autostart entries. The shortcut check resolves each .lnk file and weights it by what it points to (Table 4).

Table 4. Shortcut weighting by name match and target type.
Shortcut nameTargetStrengthw
Exact cheat nameExecutable or cheat archiveStrong1000
Exact cheat nameOther fileMedium30
Exact cheat nameUnresolvedMedium20
AnyCheat-like executableMedium25
AnyCheat-like archiveMedium15
Cheat-like nameOther fileWeak5
Cheat-like nameUnresolvedWeak3

5.3Removable media

Keeping cheat files on a USB stick is a common way to avoid leaving them on the system drive. The USB check lists storage devices recorded in the registry with their last connection time, and scans any currently connected removable drive for recent executables. Only files active in the last 24 hours are considered, and weights include a recency term of 20 (last 15 minutes), 15 (last 2 hours) or 10 (older). Findings on removable media carry high base weights (250 for an exact name, 500 for a hash match), because a cheat binary on a portable drive is strong evidence of intent.

5.4Browser history

The browser check locates the history databases of Chromium- and Firefox-based browsers, including backup copies and Microsoft Store builds, and queries them read-only. It reports visits to known cheat sites (Medium, 50) and cheat-related searches (Weak, 20). When both kinds of signal appear in the same browser, it adds a combined finding (Strong, 60). The list of browsers found is stored with the scan.

5.5Game configuration files

Counter-Strike configuration files are plain text. The CFG check collects non-default .cfg files from the game and Steam userdata folders, compares their names with a list of default files shipped with the game, and searches them for cheat names (Medium, 25), cheat-related keywords (Weak, 10) and settings typical of “HvH” (hack-versus-hack) play (Medium, 20). The files are uploaded with the scan so a reviewer can read them.

5.6Environment: virtualization and RAM disks

Some cheaters run cheats or their loaders inside virtual machines, or keep them on RAM disks that disappear at shutdown. The virtualization checks look for installed and running VM software, hardware markers such as a virtual baseboard manufacturer, VM entries in uninstall records, and VM-related installer events. The RAM-disk check looks for RAM drives, RAM-disk software and services, and system or browser paths redirected to a RAM disk. Most of these indicators are Weak (3–10), because VMs and RAM disks have many legitimate uses. Cheat files found on a RAM disk are scored like files elsewhere.

5.7Anti-forensics

The anti-forensics check detects trace-removal and cleaning tools. Its findings are recorded with a weight of zero: they increase the detection count D but not the score S. A cleaner is not evidence of cheating, but when it appears together with other findings it makes a pattern more credible (Section 7.2).

6Name matching

Most checks reduce to one question: does this file or process name refer to a known cheat? The remote configuration supplies a list of cheat names C and a list of exact names E. At scan start the engine expands C into E by adding the .exe and .dll forms of every name. Names are normalised (lower case, forward slashes turned into backslashes, whitespace trimmed) before comparison.

Definition 1 (exact match). A normalised name x is an exact match if x ∈ E.
Definition 2 (fuzzy match). x is a fuzzy match for token c ∈ C ∪ E if x starts or ends with c, or contains c immediately preceded or followed by a delimiter δ ∈ {_, -, ., space, \}.

The delimiter rule keeps short tokens from matching inside unrelated words, which a plain substring test would do. Table 5 illustrates it with a fictitious cheat token aimx.

Table 5. Matching behaviour for the fictitious token aimx.
Normalised nameExactFuzzyReason
aimx.exeYesYesIn expanded exact list
aimx_loader.exeNoYesPrefix
tools\aimxNoYesSuffix, preceded by \
claimxyz.exeNoNoToken inside a word, no delimiter
gaimx.dllNoYesToken followed by . (a known source of false positives)

The last row shows the rule's weak point: a token followed by the extension dot matches even when a letter precedes it. This is one reason fuzzy matches carry low weights, and one reason whitelist substrings are applied before matching.

7Evidence scoring model

Every finding i has a strength si ∈ {Weak, Medium, Strong} and a weight wi ≥ 0. The engine keeps the score S and the detection count D:

S = Σi wi ,    D = |{ i }|(2)

The verdict function V(S, D) is:

V = CHEAT DETECTED if S ≥ 999 ∨ (S ≥ 300 ∧ D ≥ 5); SUSPICIOUS if S ≥ 150 ∧ D ≥ 3; else CLEAN (3)
Listing 2. Verdict function (excerpt) ScannerEngine.cs
if (_metrics.Score >= 999)
    FinalStatus = "CHEAT DETECTED";
else if (_metrics.Score >= 300 && _metrics.TotalDetections >= 5)
    FinalStatus = "CHEAT DETECTED";
else if (_metrics.Score >= 150 && _metrics.TotalDetections > 2)
    FinalStatus = "SUSPICIOUS";
else
    FinalStatus = "CLEAN";
Verdict regions by detection count and score, with the case-study scan before and after the fixes 0150300 600999 0235 7911 Detections D Score S CHEAT DETECTED (single decisive finding) CHEAT DETECTED SUSPICIOUS CLEAN pre-fix build: D=11, S=395 with trust model: D=5, S=130
Figure 3. Verdict regions of Eq. (3), drawn to scale for D = 0–12 and S = 0–1100. The points mark the case-study scan of Section 11 before and after the false-positive fixes.

7.1Weight classes

The weights in Appendix A fall into four classes (Figure 4). Exact-name hits in execution history, persistence and file locations carry 1000 and decide the verdict alone. Hash and removable-media hits carry 30–520. Heuristic hits carry 10–70, and environmental indicators 3–10. The gap of more than an order of magnitude between classes is intentional: no realistic number of environmental indicators adds up to a decisive finding.

Weight classes on a logarithmic scale 1101001000 Environment Heuristic Hash / USB Exact name log scale; dashed line: S = 100
Figure 4. Weight ranges of the four evidence classes on a logarithmic axis (x = 90 + 170·log10w). Ranges are taken from Appendix A.

7.2Properties of the decision rule

Monotonicity. Because all weights are non-negative, adding a finding never lowers S or D, and V is monotone in both. A player cannot improve a verdict by producing extra findings.

Decisive findings. Every finding with w ≥ 999 produces CHEAT DETECTED regardless of D. These are reserved for exact matches in places where a legitimate program with that name is implausible.

Corroboration. Without a decisive finding, CHEAT DETECTED needs at least five findings and 300 points. Since heuristic weights are at most 70, at least five independent heuristic hits are needed, which is the property that protects against single noisy checks. SUSPICIOUS needs three findings and 150 points.

Zero-weight findings. Anti-forensic findings raise D without raising S. Two such findings plus one Strong heuristic hit of 150 points or more would be SUSPICIOUS, while the same hit alone would be CLEAN. This lets context make a pattern more credible without ever creating a score.

Up to v0.0.9 the connected server was also registered as a Weak finding worth 5 points. It raised D for every connected player and could satisfy the D ≥ 3 condition on its own together with two unrelated findings. From v0.0.10 the server is metadata and not a finding.

8Game identification

The client enumerates processes once at scan start and classifies them (Table 6). If several games are running, a fixed priority selects one, Counter-Strike titles first. The chosen process ID is kept, so the engine can later tell whether the game exited during the scan, which the report flags.

Table 6. Process-to-game classification.
PriorityGameProcess imageDisambiguation
1Counter-Strike 2cs2.exeNone needed
2CS:GOcsgo.exeNone needed
3CS 1.6hl.exe, cstrike.exeWindow title, install path, or -game cstrike argument
4FiveMFiveM_*GTAProcess.exeBuild suffix ignored
5RobloxRobloxPlayerBeta.exeStore build identified by window title
6Minecraft (Java / Bedrock)javaw.exe, Minecraft.Windows.exeJava: window title or launch arguments
Listing 3. Classification of GoldSrc processes (excerpt) GameDetector.cs
private static bool IsCs16Hl(Process p)
{
    if (SafeTitle(p).Contains("counter-strike", OrdinalIgnoreCase))
        return true;
    // ... install path check ...
    string cmd = GetCommandLine(p.Id);           // WMI Win32_Process
    return cmd.Contains("cstrike", OrdinalIgnoreCase) || cmd.Length == 0;
}

Module and memory inspection (Section 10) is restricted to Counter-Strike titles. The Java virtual machine and FiveM's JavaScript engine compile code at run time into private executable memory, and Minecraft extracts native libraries to the temporary folder. Applying the same heuristics to those games would mostly produce noise.

9Server attribution

Administrators want to know which server a player was on at scan time, ideally by domain name (e.g. go.mortall.ro). Counter-Strike clients talk to servers over UDP, which has no connection state. So the Windows socket table [10] lists the game's local UDP port but not the remote peer. The v0.0.9 approach read the TCP table instead, which lists Steam's service connections, and in practice returned the wrong address. It also declared the UDP row with two fields that do not exist in the owner-PID row format, which misaligned every entry.

9.1Passive endpoint observation

The client asks Windows for the UDP ports the game process owns, then opens a raw IPv4 socket in receive-all mode [11] on each active interface for up to 3 s. For each UDP datagram it examines only the IP and UDP headers. If the destination port is a game port, the source is a candidate; if the source port is a game port, the destination is. Private, loopback, link-local, carrier-grade NAT and multicast addresses are discarded. Observation stops early once one candidate reaches 40 packets, and the candidate with the most packets is chosen if it has at least 3. No payload is stored.

Listing 4. Header-only classification of captured datagrams (excerpt) ServerProbe.cs
if (len < 28 || buf[9] != 17) continue;          // IPv4 protocol 17 = UDP
int ihl = (buf[0] & 0x0F) * 4;                  // IP header length
var src = new IPAddress(buf.AsSpan(12, 4));
var dst = new IPAddress(buf.AsSpan(16, 4));
int sp = (buf[ihl] << 8) | buf[ihl + 1];
int dp = (buf[ihl + 2] << 8) | buf[ihl + 3];

if (gamePorts.Contains(dp) && !IsPrivate(src)) key = $"{src}:{sp}";  // inbound
else if (gamePorts.Contains(sp) && !IsPrivate(dst)) key = $"{dst}:{dp}"; // outbound

9.2Name resolution and verification

The chosen endpoint is queried with A2S_INFO [13]. Newer servers answer with a 4-byte challenge (type 0x41), which the client appends to a second request. Source servers reply with type 0x49, where the name follows a protocol byte. GoldSrc servers reply with the older type 0x6D, where the name follows the server address. Community servers usually include their domain in the name, e.g. “[CS:GO] ★ GO.OLDISGOLD.RO ★ [COMPETITIVE] 128 TICK”. The client extracts every domain-shaped token and accepts one only if forward DNS resolution returns the observed IP address. This check stops a server from claiming someone else's domain. Without a verified domain, the stored value is the plain IP:port.

Server attribution pipeline from UDP port lookup to verified domain UDP portsowned by game PID Raw capture≤ 3 s, headers only A2S_INFOserver name DNS checkname token → same IP? Stored valuedomain or IP:port no capture → +connect launch argument not connected → last server from Steam history, marked LAST
Figure 5. Server attribution. Solid arrows are the main path and dashed arrows are fallbacks.

9.3Last-played server

Players often scan from the main menu. In that case the client reads Steam's server-browser history (serverbrowser_hist.vdf), which records each server's address and a LastPlayed Unix timestamp. It selects the most recent entry, resolves it as in Section 9.2, and stores it with a (last) suffix. The panel shows it with a LAST label, and a live observation with a LIVE label. When a scan carries no server, the panel falls back to the player's most recent known server from earlier scans, also labelled LAST.

Table 7. Outcomes of server attribution.
SituationStored valuePanel label
Connected, domain in name verified by DNSgo.example.roLIVE
Connected, no verifiable domain203.0.113.7:27015LIVE
In menu, Steam history availablego.example.ro (last)LAST
No server on this scan, earlier scan has one(unchanged)LAST, from history
No informationempty—

10In-process and kernel inspection

10.1Running processes

Every running process name is tested for exact (Strong, 1000) and fuzzy (Strong, 30) cheat-name matches. A short built-in list of debuggers, memory editors, structure-reversing tools and injectors adds a Medium finding (25) when one is running during the scan.

10.2Module enumeration across bitness

The client is a 64-bit process, while CS:GO and CS 1.6 are 32-bit processes under WOW64 [12]. The .NET Process.Modules collection returns only the 64-bit WOW64 support modules of such a process, so the game's own 32-bit DLLs, where an injected cheat would be, were never examined before v0.0.10. The client now takes a Tool Help snapshot that requests both module classes [8].

Listing 5. Bitness-independent module snapshot (excerpt) Native.cs
// Includes 32-bit modules of WOW64 games (csgo.exe, hl.exe)
IntPtr snap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, (uint)pid);
var me = new MODULEENTRY32W { dwSize = (uint)Marshal.SizeOf<MODULEENTRY32W>() };
if (Module32FirstW(snap, ref me))
    do list.Add((me.szModule, me.szExePath, me.modBaseAddr, me.modBaseSize));
    while (Module32NextW(snap, ref me));

Each module is then subjected to five ordered tests: cheat-like name (Strong, 45), configured name hint (Medium, 30), load location in a temporary, download, desktop or removable path outside the game folder (Medium, 25), missing backing file (Strong, 50) and known cheat hash (Strong, 60). A module is reported at most once per scan. Tests 1–4 are subject to the trust model of Section 11.

10.3Code without a backing image

A cheat DLL that is copied into the game's memory by hand, bypassing the system loader, appears in no module list. The injection check walks the game's address space with VirtualQueryEx and inspects every committed region that is private (not file-backed) and executable. If such a region begins with a valid PE header (MZ signature and a PE\0\0 signature at the offset given by e_lfanew), the check reports a Strong finding (60), because a complete program image was placed there manually. This mirrors the approach of memory-forensics tools [6], applied to the live process.

Listing 6. PE header test on private executable memory Injection.cs
private static bool LooksLikePe(byte[] b)
{
    if (b[0] != 'M' || b[1] != 'Z') return false;
    int e = BitConverter.ToInt32(b, 0x3C);                   // e_lfanew
    return e > 0 && e < b.Length - 4 &&
           b[e] == 'P' && b[e + 1] == 'E' && b[e + 2] == 0 && b[e + 3] == 0;
}

A pre-release build also flagged large read-write-execute regions without a header. The case study (Section 11) showed that ordinary CS:GO sessions contain such regions, so that heuristic was removed before release.

10.4Kernel drivers

Kernel-mode cheats are usually loaded through a legitimately signed but vulnerable driver, a technique documented by community projects that catalogue such drivers [14]. The driver check lists loaded drivers with EnumDeviceDrivers and compares their exact file names against two short lists: drivers of cheat and memory tools (Strong, 60), and drivers with known abuse histories that are rarely loaded on a gaming PC (Medium, 30). Exact comparison replaced substring matching after it produced accidental hits.

11False-positive mitigation

During testing, a pre-release build of v0.0.10 returned CHEAT DETECTED for a clean machine running CS:GO. Table 8 breaks the result down.

Table 8. Case study: findings on a clean CS:GO machine before and after the fixes.
Finding groupHitsS beforeS afterCause
“Module has no file on disk”52500GPU driver DLLs reported under a WOW64 path that does not exist
Large RWX regions1150Heuristic removed (Section 10.3)
Browser history (1 site, 4 searches)5130130Unchanged; remote keyword list
Total11 → 5395130CHEAT DETECTED → CLEAN
Stacked score before and after the fixes: 395 versus 130 Before 395 After 130 S = 150 S = 300 GPU-driver false positives (250) RWX heuristic (15) Browser (130)
Figure 6. Score composition for the case-study machine, to scale (1.2 px per point). After the fixes only the browser findings remain, below the SUSPICIOUS threshold.

11.1WOW64 path translation

For a 32-bit process, Windows reports system paths under SysWOW64 [12]. The graphics driver store exists only under System32\DriverStore, so every GPU user-mode driver had a reported path that does not exist, failed the existence test and was scored as “no file on disk”. Paths are now translated back before testing.

Listing 7. Path translation before the existence test ModuleTrust.cs
if (File.Exists(path)) return path;
string alt = path.Replace(@"\SysWOW64\", @"\System32\", OrdinalIgnoreCase);
if (alt != path && File.Exists(alt)) return alt;

11.2Trust model

Games also load overlays, recorders, audio processing, peripheral software and antivirus hooks, which resemble injected code. Any module that a heuristic test would flag goes through three trust tests (Figure 7). Exact names, known hashes and the manual-mapping check are never suppressed.

Trust decision: Windows directory, known legitimate module, valid vendor signature Heuristicwould flag module In Windows dir?admin-writable only Known module?and not in a drop folder Signed by vendor?WinVerifyTrust + signer Not reported Reported nono yesyesyesno
Figure 7. Trust decision for a module that a heuristic would flag. The module is suppressed if one test passes; otherwise the finding is reported.
  1. Windows directory. The file exists under the Windows directory (System32, SysWOW64, WinSxS, DriverStore), excluding Windows\Temp. Writing there requires administrator rights.
  2. Known module. The file name is on a curated list of about 250 components seen in the supported games (GPU drivers, overlays, capture tools, audio and peripheral software, security products, game runtimes), and the module is not in a temporary, download or desktop folder. Common proxy-DLL names such as d3d9.dll and dxgi.dll are deliberately excluded, because cheats use them to disguise themselves.
  3. Vendor signature. The file has a valid embedded Authenticode signature, verified with WinVerifyTrust [9] (file hash and chain; revocation only from cache, no network access), and the signer is a known vendor. Results are cached per path for the scan.

The contents of the trust lists are not published, to avoid giving cheat authors a list of names and signers to imitate.

12The review platform

The public website at aacguard.com hosts the client download, documentation (features, changelog, trust centre, privacy, terms, cookies and GDPR pages), a list of partner servers and the review panel. The landing page shows live counters: at the time of writing, 11,181 scans completed, 3,658 players flagged and 52 new detections in the last 24 hours.

12.1Data model

Figure 8 shows the tables used by the panel. A scan belongs to a user, identified by Steam ID. Configuration files and the automated interpretation are stored in separate tables keyed by scan, and bans refer to users.

Entity-relationship diagram of users, scans, cfg files, AI analysis and bans users user_id (PK)steam_idsteam_name scans id (PK)user_id (FK)scan_time · created_at client_versionfinal_statusscore · total_detections total_checksgame_process_namelast_server_ipport game_exitedbrowsers_detectedoperations_json log_textmasked_ip scan_cfg_files scan_id (FK)file_path · file_nameis_userdata_cfg · content scan_ai_analysis scan_id (FK)ai_verdict · ai_text bans user_id (FK) 1N 1N 11 1N
Figure 8. Data model of the review platform (simplified; only columns used by the panel are shown).

12.2Panel views

Detected players. A paginated, searchable list (by Steam name or ID) of scans, newest first, with player, Steam ID, game, server (LIVE/LAST, copyable), verdict, time and ban status. Scans made with clients older than 0.0.4 after February 2026 are excluded. A version comparison bug hid new scans and was fixed by comparing versions numerically instead of as text:

Listing 8. Numeric version filter detected.php
-- lexical comparison ranked '0.0.10' below '0.0.4' and hid all new scans
AND INET_ATON(CONCAT(s.client_version, '.0')) >= INET_ATON('0.0.4.0')

Scan view. One page per scan with the player's Steam avatar (read from the public profile and cached for 24 hours), a link to the Steam profile, a copyable Steam ID, game and server, metrics, a plain-language summary generated from the log, per-check status, the collected configuration files with a viewer, the raw log, and the player's other scans.

Player lookup. Resolves a user name, SteamID64, legacy SteamID or profile link to a SteamID64 (via the Steam Web API's vanity-URL resolution where needed) and shows the Steam profile summary, VAC and game-ban status, and the player's AACGUARD scan history. Where configured, it adds public FACEIT statistics (level, Elo, K/D, win rate, headshot rate) and lifetime Counter-Strike statistics from the Steam API (K/D, accuracy, headshot rate, matches won).

12.3Automated interpretation

Each scan can receive an automated, language-model-based interpretation stored in scan_ai_analysis, with one of four verdicts (CLEAN, CHEATER, SUSPECT, IDK) and a short text. The panel labels it as a beta feature and warns that the model has no internet access and bases its reading only on the scan data. It is advisory: the scanner's own verdict (Eq. 3) is computed independently and is not changed by the interpretation.

12.4Time presentation

Timestamps are stored in UTC. The panel sends them as ISO-8601 values in <time> elements and converts them in the browser to each visitor's time zone, while the stored data stays unchanged. Without JavaScript the UTC value is shown with a label.

13Operational characteristics

We report the timing of the case-study scan from its log, which has a resolution of one second. The machine had six fixed drives (about 4.1 TB in total), three browsers and a running CS:GO client connected to a community server. The scan performed 188,830 individual checks and took 17 s from start to verdict (Table 9, Figure 9).

Table 9. Stage durations of the case-study scan.
StageSeconds
Prefetch, BAM, MUICache< 1
AppData11
Recycle Bin, Downloads/Desktop1
CS directory, USB< 1
Browser history1
AmCache, ShimCache, Run keys< 1
Shortcuts2
Processes, modules, server, injection1
Environment, anti-forensics, CFG1
Total17
Bar chart of stage durations; AppData dominates with 11 of 17 seconds AppData Shortcuts Recycle/Downloads Browser Live system Env./CFG Other (<1 s each) 0510 s
Figure 9. Stage durations (20 px per second). Enumerating AppData accounts for about two thirds of the scan.

Server attribution completed within the same second as module inspection: the early-stop condition was reached well before the 3-second capture limit on an active connection. The AppData stage dominates because it walks deep directory trees. It is the natural target for optimisation, for example by restricting depth or parallelising enumeration.

At the deployment level, 3,658 of 11,181 scans (32.7%) had been flagged, meaning a verdict other than CLEAN. Because players are usually asked to scan because they are suspected, this is not an estimate of cheating prevalence in the general population, and without ground truth it is not a measure of precision either.

14Privacy and ethics

A forensic scanner looks at personal data by nature, so AACGUARD follows data minimisation. The website states that the tool collects only what anti-cheat needs (Steam ID, Steam name, scan metadata, verdicts and game-related data such as non-default configs), runs only when the player presses Start or Restart, and does not run in the background. The download page states that scans are logged and associated with the player's Steam account for administrators to review. Table 10 summarises what is stored and how it is protected.

Table 10. Data stored per scan and its protection.
DataPurposeProtection
Steam ID and nameAssociate scans with a playerPublic Steam identifiers only
Public IP addressDetect shared or duplicated identitiesStored masked
Scan log and file pathsHuman review of findingsWindows user names masked as C:\Users\***\ on display
Game configuration filesCheat-specific settingsOnly Counter-Strike .cfg files
Browser findingsEvidence of acquisitionOnly matching URLs are logged, not the full history
Connected serverContext for administratorsPublic address or domain only
Network captureServer attributionHeaders of the game's own UDP traffic, in memory, ≤ 3 s, nothing stored

Two ethical risks deserve mention. First, a false CHEAT DETECTED verdict can lead to a ban and public listing. The design answers this with conservative thresholds, the trust model, full logs and a dispute process described on the website. Second, the public list of detected players names individuals, so listing should follow administrator review, not the automated verdict alone.

15Limitations and threats to validity

16Future work

17Conclusion

AACGUARD shows that a user-mode scanner can give community-server administrators a structured and reviewable basis for moderation decisions. The scanner combines standard Windows forensic artifacts with live inspection of the game process, expresses every finding as weighted evidence, and uses a decision rule that requires either one decisive finding or several corroborating ones. Version 0.0.10 adds game and server context to every report, extends inspection to the 32-bit processes where Counter-Strike cheats run, and removes a class of false positives that could label clean players as cheaters, while keeping the verdict thresholds unchanged so that scores stay comparable with earlier reports. The main open problem is evaluation at scale, which requires labelled outcomes from administrator review.

AAppendix A: Detection catalogue

All findings the v0.0.10 client can register, with strength and weight w. Prefetch weights follow Eq. (1). “Exact” and “cheat-like” refer to Definitions 1 and 2. Anti-forensic findings have w = 0 by design.

Table 11. Detection catalogue.
SourceFindingStrengthw
PrefetchExecution trace, exact nameStrong/Medium1005–1040
PrefetchExecution trace, cheat-like nameMedium/Weak35–70
BAMExecution trace, exact nameStrong1000
BAMExecution trace, cheat-like nameMedium20
MUICacheExact nameStrong1000
MUICacheCheat-like nameWeak8
AmCacheExact nameStrong1000
AmCacheCheat-like nameMedium20
ShimCacheExact nameStrong1000
ShimCacheCheat-like nameMedium20
AppDataExact cheat fileStrong1000
AppDataKnown cheat hashStrong40
AppDataSuspicious fileMedium10
Downloads/DesktopExact cheat fileStrong1000
Downloads/DesktopKnown cheat hashStrong50
Downloads/DesktopCheat-like fileStrong35
Downloads/DesktopLoader/injector-like fileMedium20
Recycle BinExact cheat file (deleted)Strong1000
Recycle BinCheat-like file (deleted)Medium20
CS directoryExact cheat-like module in game folderStrong1000
CS directoryKnown cheat hashStrong50
CS directoryPotential injection moduleStrong40
USBRecent executable, known cheat hashStrong510–520
USBRecent executable, exact nameStrong260–270
USBRecent executable, cheat-like nameMedium/Weak35–45
BrowserCheat site and search in same browserStrong60
BrowserCheat site visitedMedium50
BrowserCheat-related searchWeak20
Run keysStartup entry, exact nameStrong1000
Run keysStartup entry referencing cheatMedium20
ShortcutsSee Table 4—3–1000
ProcessesExact cheat processStrong1000
ProcessesCheat-like processStrong30
ProcessesDebug / memory tool running †Medium25
ModulesKnown cheat hashStrong60
ModulesNo backing file on diskStrong50
ModulesCheat-like nameStrong45
ModulesSuspicious name hintMedium30
ModulesLoaded from suspicious pathMedium25
Injection †Manually mapped PE imageStrong60
Drivers †Cheat/tool kernel driverStrong60
Drivers †Driver abused by kernel loadersMedium30
CFGContains cheat nameMedium25
CFGHvH / rage settingsMedium20
CFGCheat-related keywordWeak10
RAM diskExact cheat executable on RAM diskStrong40
RAM diskKnown cheat hash on RAM diskStrong30
RAM diskCheat-like executable on RAM diskMedium20
RAM diskRAM drive presentMedium8
RAM diskTEMP or browser data on RAM diskWeak4
RAM diskRAM-disk software (files, service, uninstall entry)Weak3–4
VirtualizationVM-related installer eventMedium10
VirtualizationVM software, process, baseboard or uninstall entryWeak5
Anti-forensicsCleaner / trace-removal toolvaries0

BAppendix B: Glossary

A2S_INFO
Valve's UDP query that returns a game server's name, map and player count [13].
AmCache / ShimCache
Windows compatibility databases that record programs present on or run by the system.
BAM
Background Activity Moderator; a Windows service whose registry data records executable paths and last-run times per user.
External cheat
A cheat running as its own process that reads or writes game memory.
HvH
“Hack versus hack”; servers or settings for players who openly use cheats against each other.
Internal cheat
A cheat running inside the game process, usually as an injected DLL.
Manual mapping
Loading a DLL by copying it into another process's memory without the system loader, so it does not appear in module lists.
PE
Portable Executable; the file format of Windows executables and DLLs.
Prefetch
Windows start-up optimisation files that also record which executables have run.
Vulnerable driver
A legitimately signed kernel driver with a flaw that lets user-mode code read or write kernel memory; used to load unsigned kernel cheats.
WOW64
The subsystem that runs 32-bit programs on 64-bit Windows, including file-system path redirection [12].

References

  1. J. Yan and B. Randell. A systematic classification of cheating in online games. In Proc. 4th ACM SIGCOMM Workshop on Network and System Support for Games (NetGames), 2005.
  2. C. Dorner and L. D. Klausner. If it looks like a rootkit and deceives like a rootkit: A critical examination of kernel-level anti-cheat systems. In Proc. 19th International Conference on Availability, Reliability and Security (ARES), 2024.
  3. S. Collins, A. Poulopoulos, M. Muench and T. Chothia. Anti-cheat: Attacks and the effectiveness of client-side defences. In Proc. ACM Workshop on Research on Offensive and Defensive Techniques in the Context of Man At The End (CheckMATE), 2024.
  4. H. Carvey. Windows Registry Forensics, 2nd ed. Syngress, 2016.
  5. B. Lagny. Analysis of the AmCache. ANSSI technical report, 2019.
  6. M. H. Ligh, A. Case, J. Levy and A. Walters. The Art of Memory Forensics. Wiley, 2014.
  7. P. Yosifovich, A. Ionescu, M. E. Russinovich and D. A. Solomon. Windows Internals, Part 1, 7th ed. Microsoft Press, 2017.
  8. Microsoft. CreateToolhelp32Snapshot function (tlhelp32.h). learn.microsoft.com
  9. Microsoft. WinVerifyTrust function (wintrust.h). learn.microsoft.com
  10. Microsoft. GetExtendedUdpTable function (iphlpapi.h). learn.microsoft.com
  11. Microsoft. SIO_RCVALL control code. learn.microsoft.com
  12. Microsoft. File System Redirector. learn.microsoft.com
  13. Valve Developer Community. Server queries. developer.valvesoftware.com/wiki/Server_queries
  14. LOLDrivers: Living Off The Land Drivers. loldrivers.io
  15. Valve. Steam Datagram Relay. Steamworks documentation. partner.steamgames.com
  16. AACGUARD. Project website, features, changelog and privacy policy. aacguard.com, accessed September 2026.

© 2026 The AACGUARD Project · Source code is proprietary; listings are abridged excerpts for explanation only.