Please scroll all the way down before making a reply/criticism; I do not like ignorant people
Hey folksters. I’d like to showcase a method in detecting practically every public remotespy out there. Fundamentally, EVERY remotespy should be detected by this, as the behavior of a remotespy naturally should open the script up to this detection.
Watch this video and notice the behavior of a mimication of what a remotespy would do. See the results that occur.
What happened? Somehow the gcinfo difference in the before and after jumped dramatically from less than 10 to a little over 100. Later on, it drops down to somewhere around 30-60, but it only needs to detect you once.
This behavior can be taken advantage of by using this snippet of code:
local remote = Instance.new("RemoteEvent", game:GetService("ReplicatedStorage"))
local tbl = {}
for i = 1, 300 do tbl = {tbl} end
while task.wait(2) do
local oldGcinfo = gcinfo()
pcall(function() remote:FireServer(tbl) end) -- should error but that's not important for this case
-- checking difference of gcinfo
if gcinfo() - oldGcinfo > 2^6--[[ == 64]] then
warn("Remotespy Detected")
end
end
The best part about this detection? It will never false. Normally, the gcinfo difference always remains at, or below 10, and it only jumps up because there is a Lua argument handler present that is hijacking the FireServer and translating the args into something safe for the exploit to use.
This is the code that was used in the video, it merely serves to demonstrate the difference between a normal and remotespy-hijacked attempt to fire to the server:
-- code snippet used in the video
-- performs the original fireserver then mimics the behavior of a remotespy
local MaxLuaStackSizeReached = {}
for i = 1, 300 do -- second number could be bigger if you want to make the gcinfo difference greater
MaxLuaStackSizeReached = {MaxLuaStackSizeReached}
end
local remote = Instance.new("RemoteEvent", workspace)
local FireServer = function(...)
pcall(function(...) remote:FireServer(...) end, ...)
end
print("Running normal version")
for i = 1, 3 do
local oldGcinfo = gcinfo()
FireServer(MaxLuaStackSizeReached)
local newGcinfo = gcinfo()
print("Gcinfo difference: " .. newGcinfo - oldGcinfo)
task.wait(1)
end
-----------------------------------------------------
-- function from simplespy
-- fundamentally you cannot simply call table.clone on a table, as there could be
-- values in that table that are being weaktable checked. if you do table.clone
-- you hold a reference to those values, and that opens you up for a separate
-- detection (you could also make the table so big this function stack overflows)
local function deepclone(args: table, copies: table): table
local copy = nil
copies = copies or {}
if type(args) == 'table' then
if copies[args] then
copy = copies[args]
else
copy = {}
copies[args] = copy
for i, v in next, args do
copy[deepclone(i, copies)] = deepclone(v, copies)
end
end
--[[elseif typeof(args) == "Instance" then
copy = cloneref(args)]]
else
copy = args
end
return copy
end
local args = {};
local function BadArgHandler(arg, numTabs)
numTabs = numTabs or 0
local str = string.rep("\t", numTabs).."{\n"
for i, v in pairs(arg) do
str = str .. BadArgHandler(v, numTabs + 1) .. ",\n"
end
str ..= string.rep("\t", numTabs).."}"
return str;
end
task.spawn(function()
-- example of remotespy cache for arguments
repeat task.wait(1) until args;
task.wait(5)
for i, arg in pairs(args) do
print(BadArgHandler(arg))
end
end)
local old = FireServer -- example deter
FireServer = function(...)
table.insert(args, deepclone(...)) -- clone used because a script could hold a reference to the table being fired
print(...)
return old(...)
end
-----------------------------------------------------
task.wait(2)
print("Running deterred version")
for i = 1, 3 do
local oldGcinfo = gcinfo()
FireServer(MaxLuaStackSizeReached)
local newGcinfo = gcinfo()
print("Gcinfo difference: " .. newGcinfo - oldGcinfo)
task.wait(1)
end
Enjoy. The client is a great defense tool and to say it should be thrown away and discarded in favor of the server would not be something I suggest you do.