NEVER TRUST THE CLIENT: What hackers can/cant do, PT. 3

This is the third installment of the what hackers can/cant do series. The table of contents is listed below.

THE CLIENT: Why you NEVER trust the client.
THE SERVER: Always run scripts on the server.
ANTICHEAT DEVELOPMENT: Best practices

1. THE CLIENT

Hackers can do anything on the client. They can modify localscripts, delete anything in their StarterPlayer or StarterPack, and generally cause chaos on the client.

Good anticheats can detect tampering on the clientside level, but every good anticheat can be bypassed. Always check hacking websites and forums to see if your game has been bypassed.

ADDENDUM: Hackers cannot change their avatar directly, such as clothing. They can remove their hats under certain situations.

2. THE SERVER

Anything on the server, hackers cannot touch. Server scripts also cannot be read or interpreted, so your scripts are safe on the server. Hackers also cannot access ServerStorage or ServerScriptService.

3. ANTICHEAT DEVELOPMENT

Anticheats are best developed MOSTLY serverside. Any clientside anticheats can be readily bypassed quickly, unless you are a godlike scripter and manage to hide it. If you do want to create a clientside anticheat, make sure its hidden as well as possible, and always have a backup.

If you want to submit your own thread to be added here, or have more advice (idk anything about the new anticheats), then comment below! I am on 1 hour of sleep, so I likely made mistakes.

29 Likes

On another note about detecting cheating software:

Any anticheat that can detect saveinstance() or script injections is lying. There is no reliable way to detect these forms of exploits. If you can prove me wrong, please reply.

5 Likes

You can actually detect injection and execute at least on the UWP version of roblox, you can use actors to prevent any type of hooks since as of rn no executor has parallel luau support, an example of that is citadel anti cheat system which is fully or mostly client sided and works very well and It doesn’t use actors.

5 Likes

Also on the WEB version of roblox, hackers/exploiters can’t access Core Gui, or they get detected, no Exploit can access Core Gui at all, the max thread identity is 3.

4 Likes

I meant with no anticheat, they can do anything. Also, can you go into a bit more detail about your first reply? I want to integrate that into my anticheat.

4 Likes

It’s a server client model you always do verification checks and handle important values on the server side.
Although if you are interested in making production code harder to read check out this resource
This will turn your code into the smallest operations possible. and make it basically illegible!
Imagine the nightmare of reading this

function cm.InterpretMathQuestion(a)local b=nil;local c,d,e,f=nil,nil,nil,nil;local c=cm.CompleteQuery(a,AddConstruct,true,true,false)if c==nil then d=cm.CompleteQuery(a,SubtractConstruct,true,true,false)if d==nil then e=cm.CompleteQuery(a,MultiplyConstruct,true,true,false)if e==nil then f=cm.CompleteQuery(a,DivideConstruct,true,true,false)end end end;if e or c or d or f then local g={}for h,i in pairs(Operators)do table.insert(g,h)end;local function j(k,l)local m={}local n=string.find(k,tostring(l))m[1]=string.sub(k,1,n-1)m[2]=string.sub(k,n+1)return m[1],m[2]end;local function o(k)local p,q=nil,nil;local r=nil;local s,t=nil,nil;for u in string.gmatch(k,"%S+")do if tonumber(u)then if not p then p=tonumber(u)s,t=j(k,p)else if r==nil then end;q=tonumber(u)break end end end;return p,q end;local p,q=o(a)if p and q then local v=nil;if c~=nil then v=AddConstruct[1]g=AddConstruct elseif d~=nil then v=SubtractConstruct[1]g=SubtractConstruct elseif e~=nil then v=MultiplyConstruct[1]g=MultiplyConstruct elseif f~=nil then v=DivideConstruct[1]g=DivideConstruct end;if v~=nil then local w=Operators[v]v=g[cm.mathrandom(1,#g)]local x=v;local y;local z;local A=w(p,q)local B=p..x..q.."="..A;b=B end end end;return b end

Lua Minifier Online (codebeautify.org)
Make’s me queasy just looking at it! good luck rever engineering that if you do you earned it I guess.

1 Like

that… is the most horrendous beautiful thing i have ever seen

I did know about LUA minifiers, but they could just un-minify it. There are scripts online to deobfuscate those types of scripts.

3 Likes

I didn’t know about the unminify tool! This look really useful.

function cm.InterpretMathQuestion(a)
local b=
nil;

local c,d,e,f=
nil,
nil,
nil,
nil;

local c=cm.CompleteQuery(a,AddConstruct,
true,
true,
false)
if
 c==
nil 
then d=cm.CompleteQuery(a,SubtractConstruct,
true,
true,
false)
if
 d==
nil 
then e=cm.CompleteQuery(a,MultiplyConstruct,
true,
true,
false)
if
 e==
nil 
then f=cm.CompleteQuery(a,DivideConstruct,
true,
true,
false)
end 
end 
end;

if
 e 
or c 
or d 
or f 
then 
local g={
}
f
or h,i in pairs(Operat
ors)
do table.insert(g,h)
end;

local function j(k,l)
local m={
}

local n=string.find(k,tostring(l))m[1]=string.sub(k,1,n-1)m[2]=string.sub(k,n+1)
return m[1],m[2]
end;

local function o(k)
local p,q=
nil,
nil;

local r=
nil;

local s,t=
nil,
nil;
f
or u in string.gmatch(k,"%S+")
do 
if
 tonumber(u)
then 
if
 
not p 
then p=tonumber(u)s,t=j(k,p)
else
 
if
 r==
nil 
then 
end;
q=tonumber(u)
break 
end 
end 
end;

return p,q 
end;

local p,q=o(a)
if
 p and q 
then 
local v=
nil;

if
 c~=
nil 
then v=AddConstruct[1]g=AddConstruct 
else

if
 d~=
nil 
then v=SubtractConstruct[1]g=SubtractConstruct 
else

if
 e~=
nil 
then v=MultiplyConstruct[1]g=MultiplyConstruct 
else

if
 f~=
nil 
then v=DivideConstruct[1]g=DivideConstruct 
end;

if
 v~=
nil 
then 
local w=Operat
ors[v]v=g[cm.mathran
dom(1,#g)]
local x=v;

local y;

local z;

local A=w(p,q)
local B=p..x..q.."="..A;
b=B 
end 
end 
end;

return b 
end

Also if you want to use this module I wrote it’s called ChatModule and it’s a powerful library for english language search queries and LLMs

2 Likes

to be fair you have a point ;-;

1 Like

I’m just going to plug this in cause its awesome. Machine Learning Library for Training Text Based Chatbots [Open-Sourced] Update: Bag of Words Function Previous/Next Word Predictor Text Randomizer - Resources / Community Resources - Developer Forum | Roblox

But mainly for my application I would be worried about someone stealing my precious code!
Another thing is your could potentially Fire a secret array using a Remote Function

local bindableFunction = game.ReplicatedStorage.GlobalSpells.BindableFunction -- Find the same BindableFunction object in the Workspace
bindableFunction.OnInvoke = function(name) -- Define a function that runs when the BindableFunction is invoked and receives the name as a parameter
	--print("Invoked")
	return GetServertable(name) -- Get the table from the Spells module using the name

end

I use this because it reduces the number of times you call the GetChildren to build an array.

3 Likes

Guess who’s here :sunglasses:

Here to plug my thread, if anyone would like to add to it, go ahead :slight_smile:

my thread

2 Likes

Server-side script

local bindableFunction = game.ReplicatedStorage.GlobalSpells.BindableFunction -- Find the same BindableFunction object in the Workspace
bindableFunction.OnInvoke = function(name) -- Define a function that runs when the BindableFunction is invoked and receives the name as a parameter
	--print("Invoked")
	return GetServertable(name) -- Get the table from the Spells module using the name

end
	function dfg.Gettable(Key)
		--print("StableCall")	
		local result=bindableFunction:Invoke(Key)
		--print(result)
		return result -- Invoke the RemoteFunction on the server with the table as an argument and get the response
	end

So you could potentially encrypt the key with a hashing function?

function cm.hash(str)
	local h = 0
	for i = 1, #str do
		h = h + string.byte(str, i)
	end
	return h
end

Maybe make a custom seed based on the hash

function cm.CustomSeed(Seed,name)
	local seed = cm.hash(name) 
	math.randomseed(seed)
	globalrng=Random.new(math.random(1,999999))
return	globalrng
end

And use it as a internal confirmation key that is held internally and not stored as a local variable and fire it at the start of the session.

This would disable the ability for an exploiter to fire a function without the hash key.

Humanoid.WalkSpeed is equal to studs per second. So the projected movement of a humanoid can be confirmed on the server.

I copy and pasted this code from my chatmodule library It’s about 6000 lines of code. I open sourced it. It might be very educational to check out.

7 Likes

Woah woah. Is there any way you could dumb it down… like a lot? Especially the hashing function.

Once again, your work has confused, but impressed me in like 200 different ways :sweat_smile:

3 Likes

That is a good point! So you can get the Remote only once then hash the name into a undecryptable string.

5 Likes

Ha no. I have a kinda old Windows PC.

Ah a form of security, right? Is this protecting the RemoteFunction or something else?

3 Likes

Yeah I’m self taught programmer! That’s a good point you could make the name a undecryptable string!. I mean actually no… Idk… But I’m just shooting you ideas. But could store an internal variable as a password in the beginning of the session so you cannot get it again. It’s been a lot easier since ChatGPT came out sometimes you just gotta know what you are looking for. Build a library and use that library for as many things as possible.

4 Likes

Did you teach yourself all about this? You got a lot of knowledge… :astonished:

3 Likes

Well security theory is a age old topic! I’ve comtemplated a security thing but I dont have any need to develop it. I learned a lot making an AI Chatbot an Effects library, Inventories bank systems Procedural World generation i’m pretty top-tier! I use to have a famous account but it got hacked when I tried downloading filmora

4 Likes

You could become a anti-cheat developer for huge games. Do you happen to have this same level of knowledge in other programming languages perhaps?

3 Likes

I’m busy with my own project but if you are interested in seeing some of my interesting work in the form of this simple to use chatmodule library then you can check out that. I’m busy making a MMORPG that is really good and almost done. It’s built upon algorithmic systems so i can just add new stuff very easily. But I implore you to maybe check out the code because I often use it myself as a reference library for manipulation of tables Lua is a very good language based on C++ very performant.
I don’t know how familiar you are with modules but if you want to use the library it’s very powerful and interesting chatmod=require(ChaMmodule)

3 Likes