Instant exploit detection! [Xeno, Solara and more!] (Anti Cheat)

(patched)
Hello, everyone!

Today, I’m releasing a simple yet effective script designed to instantly detect exploits as soon as an injects to your game. This solution is lightweight, easy to understand, and straightforward to implement.

(Tested on Xeno and Solara in my own place.)

Just create a LocalScript under ReplicatedFirst and add your own detection function and its ready to go!

local RunService = game:GetService("RunService")
RunService.PreRender:Connect(function()
	if game:FindService("AppUpdateService\000") then
		warn("Detected") -- CHANGE THIS
	end
end)

74 Likes

You said its easy to understand but how does it work and how do you know it can’t just be bypassed

3 Likes

When exploit tries to inject into current game client, It uses:
game:GetService("AppUpdateService") resulting in initialization of the service in its init script. However, in normal roblox clients, this service is not initialized by default.

FindService only returns if the service is initialized and exists under DataModel.
GetService on the other hand returns the service if it’s initialized, and automatically initializes it if it isn’t.

Using this behavior, you can easily detect exploit injections by checking whether AppUpdateService has been initialized unexpectedly.

Everything can be bypassed, but you can make it significantly harder — even nearly impossible — with the right way.

14 Likes

vouch :heart: :heart: :heart: :heart: :heart: :heart:, ty for sharing

3 Likes

Does every single executor use the AppUpdateService?

3 Likes

This method appears to work on popular exploit clients. I’ve confirmed it with Xeno and Solara. Good luck catching skids until this method gets patched by the “devs”.

7 Likes

What is \000 for and what is the benefit of adding that to AppUpdateService?

1 Like

Probably a null terminator

5 Likes

Can’t you just do this? (I’m pretty sure it is efficient because it doesn’t do it every frame)

local name = "AppUpdateService\000"

local function detected()
	print("Blud")
end

if game:FindService(name) then
	detected()
else
	game.ServiceAdded:Connect(function(service)
		if service.Name == name then -- or game:FindService(name)
			detected()
		end
	end)
end
2 Likes

Pretty sure the performance cost of doing it every frame is neglible since it’s just a single method call, and not being called on a ton of instances at once each frame.

4 Likes

The service itself has a SecurityCapability called RobloxScript. Because of that, game.ServiceAdded does not trigger for AppUpdateService in game scripts.

5 Likes

A weird thing about Roblox instance names is that they actually work like C strings instead of length-based strings, so you can add a null terminator to a string and use it to index instances and any instance matching the string before the null terminator will be returned

5 Likes

Cool, but is this ever useful lol?
Still confused as to why this exploit requires the null terminator.

1 Like

This actually surprised me when I tested and it worked! Keep up good work.

3 Likes

So how come FindService("AppUpdateService") works but not GetService("AppUpdateService")???
Just a question

1 Like

FindService only checks if the service exists, but GetService creates it if it doesnt exist already. The context of a standard script doesn’t have permissions to access the service so it cant create.

That said, you need to see if it exists, so even if it could be created with GetService it would be pretty useless anyway… :sweat_smile:

5 Likes

It actually does create, it’s just that the security level on it prevents you from so much as even trying to print the instance in a normal script, but you can still confirm it actually exists by checking the result of type/typeof:

print(typeof(game:GetService("AppUpdateService")))
4 Likes

How does GetService “Access the service” while FindService doesn’t?

1 Like

Oh, right - thanks for the correction.

1 Like

GetService tries to create the service if it doesnt exist already - some services dont exist by default. FindService doesnt try to create it and just returns it if it already exists - so here, if it exists, you know some injected code has created it (if FindService returns it) because it shouldn’t exist by default.

Tldr:

  • GetService creates the service if it doesnt already exist, meaning it will always “access” the service
  • FindService does not create the service, and returns nil if it doesnt exist

Note that it’s the __tostring invocation on the service (from print) that causes the error, not creating the service.

3 Likes