Behavioural detection without reading memory
Plenty of detection writing assumes you can look inside the process: scan memory, walk modules, compare code against what it should be. In a large number of real deployments you cannot, and the interesting question is what remains once that option is gone.
Why memory access is often unavailable
- The detection code runs inside a sandboxed scripting environment with no route to arbitrary process memory.
- Shipping a kernel driver to every player is a support and liability commitment most operators cannot make, and one many players will refuse.
- Scanning competes for frames. A check that costs the player performance gets uninstalled, and an uninstalled check detects nothing.
- Reading another process's memory sits close enough to the line that the platform's own rules — and in some jurisdictions the law — are worth reading before you rely on it.
What is left
What survives is everything the environment already tells you as a consequence of being played: input events and their timing, the sequence and frequency of engine calls, state transitions, and network timing. None of it reveals the cheat. All of it reveals how the player is behaving, and tooling behaves differently from hands.
The useful features are almost never averages. They are the second-order properties:
- Variance. Human input is noisy at every scale. Generated input is regular, and regularity is measurable even when the values themselves look plausible.
- Quantisation. Automated input tends to land on a grid — a fixed poll interval, a rounded step. Real motion does not respect grids.
- Autocorrelation. Repetition that is slightly too similar to previous repetition is a stronger signal than any single action being unusual.
- Impossible transitions. Not "unlikely", but sequences the engine's own rules cannot produce. These are rare, and worth far more than the statistical signals because they do not need a threshold.
The real design constraint is the base rate
This is the part that decides whether a behavioural system is worth deploying, and it is arithmetic rather than engineering.
Suppose one player in a thousand is cheating, and you build a test that is 99% accurate in both directions. Run it across ten thousand players: it catches about ten of the ten cheaters, and it also flags about a hundred of the 9,990 honest players. Your flag list is now roughly 90% innocent people, with a test most engineers would call excellent.
A detector's accuracy tells you almost nothing about whether its output can be acted on. The prevalence of what you are looking for decides that.
Which produces three non-negotiable design consequences.
Combine independent signals. Two weak, unrelated signals agreeing is worth much more than one strong signal shouting, because their false positives are uncorrelated while a real cheat trips both.
Require persistence. A single window is noise. The same anomaly across many windows, separated by time, is a pattern. Scoring over a window with a minimum trigger count converts a jumpy detector into a defensible one.
Separate observing from enforcing. Every rule should be able to run in a mode where it records and does nothing. That is not a convenience feature — it is the only honest way to learn what a rule's false positive rate looks like on a specific population before it is allowed to affect anybody.
What to keep
Because these signals are statistical, the record matters more than in any other class of detection. "Your score was high" cannot be defended to a player and should not persuade an operator. What can be defended is the stored series: which signals fired, what the values were, over which windows, and what the configured thresholds were at the time.
Behavioural detection without memory access is not a weaker substitute for inspecting the process. It answers a different question — not "what is running" but "is this being played by a person" — and for that question it is frequently the better instrument. It just has to be built by someone who has done the base-rate arithmetic first.