How To Improve This Anti Exploit Script

Hello there fellow developer,

I am new to roblox dev forum and scripting. I have made this simple anti cheat script, but I am not satisfied with it. It has some lack of security. I want to improve it.
This script prevent hackers to:

  • Fly
  • Btools
  • Have More Jump Power
  • Have More Max Health
  • God Mode
  • Destroy The Script

This is the things that i want to improve:

  • More Secure
  • Doesnt Get Easily Bypassed
  • Hard To Read

This is the first script.

local LocalPlayer = game:GetService("Players").LocalPlayer

repeat wait() until LocalPlayer
repeat wait() until LocalPlayer.Character

local Character = LocalPlayer.Character
local Backpack = LocalPlayer:WaitForChild("Backpack")
local HumanoidRootPart = Character:WaitForChild("HumanoidRootPart")
local Anti = script.Parent:WaitForChild("Anti")
local Bodys = {
	["BodyGyro"] = true,
	["BodyPosition"] = true,
	["Body Velocity"] = true
}
local Btools = {
	["HopperBin"] = true,
}

while true do
	--Anti Btools
	Backpack.ChildAdded:Connect(function(Obj)
		if Btools[Obj.ClassName] then
			LocalPlayer.Character.Humanoid.Health = 0
		end
	end)
	
	--Anti Fly
	HumanoidRootPart.ChildAdded:Connect(function(Obj)
		if Bodys[Obj.ClassName] then
			LocalPlayer.Character.Humanoid.Health = 0
		end
	end)
	
	--Anti FE God / Anti Humanoid Destroyer
	Character.ChildRemoved:Connect(function(Obj)
		if Obj:IsA("Humanoid") then
			LocalPlayer.Character.Humanoid.Health = 0
		end
	end)
	
	--Anti Jump Power
	if LocalPlayer.Character:WaitForChild("Humanoid").JumpPower ~= 100 then
		LocalPlayer.Character.Humanoid.Health = 0
	end
	
	--Anti Speed
	if LocalPlayer.Character:WaitForChild("Humanoid").WalkSpeed ~= 100 then
		LocalPlayer.Character.Humanoid.Health = 0
	end

    --Anti Max Health
	if LocalPlayer.Character.Humanoid.MaxHealth ~= 100 then
		LocalPlayer.Character.Humanoid.Health = 0
	end
	
	--Anti Disable / destroy
	if not script.Parent:FindFirstChild("Anti") then
		game:GetService("ReplicatedStorage"):FindFirstChild("Kick"):FireServer(function()
		end)
	elseif Anti.Disabled then
		Anti.Disabled = false
	end
	wait(0.05)
end

Second script.

local Players = game:GetService("Players")
local LocalPlayer = Players.LocalPlayer
local Main = script.Parent:WaitForChild("Main")

while true do wait()
	if not script.Parent:FindFirstChild("Main") then
		game:GetService("ReplicatedStorage"):FindFirstChild("Kick"):FireServer(function()
		end)
	elseif Main.Disabled then
		Main.Disabled = false
		wait(0.05)
	end
end

Third script

game:GetService("ReplicatedStorage"):FindFirstChild("Kick").OnServerEvent:Connect(function(player)
            player:Kick("No Exploiting")
		end)

Thank you for reading. Sorry if this is not appropriate to the topic. I am new to roblox dev forum. Any suggestion will be accepted.

12 Likes

nice script! One important thing to keep in mind however, is that this is all in a local script, which can be 100% exploited (they can literally delete all of this code). I’d recommend using a regular Script if you want to make a secure anti cheating system.

8 Likes

There’s some unnecessary things in if statements, being object:FindFirstChild("object") == nil. You can just use if not object:FindFirstChild("object") then. Also with the while wait() do, it’s a better practice to use while true do wait() end, more importantly using RunService with Stepped:Wait(), RenderStepped:Wait() or Heartbeat:Wait().

As @Moonvane said earlier, you should use a server script instead. Anti-cheat shouldn’t be controlled by a local script.

2 Likes

You’re a tough nut for creating an anti-cheat client sided. Tbh, the anti-cheat isn’t that effective as an exploiter can easily abuse the local script, as they have full control over their client. I like the way you systemized different aspects of your code, however it will only take a few seconds for an exploiter to disable your script.

3 Likes

Just so you know exploiters don’t need to disable your script or destroy it to stop it. They probably have some sort of wizardry to magically stop a script, or they can force it to error by messing with the globals etc.

Also, unless you changed the default jump power of your game, the default jump power is 50. And walk speed isn’t the only way exploiters can get speed.

Just don’t invest too much time into this client-sided anti-cheat. A small one on the client is fine, as it will help against some skids, however if your game is big enough then scripts are probably made specifically for it that account for your anti-cheat, and the client-sided one shouldn’t be the main focus. The main focus should be the server anti-cheat. Do the best you can to mitigate the damage exploiters could deal.

6 Likes

Well as I develop secured systems or anti-cheats I always use an Obsfucator and just code the script normally and when I am done obsfucate it and then just put it where I need to. I personally use Defaultio’s Obsfucator which is a great choice in my opinion. And I would sugerate to make like a all type tool preventer, like have a ignore table and just on a new child added to the player’s inventory check if the tool’s name is one from the ignored table list if it is then don’t kick them, if it isn’t kick them, here is a example to understand better.

local Players = game:GetService("Players")
local Player = Players.LocalPlayer
local IgnoreList = {
    "Sword",
}

Player:WaitForChild("BackPack").ChildAdded:Connect(function(Child)
    if Child.Name == table.find(IngoreList, Child.Name) then
       return true
      elseif Child.Name == not table.find(IngoreList, Child.Name) then
       return false
   end
end)
1 Like

There are many bad practices used in your Anti Cheat script. First off, why are you using a while loop when you can use Changed or GetPropertyChangedSignal? Both are here for a reason, using a while loop also contributes to the wastage of resources.

if script.Parent:FindFirstChild("Main") == nil

You can use an alternative:

if not script.Parent:FindFirstChild("Main")

Since that’s better and looks more clean.

I see that you use 2 scripts which is completely useless with the fact that you have already defined Character in your first script, just simply do the stuff which the second script does on the first one.

It is also worth mentioning that an experienced exploiter can just delete the local script or modify it. You are better making a server sided anti cheat.

3 Likes

This anticheat can be disabled in seconds. There are so many client anti-kick scripts that will render this whole script useless. They use the metatable of game to detect a kick, and make it hang (With wait(math.huge)) before it kicks you.

Do not invest your time in a client-sided anti-cheat, and rather make a strong server-sided one.

They can also simply change the metatable of the Humanoid.MaxHealth or Humanoid.WalkSpeed to just return 16 everytime it is indexed. For example, if I change the metatable of Humanoid walk speed to be return 16 then it doesn’t matter what speed I am at, (I can be at 1000) if you check the walk speed, it will return 16.

A server-side anticheat cannot be accessed by the client, making it a much smarter way of making an exploit. On the other hand, most things that help you find out that a client is exploiting is not replicated to the server. There are other ways though to get the client’s walk speed. There might be some false positives, but that is expected. Make sure instead of kicking them, you just teleport them back or kill them.

tl;dr: Client-sided anti-exploits are useless against an average exploiter.

1 Like

For movement hacks specifically, you can have the server check their position and store their previous position and compare the two. If the movement is deemed to be too “fast” by your script, you can make them rubberband back.

2 Likes

If you wanna make it hard to read then you can obfuscate your script using this Plugin: https://www.roblox.com/library/930021250/Obfuscate

Having it obfuscated doesn’t mean it can’t be deobfuscated but it is still an attempt.

3 Likes

Remember, obfuscation on top of a script the client has access to doesn’t secure it in the slightest.

Readability doesn’t really matter when it’s just about preventing the script from executing in the first place.

3 Likes

I’m pretty sure most script kiddies won’t figure out how to get through it.

That’s not going to help, because If someone inserts a HopperBin into there backpack it won’t reflect on the server.
@incapaz @Desired03 @SilentsReplacement @Ethanoj1 @itsokayepic

This is why you add server sided anti-noclip to prevent them from no clipping with the hopper bin. Believe me, a server-sided anti-exploit is way better than a client-sided anti-exploit.

Sure, but it’s just a matter of preventing or deferring the local script; it’s one of the first things both amateur and experienced people alike would try.

Even so, when it comes to player enjoyment, community development, and the direct loss of revenue, it makes very little sense not to implement a server-sided anti-cheat and take the proper measures to make everything secure.

In Roblox’s current state, client-sided anti-cheat should just be considered null and void; given the platform, there is no foreseeable future where this fact changes.

The problem Is it won’t reflect to the server

I don’t think you get what I am saying. You can detect with raycasts if the character is passing through parts. Yes, you cannot detect if they have a hopper bin, but that can by bypassed on the client sided anyways, so it’s safe to go with a server sided anti exploit, that the client cannot touch.

I understand now, but if Someone adds a Raycast to there Character or something else that does with RayCast?

What’s a Raycast?

A raycast is a ray that is cast between one position, and a ray direction. You can get the bool value of if it hit something, and where it hit (if it hit). Since the character position is replicated on the server-side, you can cast a raycast from their last know position to their current position direction. If the raycast hits anything other than the character, then they are no clipping through a part. As a punishment, you can just teleport them back to their last known safe position.

Here is an example:

local raycast = Ray.new(Char.HumanoidRootPart.Position, rayDirection)
local hit, pos = workspace:FindPartOnRayWithIgnoreList(raycast, {Char})
if hit then
print(tostring(pos))
end --Made myself, probably spelling errors

You would be surprised by how much protection you can get with a server-side anti-cheat.

Sorry if I did a bad way of explaining it. Here is the article if you want to read more about it. https://developer.roblox.com/en-us/articles/Raycasting
Datatype Ray: https://developer.roblox.com/en-us/api-reference/datatype/Ray

2 Likes

Hello, So, First of all. I’ll go though some basic problems. And strategies that exploiters may use to abolish this script. Then i’ll go on and talk about how you can make it better and how to start making it really hard for big hackermens to bypass it.

Bypassing Your Anti Cheat

First up, I’ve noticed when it comes to creating new things that really mess with hackers. Its wasting time, Just tinkering around with things in-studio. I have friends who created an anti decompile, Just by tinkering and using common knowledge.

So, Anyway. Firs problem. You’re not pre-defining your variables, As a hackerman you can reset things. Such as Kick, What not. creating a local at the start of the game to handle that Kick function is always handy, This means you can always check to see if the Kick function is unique from the original

local playerKick = game.Players.LocalPlayer.Kick

while true do
   if playerKick ~= game.Players.LocalPlayer.Kick then 
       while true do os.clock() end
   end
end

You can make a table, Checking alot of variables with this. Just to see if the environment has changed or is different.

Secondly, Connections. They’ll just delete it.
Any Connection you make, A hacker can just get that connection and disable it. (On a developers side, It’ll still look connected. But it’s really not going to get those connections.) People do this to avoid detections like .ChildAdded, They’ll remove connections related to it.

Thirdly, Humanoid, A humanoid can easily be spoofed by a hackerman setting a custom __namecall, Hence allowing them to zoom zoom, But allowing u to see it as fine. Any property/value in the humanoid can be edited and changed so. Watch out for that.

Fourthly, A loop to check if your file still exists. They can easily just create a new local script, Call it “Anti” and plop off. Delete your real one.

Lastly, My point is. A hacker has plenty-o-ways to bypass anything you put onto the client. And if you use the “But it’ll stop alot of hackers and that” argument. The only reason it will do that. Is because those people are going to follow the path of another one. Meaning. If that “other” one makes a bypass. Everyone will have that bypass.

Creating A Better Anti Cheat

So, Unless you’re a good developer who knows the language lua and the platform roblox quite alot. Battling with the hackers on a client will be a massive waste of time and resources. They’ll get a laugh out of it, and you’ll be beaten down for it. Personally. If I were you. I’d have it all on the server for now. Until you can create a complex system that will bash big men hackers.

For flying, You’d check the raycast from you and the floor. Most hackermans use a BodyPosition or some type of body force. So along with this raycast. Check the humanoid state. If all is equal to the character in the sky, But not falling. Kick them, Somethings off. - Make sure your raycast is fair, Remember that roblox’s hitbox will allow a player to stand 1 leg on. With like half off.

For sleep, Have a loop that checks the distance between points. For instance, If a big man hacker went 1000 studs, The distance between the old location and the new would be MAHHOOOSIVE. Which means you can obviously teleport them back. Don’t kick them straight up as it could be a bug etc. But after 3/4 exclusions. Yeah. It’s likely they’re trying to bypass. So kick.

Though! Be careful. Check if they’re in a seat. Such as in a car. Then check that car. Etc. From there you’d do the same checks. But on the car.

FE god, And that. I’m Confident the server can actually detect humanoid changes. on the sever, Check .ChildRemoved on the server.

https://gyazo.com/b1cbccbea04e05f4c2f06b2b2a83cf2a
The script JulioCoolio is inside the player, A hacker physically can’t mess with that. So we’re sorted.

For jump Power You’d check the ray cast, Old, New, Like the walkspeed.
The humanoid health doesn’t replicate to the server. A hacker exploiting that would be a waste.

And. That basically concludes my writing.

Sorry about not being so format. But hopefully you’ll understand :smiley:

2 Likes