Anti-Tamper system

Hello this is a funny little system that I made which makes exploiting games that one more bit a teeny bit harder.

Things it detects:
Exploit scripts possibly infinite yielding
if any executor other than synapse calls the error() function for some reason
A list of blacklisted instances which you can change
exploiters putting exploit guis into PlayerGui (kinda)
and a few other things that I won’t list for the purpose of detecting more noobs

You can easily change what Instances are blacklisted by simply remove or adding the instance to the BlacklistedInstance folder on the client, yes I do know that this can be bypassed but it does make your game harder to exploit also I do know that most exploits put their gui in CoreGui but the playergui detection is to purely detect free executors and people who simply forgot to parent their gui to CoreGui

Link to model: AntiTamper - Roblox
(sorry about the outdated method that I used to use to hide scripts from getnilinstances() and dex :frowning: executor devs found out)

btw please read the README script to avoid the system breaking

Enjoy! (also working on some other cool things and sorry if it’s a bit unoptimized)

6 Likes

what videos of me using an executor?

I gonna test this system someday and I guarantee that it’s gonna be good.

I have a few questions and concerns:

  1. How does FunctionalTest bypass getnilinstances?
  2. A lot of games use these specific Instances:
    image
    Wouldn’t it be a better idea to limit the detection to the character instead of the whole game?
  3. Error message generated by developers would trigger this anti cheat.
  4. The TamperingDetecter script could be obtained by using getscripts (or whatever it’s called) and calling Destroy on it would halt it. Parenting it to the “untouchable” FunctionalTest is redundant.

I only skimmed the code as reading any further made my head hurt, so forgive me if I misread a thing or two. Here’s the code for those who are curious.

TamperingDetecter
script.Parent = Instance.new("FunctionalTest") -- parents the localscript to somewhere dex and getnilinstances() can't see
local AntiTamperFolder = game:GetService("ReplicatedFirst").AntiTamperClient -- gets the AntiTamperFolder so it's ready to be deleted when everything is set up
local Player = game:GetService("Players").LocalPlayer
local BlacklistedInstances = AntiTamperFolder.BlacklistedInstances -- gets the blacklisted folder so it's ready to be deleted
local ReplicatedStorage = game:GetService("ReplicatedStorage") -- gets ReplicatedStorage for the remote
local LogService = game:GetService("LogService") -- gets log server for detected if an exploiter calls the error() function
local AntiTamperRemote = ReplicatedStorage:WaitForChild("AntiTamperRemote") -- grabs the AntiTamperRemote from ReplicatedStorage
AntiTamperRemote.Parent = Instance.new("FunctionalTest") -- parents the RemoteEvent to somewhere dex and getnilinstances() can't see or call it from
local FireServer = AntiTamperRemote.FireServer -- gets the funciton to fire to the server to avoid __namecall hook detection used to spy on remotes __index hooks are less common for remote spies
local Blacklist = {} -- creates a table for blacklisted instances
local LastHistoryLength -- creates a variable for the last length of the log history table

_G.AntiCheatEnabled = true
shared.AntiCheatEnabled = true

--[[WARNING!]]--

--[[
	Do Not Edit This Script Unless You Know What You're Doing.
]]--

for _,Instance in ipairs(BlacklistedInstances:GetChildren()) do -- loops through all the instances in the blacklisted folder
	Blacklist[Instance.ClassName] = true -- inserts the instance's classname into the blacklist table
end

AntiTamperFolder:Destroy() -- destroys the AntiTamper folder so the exploiter doesn't know it's in the game and also to stop false flags from the instances in the blacklisted folder

local function ReportToServer(Type : string, Args) -- creates a function to report odd behaviour to the server using the FireServer function we got earlier
	AntiTamperRemote.Parent = ReplicatedStorage -- parents the remote to ReplicatedStorage so the messages can be sent to the server
	FireServer(AntiTamperRemote, Type, Args) -- calls the FireServer function
	AntiTamperRemote.Parent = Instance.new("FunctionalTest") -- reparents the remote to somewhere dex and getnilinstances() can't see
end	

Player.PlayerGui.ChildAdded:Connect(function(Gui) -- runs callback function if a gui is added to playergui
	if Gui.Name:lower():find("dex") or Gui.Name:lower():find("hub") then -- checks gui's name for odd things
		ReportToServer("G", Gui)
	end
	for _,Obj in ipairs(Gui:GetChildren()) do -- checks gui's children's name for odd things
		if Obj.Name:lower():find("dex") or Obj.Name:lower():find("hub") then
			ReportToServer("G", Gui)
		end
	end
	for _,Obj in ipairs(Gui:GetDescendants()) do -- checks gui's descendant's name for odd things
		if Obj.Name:lower():find("dex") or Obj.Name:lower():find("hub") then
			ReportToServer("G", Gui)
		end
	end
end)

coroutine.resume(coroutine.create(function()
	while task.wait(.5) do
		if not _G.AntiCheatEnabled or not shared.AntiCheatEnabled then
			ReportToServer("H")
		end
	end
end))

coroutine.resume(coroutine.create(function() -- creates a seperate thread and runs it so it doesn't stop the further code from working
	while task.wait(.5) do 
		for _,Obj in ipairs(game.GetDescendants(game)) do -- loops through every descendant of game using but calls the function using the __index metamethod instead to make hooking a bit trickier
			if Blacklist[Obj.ClassName] then -- if it finds an instance with a blacklisted ClassName then the code below runs
				ReportToServer("B", Obj.ClassName) -- reports the blacklisted Instance's classname to the server
			end
		end
	end
end))

while task.wait(1) do 
	if not LastHistoryLength then -- if the LastHistoryLength variable hasn't been set yet then it sets it to the length of the returned table from the GetLogHistory() function
		LastHistoryLength = #LogService:GetLogHistory()
	else
		if #LogService:GetLogHistory() > LastHistoryLength then -- if there has been a new message sent to the console then the code below runs
			ReportToServer("L", LogService:GetLogHistory()[LastHistoryLength+1]) -- reports the new message to the server
			LastHistoryLength += 1 -- increases the variable by 1 to avoid duplicate reports
		end
	end
end

I feel like this is the problem with most “anti cheats” posted here. They just shove all detections known to mankind and call it an “anti cheat” or other derivatives.

5 Likes

This anticheat is terrible, not only does it cause insane amounts of lag but it also does not work when you are auto-exec and delete the instances folder, 30 different bypasses to this + free executors are support CoreGui. This is not year 2018 lol

2 Likes

FunctionalTest used to bypass getnilinstances() but it still makes the script harder to find, the instances in the folder can easily be changed by literally adding or removing them like I stated, it shouldn’t false flag because it sends the error message to the server to validate if it’s an exploit script or not, I have already tried reparenting the script and calling destroy on it and it did nothing

I know it can be bypassed that’s not the point, it is simply there to make exploiting the game that tad bit harder and it also relies on the exploit developer’s human error mostly, I don’t see how it causes insane amounts of lag but I will check it out.

1 Like

Not to mention you can just draw a GUI to the screen itself to bypass any detections

1 Like

I don’t think you can draw an entire functioning gui, at least not to my knowledge

This is a system that relies on human error mostly, yes it can be bypassed I know that I know everything that you’re gonna say about it (yes I do know that basically everything can be bypassed by hooking task.wait) but that’s not the point, the point is to detect human error like misspelling an Instance name.

I don’t trust your system if this is your introduction.

No exploit does this.

You linked the source code for the anti-exploit?

It wasn’t outdated, it was just wrong. I believe it was just parenting the script to a ‘FunctionalTest’, which is just a random instance parented to nil. Same difference.


(quoting because I can’t open the model right now)

Why is the Highlight instance blocked? I use this a lot, I don’t appreciate that I can’t use this anti-exploit without removing my highlights. And yes, you can just remove it from the blacklist, but I use the other instances too. And an exploit can remove these too.

Really?

-- executor:
getrenv()._G.AntiCheatEnabled = nil

If I’m being honest, you need some exploiting knowledge to be able to make an anti-exploit. Or else, you can never know what is very easy to bypass or what actually helps prevent things.

4 Likes

Exploiters could totally go out of their way to manually call low-level rendering API functions to draw UI over Roblox if they really wanted to, but most probably don’t because there is never going to be a way to fully detect exploit GUIs on the developer side, mainly because most of them use the CoreGui and Roblox themselves try very hard to make sure we can’t tamper with that.

1 Like

Lol _G and shared are just honeypots they do literally nothing, read both the server and client code please

I know that this is easy to bypass, stating this for the 3rd or so time: it is simply there to annoy exploiters even more and it relies on human error

About exploiters being able to remove instances I might just add a way to hard code Classnames into a table as well

That is pointless if your method is to annoy exploiters. If barely anyone is going to use this resource, why wouldn’t they move on to the next game? If script kiddies GUI doesn’t work why wouldn’t they just go to a different game…

1 Like

You really don’t understand the point of an anti-cheat

An anticheat is only effective if it is good at its job, the point is to hinder what an exploiter can do, not annoy them. People in this post have already pointed out glaring issues with this, and there are already other anticheats that are more professional that you could use instead of this one. It is also pointless to have a clientside anticheat, because there are already ways to bypass this.

1 Like

having a client-sided anti-cheat isn’t pointless at all, a fair amount of games that know how to use them do use them and they work very well.

1 Like

I do support the usage of client sided anti exploits but this just isn’t it.

this can be fully bypassed by a simple index hookmetamethod or a hookfunction since you call the FireServer through index and not namecall.

2 Likes