I have recently tried to come back to developing anti-tamper / anti-cheat software for Roblox (that should ideally detect most of the exploits). Roblox removed the ability to reference services which the security capability doesn’t have access to (e.g referencing CoreGui on the client will return nil). I’ve also tried to study some scripts (which includes some init scripts aswell that are coded in Lua) to try to find vulnerabilities which could detect them. My question is are there any methods you could use to detect executors like Xeno since they are easily detectable (external and the entire init script is written in Lua). I’ve also heard of detecting hooked functions but all of the threads I read about such topics say that these methods are patched. I’m not asking for code snippets, but rather a guide on how to detect these and if there are any alternatives to the good old ‘detect GUI’s added into CoreGui’. Also if someone explained the whole metatable hooking stuff aswell, that would be great.
Trying to detect the executor itself usually is not the best route, because exploit methods change all the time and client checks can be bypassed.
The safer approach is to assume the client can be tampered with, then make the server check whether what the client is asking for actually makes sense.
For example:
if a remote says a player dealt damage, the server should verify they were actually close enough
if a remote says an ability was used, the server should verify cooldowns and state
if a remote sends movement or position related info, the server should sanity check it
if a remote is fired in a weird order or with values you never expect, log it
So instead of asking “is this player exploiting”, it is usually better to ask “is this action even possible”.
You can still use client side checks as an extra layer, but not as your main defence.
A good practical idea is to set up logging for suspicious remote activity. For example, send a webhook to a private Discord server whenever:
a remote is fired with unexpected arguments
a player fires something too fast
a remote is called in an impossible state
a client tries to use something they should not even have access to
That way you are not only blocking obvious abuse, but also collecting info on new methods people try.
So in short, I would focus more on strong remote validation, sanity checks, and logging than on trying to directly detect something like Xeno itself.
@Lukaa_Playz’s reply is perfect for your question.
Just so you also know, exploiting is monumentally harder than it used to be (after the Synapse X “betrayal”). Any new exploits are either detected right off the bat or patched within a week. The ones that slip through are often locked beyond a paywall, and not a cheap one at that, which already makes them inaccessible to an overwhelming majority of exploiters. The consequences have advanced too, ban waves can hit all of your (current and future) accounts simultaneously if Roblox has as little information as your typing pattern that can connect them. The “elite” who are behind finding exploits also face lawsuits now.
For most games today, even for ones with vulnerabilities, an anti cheat is not necessary if you don’t have a persistent & pre-existing exploiter problem.
I always tried to go for exploit detection but I could try this and apply obfuscation (maybe?) so it doesn’t get reversed easily. Thanks for the advice!
Heya! Sorry for the random re-appearance but a big part of my anticheat is trying to detect and intercept saveinstance (and intercepting exploit injection / init scripts). Any way on doing that? The part that concernes me the most is the saveinstance part.
There’s a cheap hack you can do to detect one of the services “USSI” uses.
Though, for something like individual decompile(script) runs, there is currently no public tech that easily prevents it.
If you’re trying to protect the map instead, you would probably have to do custom streaming, to make sure the client doesn’t have the full map.
I already have that implemented, but if the executor devs were competent and added a custom gethiddenproperty function which doesn’t rely on UGCValidationService, you can easily bypass this (which is the case with most executors), so I was trying to detect the executor itself instead (or any USSI detections there could possibly be..)