Looking for a deep dive into exploit creation, and therefore prevention

I mean even if you can counter it, it will still somewhat work especially with skids

Eh, if you’re trying to counter exploiting effectively, then this won’t work for very long.
Some experienced exploiters may include an automatic bypass for your fake remote event, and skids may take those scripts made by those exploiters and use them without even noticing those fake events.

And let’s be honest, skids would generally have no idea if that remote event would’ve existed since if they can effectively search for events and instances, they’re kinda out of being a skid.

2 Likes

True true, but do you have any other tips

@diordy I see you liking theses posts lol, gl learning with me as well

1 Like

The same ol’ saying: Don’t trust the client.
Now I’m not gonna go all out to say that you should never make a client-sided anti-cheat, but make sure to focus on server-side first.

Build a strong, server-sided anti-cheat that will prevent actions such as walkspeed, jumpheight, and gravity modifications by implementing checks to make sure the character always acts how it’s supposed to without needing a client-sided anti-cheat.

Now, here’s the thing, if you want to, you can leave it here since server-sided anti-cheats are secure and safe. They don’t generally need patching as if Roblox doesn’t change anything, you’ll be good.

But if you still want to develop client-sided anti-cheats, then you can go on and do it. But as I said, as long as you have a server-sided anti-cheat to back it up.

We generally say: “Do not trust the Client.” because it’s true. You cannot trust the client no matter which type of detection you add to it. Let me explain by talking about the methods first.

There are some popular methods such as Handshake, which is a local script on the client handling the anti-cheat while constantly sending signals to the server that it’s doing its job. Making sure that the exploiter cannot delete the script or else the signal will stop being sent and the server will kick the player because of that.

Other methods such as hiding the environment, hides the script from DEX and getnilinstances() method. Pretty neat right? There are many ways you can try to prevent exploiters from modifying your scripts. So it might generally look like a good idea to use these methods. And to be honest? They actually work sometimes.

But this doesn’t mean they’re 100% effective and something you should put your trust upon.

The client has access to everything. With an executor/exploit, you have control over everything. The environment, the globals, the functions, events, and practically everything the engine has to offer. You can modify it. Developers are limited to heavily sandboxed methods while exploiters are free. They aren’t limited to global methods to do things. They have access to even the C++ side of the engine which no developer has access to.

The developer might try to use the getfenv() method, but oopsies, the executor developer changed that global method to return nil or something else instead. What are you going to do then? The handshake method? Another oopsies, they have access to the bytecode, even if you try to encrypt it it’s a matter of time before the exploiters find a way to bypass it altogether.

This is why we say “Don’t trust the Client.”
Because it’s their territory, they can change anything. Even the Roblox engineers accept this fact while some people out there refuse to accept this only to get their games swarmed by exploiters who have figured out how to bypass their fancy “C stack overflow” method.

As I said, I’m not saying you should completely avoid client-sided anti-cheats, they can be effective if used well with a good server-sided one. But be careful.

1 Like

Here’s this post I made that a bunch of awesome people contributed to. It’s got a bunch of amazing content:

1 Like

how would you use this, and getfenv()

Thank you so much, I will look into this

1 Like

getnilinstances() is a function used by exploiters. It basically gets a list of everything that is well, set to nil

And getfenv() gets the current function’s environment “env” which is basically all the global variables in a script including game, workspace, and every global variable you set (i.e. myVar = 1). However keep in mind that you can also use it to get the global variables of functions too

1 Like

so using getfenv will look for global variables, and how should I use that to help?

@TheRealANDRO mentioned that exploiters can set the values to nil therefore making them undetectable to us, the developers. And if there is a way, I’m unaware of it.

The client is outta your control basically like he mentioned

2 Likes

so the best way, is to set the global varibles that are unrecognized to nil? to hopefully break some parts

Wait no no no I was just saying that the exploiters can do that to hide their tracks.

1 Like

Here’s a good post

1 Like

ohhh, make sense. But what are ways that will help me detect an exploiter, like for example checking if the memory is high (I don’t rely on it much I only do a kick for it considering that it could just be someones device)

Well yes that could indicate that the player is actually exploiting but you will get a lot of false positives from non explorers due to their device

nvm

1 Like

Do you have any other ways to indicate someone is exploiting, like I mentioned I want to mainly go into the more advanced ways, I mean understanding how exploits work is a good thing I also want to know

Uhh well you could try checking a player’s speed to see if the distance they traveled is sane for their speed unless you have some sorta mechanic that boosts the player.

You basically use this formula: speed = distance/time.

How would you use this? You basically check every interval (for example 5 seconds) and save their position in a table or something (ON THE SERVER). Then if there is a value before it in the table, then you use the formula and determine if the speed is similar or the same as their speed.

local t = {
-- add players to this table when they join
}

coroutine.wrap(function()
task.wait(5)
table.insert(t[Player.Name], Character.HumanoidRootPart.Position)

if #t[Player.Name] > 1 then
     -- do math which I’ll add soon
     -- nvm cuz OP doesn’t want it
end

end)()
1 Like

I forgot to say thank you, so sorry

1 Like

Could you provide an example of what you’re looking for?

1 Like