Insights on exploit prevention

Ah, it was a misunderstanding then on my party. I thought in your example the client was defining the cost for the point upgrade which made me reply.

2 Likes

I suggest that instead of scripts getting deleted, have anti cheat local scripts hidden like you know you could use remote functions to run codes inside of the local script and like to get the serverinvoke through the ServerScriptService, my idea may seem lame, but I think this should clean the path.

And btw, doesn’t people who dont have access in replying and only view. Can’t they also seem to know our plans? Im a bit frightened.

And btw, doesn’t people who dont have access in replying and only view. Can’t they also seem to know our plans?

Yep, and that’s why any kind of client-sided exploit detection is pointless in the long run. Focus on server-sided exploit detection and protect your remotes with sanity checks. This is not security through obscurity unlike the client-sided exploit prevention.

1 Like

You can’t really hide any code running on the client from exploiters

I don’t know what you mean. You cannot use loadstring on the client, and if you mean using a lua vm like rerubi or adonis loadstring, then it’s even worse because the exploiter could intercept the source and edit it as they wish (i.e. set to empty string)

It’s not like exploiters sit here 24/7 and check new replies to all exploiting-related threads lol. In fact, most of the time when they want to exploit a game, they start without any knowledge of what checks it has, whether they are clientsided or not, how the game system works, etc. and yet they still end up figuring something out so yea.

1 Like

Look, I have one anticheat on my client and its mainly to dissuade script kiddies.

The first step to making an effective anti exploit is to accept that your main goal is to remove script kiddies, big bois are taken down temporarily and likely wont be there unless your game is insanely popular.

Here’s what I do for my local anti exploit, the most I do is make sure the humanoid is not in an invalid state, then make sure no stats are wack. Maybe an anti fly, but that’s getting fancy and useless.

After that, I use a remote function that returns a simple value to the server that relays the local anti is alive. If it doesnt relay the value the player is kicked. On the server the remote function is pcalled and applied a wait of 12 seconds (9 seconds is how long the roblox client had to reply before the server determines it got disconnected, and the extra 3 seconds are there for safe measure).

Yes it’s most likely useless for big bois, but this should get rid of some smarter script kiddies.

Yes it’s a waste of time for some people, but I just wanted to be thorough as well as I usually have time to kill.

No this is not the main focus for my anti system, this always comes last before anything.

I can probably make it more thorough by having a very important local script check for its existence and do some sanity checks there, but that’s for when I have more time to kill, and it’s not very important.

You can skip the local anti, it’s not gonna be effective past script kiddies.

As for server side, of course the saying goes “server sanity checks” so do those.

This should ALWAYS be your first priority when making an anti cheat. You can probably skip local anti cheats all together.

For detecting false positives, a strike system is fairly effective, of course this can also be bypassed by only doing an exploit once in a while, but at that point its useless. Make sure to degen the strikes, and it should work “well”

After that you do you.

1 Like

This is exactly what I try to explain to people whenever they say “client-sided anti exploit is useless, you shouldn’t be doing it”.

Your anti exploit system seems good. The fact that you account for infinite yield in a client invoke and stuff.

I have made a client-sided anti exploit myself aswell. It’s more of a hobby/PoC thing since I don’t have an actual game I could use it for, but here’s how it works if you’re curious:

wall of text
  1. The entire script is wrapped in two anti-decompile methods
  2. It’s a ModuleScript which destroys itself after running, and has an infinite loop at the end. If the loop gets aborted, the localscript that required the module will notice it and take action
  3. It doesn’t use remotes to send to the server, unless all other methods fail
  4. It also has a ping check with remotefunctions + return check (do something with the argument passed by the server, check if it’s correct)
  5. Common anti-exploits detections, such as game[{}] in xpcall, and some less known ones
  6. Trap variables (__tostring, String too long error)
  7. Verifying constants (strings) with ("").char in a loop
  8. Memory checks in a loop:
    • Checking if tostring(func) == cachedTostringFunc
    • Checking if the bytes of the above match cached bytes in a table
    • Checking the return of some functions
    • Checking their env
    • Checking if they are lua closures
    • Calling them as metamethods to detect any yielding (attempt to yield accross metamethod/C-call boundary)
  9. Miscellaneous checks related to DataModel’s metamethods, Instance.new("RemoteFunction").InvokeServer(workspace, workspace) and whatnot
  10. Comparing error messages of various stuffs
  11. Checking if connections were disconnected
3 Likes

I’ve never heard of that, could you explain to me how those work. It could help OP as well if he decides to do some light local anti exploits

These are particularly weird and I’ve never understood them, do you perhaps use hopperbin? I’ve seen that instance used around, but I never really understood its purpose.

Anti decompile/anti unluac are methods which cause the unluac.jar to get confused and spit out malformed code or crash.
For example the first method that I know let’s you hide a function completly from its output. It’s also the most commonly known method.
The second one causes it to output while true do while true do while true do endlessly until it runs out of memory/bounds.

Idk what you mean. I meant memory checks as in checking if any of my functions have been hooked (replaced) by the exploiter.

1 Like

It’s relatively simple for an exploiter with a script executor to obtain any scripts, or locations of items, that are able to be found on the client. The simplest way would be to load a pre-made explorer script and then, using that, do a search for scripts (if possible, I don’t know how well explorer scripts work, I’m not exploiter, I just know they’re a thing since I’ve used one before on my own game when I was starting out), select and copy the script you want and then paste the script into studio. Then its just two clicks and you can see how that script works. Having separate scripts on the client, one for functionality and one for exploit-checking isn’t a good idea, in my opinion - if you have the exploit checking script integrated within the functionality script, it’ll cause players to be discouraged in relation to deleting the script, as by deleting it, they’re technically deleting the object that they wanted to access in the first place.

Also why you make all your main checks server-side and NEVER take checks from the client - if you must take client checks, make sure to communicate these checks to the server and double check it there as well.

1 Like

Yes… that’s basically what I said…

That’s uhh, not how it works. Exploiters need to decompile the script first, that is grabbing the bytecode and running it through unluac.jar to turn it back into lua code. They can’t copy/paste it to studio without setting clipboard’s metadata (or whatever studio uses) to the xml data of the script instance.

Well, it’s not like they can in fact “delete” a script in the first place. Once a script is running, there isn’t really a way to stop it. You can at most set its Disabled to true, disconnect its event connections, and erase its variables, to “emulate” it being deleted.
But you can do that to a certain part of a script aswell. That’s why it doesn’t really matter if the anti exploit is inside the main script or not, because exploiters almost never disable any scripts when exploiting a game anyways.

1 Like

That is how it’s work, I’ve tested a few of these scripts in the past in order to find out ways to counter-act them, as well as see if my current scripts do so, you can legitimately copy and paste the scripts in, you can also delete them using the explorer script, whether that stops the script or not depends on the content of the script and properties.

For clarification, when I say explorer script, I mean a script that replicates the abilities of the actual studio explorer as well as more features through the usage of buttons rather than keys, such as delete, copy, paste, etc, it also comes with a property script, if I remember correctly.

The script’s thread will get stopped, but the functions it created will still exist, including the anonymous ones used when connecting to events. That’s why i.e. RenderStepped:Connect(function() end) will continue to run.

Actually I can’t remember if roblox made all events pause when you disable a script, will have to check it later.

Again, Dex explorer CANNOT copy/paste instances to studio. Its copy feature uses a fake clipboard - a variable!!
It’s open source so you can check that yourself if you want

1 Like

Well it worked for me in the past, perhaps I’m just explaining it incorrectly? It was 2-3+ years ago, Roblox may have changed it since then, or I’m misunderstanding how it works.

You’re misunderstanding how it works. Dex is a completely Lua-implemented emulation of the Studio window at run time, which means it’s bound by what can be accomplished within the game environment at the highest context level.

There’s a reason why even if Dex can see most of your game, it can still never access server-sided objects like a standard exploit. There’s also a reason why it doesn’t work as perfectly as you expect, though it comes close in some regards.

Yes, I know that I’m misunderstanding it.

Which leads me to question how I successfully did this in the past? Maybe I just duplicated the script into the explorer rather than studio itself (gameExplorer#1-gameExplorer#1 rather than gameExplorer#1-studioExplorer#1)

Here’s an idea:

  • Make the anticheat script not visible to them.

I’m not quite sure what you’re saying anymore or how it’s relevant to the discussion. What exactly are you talking about?

Script-duplication from game client to studio in order to view the code from within said script, normally a LocalScript, but possibly others depending on the owner’s placement.

Either way, I’ve complete and utterly, to put it bluntly, screwed myself over somewhere down this conversation, so please ignore some of the things I’ve said.

EDIT: I’m aware you guys are saying its impossible. So no need to keep saying that over and over again. :slightly_smiling_face:

Doesn’t work. Client can see any instances replicated to them, even in nil. Hiding it’s visibility just complicates your hierarchy unnecessarily. Embedding your code into core game logic, on the other hand, is considered hiding it’s visibility but that would just make your own codebase messy.

Better suggestion: stop trying to focus on client-side anti-exploit until you’re certain that your server is secure.

No, that’s not possible and it never has been. I don’t know what kind of whack information you’re working off of but the client cannot interact with Studio. Period.

If you’re aware that people are saying this, maybe you should listen rather than try to repeat the point that you were somehow able to accomplish something that has never been possible.