SaveInstance Injection Detection (Exploit Detection)

Hi, I’m reposting the SaveInstance detection method I posted a couple months ago (as per request by a lot of people). Reason why I deleted the old one was because the code was pretty “poor” and at the time I didn’t want to risk it being patched by UniversalSynSaveInstance Dev’s.

The way this works:

UniversalSynSaveInstance (SaveInstance) utilises UGCValidationService for it’s HiddenProperty feature, however UGCValidationService isn’t actually apart of the game’s DataModel until explicitly referenced (you can’t use the Weak Metatable method because they use cloneref on every service), so this creates an easy detection. There is no actual use for UGCValidationService for game developers, which means it shouldn’t ever be used in your game in the first place.

There are multiple ways to detect if UGCValidationService is being used, including:

game.DescendantAdded
game.ChildAdded
game:FindService()

The best method of detection to use is game:FindService, due to multiple factors, one being because if a user executes SaveInstance (autoexecutes) before the scripts code runs then it won’t be able to detect SaveInstance using the methods game.DescendantAdded and game.ChildAdded, whereas if you loop the FindService method, it will continuously scan the game for UGCValidationService every set seconds.

local GuiService = game:GetService("GuiService")

task.spawn(function()
	while true do
		if game:FindService("UGCValidationService") then
			for i = 1, 1e5 do
				local Lol = Instance.new("HumanoidDescription")
				Lol.FaceAccessory = "0"

				GuiService.CloseInspectMenu(GuiService)
				GuiService.InspectPlayerFromHumanoidDescription(GuiService, Lol, string.rep(utf8.char(8203), 1e5) .. "")
				-- The code above crashes the client
			end
		end
		task.wait(1.5)
	end
end)

The reason why we crash the client instead of only kicking them is because even once the client (player) is kicked, they still have access to the game’s memory, as they are still being fed the game’s network data, which allows them to still save the game. Whereas if we crash them this will completely prevent them from being able to save the game (for obvious reasons).

The crash I put in the code above works by creating a massive Unicode string and repeatedly feeds it to a rendering-related function/API which essentially “chokes” on long strings. It does this over 100,000 times (1e5 is just an exponential form of 100k) to ensure a massive bulk of these strings get sent, which leads to a huge RAM spike causing the player’s client to crash.

Note that this crash is susceptible to being hooked (bypassed), especially because of the fact it’s now free released and not obfuscated. So I’d definitely suggest making a new crash for it, if you know how to ofc (probably not needed tho, and do not use while true do end).

UniversalSynSaveInstance Dev’s are still yet to make a patch for this detection method (honestly they probably never will for various reasons lol), and the only way they can patch it without removing this feature is easily detectable. Removing this feature could also cause certain issues with SaveInstance.

To those that will comment “the client isnt secure this can be bypassed! blablabla”:
This code/detection is ofc susceptible to being bypassed as is anything on the client (same with the server if given the correct vulnerabilities via the likes of backdoors), that being said this should obviously be secured to prevent any bypasses and any other tampering (of which I’m not going to do for you, that’s something you’ll have to do)

Place this code in a LocalScript, in ReplicatedFirst. If you have any other questions feel free to let me know.

This post is dedicated to those that for years have said SaveInstance is “undetectable”, nothing is undetectable in terms of security, just as nothing is ever completely invulnerable (Anti-Cheats).

42 Likes

This crashes the client even if you aren’t even doing anything because game:FindService("UGCValidationService") will always return True

Only in Studio, not in game. Either disable the script in Studio or add a check to see if you’re playing in Studio and exit out of the script:

if game:GetService("RunService"):IsStudio() then return end

However this can be hooked, so you’d need to add extra checks for that.

10 Likes

Thanks for posting this useful information, my game were targetted a lot by exploiters, requesting other exploiters who had access to service to saveinstance the game, now i can continue working on my game with peace of mind :sweat_smile:

7 Likes

When are you ever going to learn that publicly posting these detections is exactly how you get them patched in a few days regardless of how special you craft it?
What do you even get out of doing this? Are little hearts next to your post really that worth it?

3 Likes

Please read the post completely before commenting next time. UniversalSynSaveInstance developers have known of this detection ever since I had first released it and are yet to make an attempt to try and patch it.

6 Likes
local GuiService = game:GetService("GuiService")
local RunService = game:GetService("RunService")

RunService.PreRender:Connect(function()
	if game:FindService("UGCValidationService") then
		while true do
			local HumanoidDescription = Instance.new("HumanoidDescription")
			HumanoidDescription.FaceAccessory = "0"

			GuiService:CloseInspectMenu()
			GuiService:InspectPlayerFromHumanoidDescription(HumanoidDescription, utf8.char(8203):rep(100000))
		end
	end
end)

Bro wrong message again but I was trying to make your code better

There is absolutely no need to use RunService.PreRender for this

3 Likes
local GuiService = game:GetService("GuiService")

task.spawn(function()
	while task.wait(1) do
		if game:FindService("UGCValidationService") then
			while true do
				local HumanoidDescription = Instance.new("HumanoidDescription")
				HumanoidDescription.FaceAccessory = "0"

				GuiService:CloseInspectMenu()
				GuiService:InspectPlayerFromHumanoidDescription(HumanoidDescription, utf8.char(8203):rep(100000))
			end
		end
	end
end)

I highly suggest that before commenting, you do some research, especially when you’re clearly absolutely clueless on the topic. Literally every executor’s built-in saveinstance() function sends a HTTP fetch request to UniversalSynSaveInstance’s github repository. As far as I know, I don’t think any current executor has a custom SaveInstance; they all use UniversalSynSaveInstance.

3 Likes

Go test them yourself, or simply ask the executor’s developers, it’s pretty common sense!

2 Likes

I can just tell you’re a daily devforum user, actual insanity. That code is definitely not unreadable. All you changed was it from using task.spawn(function() to RunService.PreRender, and changed the for loop to a while loop :thinking:

2 Likes

And instead of using a for loop that specifically stops at “1e5” iterations I used a while loop and instead of doing string.rep… you can just do :rep?

GuiService.CloseInspectMenu(GuiService)

Okay this is funny though

Notice how I sent another reply following your conditions

100,000 iterations is more than enough to crash the client. You can do either a while loop or for loop for this crash, it doesn’t matter. :scream:

3 Likes

You’re constantly proving to me that you never read this post, at the bottom I quite literally state this detection is susceptible to being bypassed as I have provided no anti-tamper logic.

Whilst what you said is true, it is as simple as making a namecall hook to bypass this detection, namecall hooks are easily detectable and have been for years, even more so now because no current executor has good hooks lol

5 Likes

My nationality is completely irrelevant to this topic, and considering Brits on average have a higher IQ than both Americans and Canadians, you should probably withdraw your statement. Plus considering the fact you’ve gone and researched a word I’ve said shows that you probably haven’t seen grass in weeks

2 Likes

Don’t assume. This is out there, and summer time nears. We all know 90% of exploiters are simple schoolchildren whose time is normally occupied by it. They’ll have all the time in the world now to stay up late and patch this out. Most likely the reason they aren’t caring about this is because most games that exploiters utilize this in don’t have this detection, and now that you’re trying to get this up and public again, they WILL use the detection and be protected, but that just gives them more of a reason to try and patch it out.

UGCValidationService only shows up three times here, and used in a ‘fallback’. In addition to being an open source project, any punk can make a pull request FOR the developers to deprecate the use of this service entirely in response to this devforum post.

2 Likes

Which will take quite some time to do, as I’ve stated before. Didn’t realise we’re not allowed to publicly release detections anymore :rofl:

2 Likes

which will take some time to do

Don’t expect things like these to last very long when you don’t gatekeep it from the masses.
You reap what you sow, mister

for i = 1, 1e5 do.
2 Likes