
KeylessUniversal

--please give credits if you use in projects -> discord: cool.guy.69
local settings = {
copytoclipboard = true,
copyasscript = true,
logfireserver = true,
loginvokeserver = true,
logonclientevent = false, --half working
logonclientinvoke = true,
logindexing = true,
}
print("[signalspy] loaded")
local safetostring = function(v)
local t = typeof(v)
if t == "string" then
return '"' .. v:gsub('"', '\\"') .. '"'
elseif t == "number" or t == "boolean" or t == "nil" then
return tostring(v)
elseif t == "Instance" then
return v:GetFullName()
elseif t == "EnumItem" then
return tostring(v)
elseif t == "table" then
local parts = {}
for k, val in pairs(v) do
local kt = type(k) == "string" and '"' .. k:gsub('"', '\\"') .. '"' or tostring(k)
local vt = safetostring(val)
table.insert(parts, "[" .. kt .. "]=" .. vt)
end
return "{" .. table.concat(parts, ",") .. "}"
elseif t == "vector" then
return string.format("Vector3.new(%g, %g, %g)", v.X, v.Y, v.Z)
else
return "[" .. t .. "]"
end
end
local function makescript(remote, method, args)
local goodcurry = remote:GetFullName() .. ":" .. method
if #args == 0 then
return goodcurry .. "()"
end
local arguwu = {}
for _, v in ipairs(args) do
table.insert(arguwu, safetostring(v))
end
return goodcurry .. "(" .. table.concat(arguwu, ", ") .. ")"
end
local function tts(tbl)
local str = ""
for i, v in ipairs(tbl) do
str = str .. "arg[" .. i .. "] = " .. safetostring(v) .. "\n"
end
return str
end
local function isvalidremote(self)
return typeof(self) == "Instance" and (self:IsA("RemoteEvent") or self:IsA("RemoteFunction"))
end
local function log(where, remote, method, ...)
local args = {...}
local out = "[" .. where .. "] " .. remote:GetFullName() .. ":" .. method .. "\n" .. tts(args)
print(out)
if settings.copytoclipboard and setclipboard then setclipboard(out) end
if settings.copyasscript and setclipboard then
local script = makescript(remote, method, args)
setclipboard(script)
end
end
local namecallorg
namecallorg = hookmetamethod(game, "__namecall", newcclosure(function(self, ...)
if oth and oth.is_hook_thread and oth.is_hook_thread() then
return namecallorg(self, ...)
end
if not isvalidremote(self) then
return namecallorg(self, ...)
end
local method = getnamecallmethod()
if method == "FireServer" and settings.logfireserver then
log("client -> server", self, method, ...)
elseif method == "InvokeServer" and settings.loginvokeserver then
log("client -> server", self, method, ...)
end
return namecallorg(self, ...)
end))
local indexorg
indexorg = hookmetamethod(game, "__index", newcclosure(function(self, key)
if oth and oth.is_hook_thread and oth.is_hook_thread() then
return indexorg(self, key)
end
if not isvalidremote(self) then
return indexorg(self, key)
end
if settings.logindexing and (key == "FireServer" or key == "InvokeServer") then
print("[signalspy] accessed -> " .. self:GetFullName() .. "." .. key)
end
if key == "OnClientInvoke" and settings.logonclientinvoke and self:IsA("RemoteFunction") then
return function(...)
log("server -> client", self, "OnClientInvoke", ...)
end
end
return indexorg(self, key)
end))
if settings.logonclientevent then
for _, r in ipairs(game:GetDescendants()) do
if r:IsA("RemoteEvent") then
pcall(function()
r.OnClientEvent:Connect(function(...)
log("server -> client", r, "OnClientEvent", ...)
end)
end)
end
end
game.DescendantAdded:Connect(function(obj)
if obj:IsA("RemoteEvent") then
task.wait(0.1)
pcall(function()
obj.OnClientEvent:Connect(function(...)
log("server -> client", obj, "OnClientEvent", ...)
end)
end)
end
end)
end
--faded was here



vxsty pls no sue
ewwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww, never cook again
Ohio spy
u guys so rudeee
Anything but Sigma Spy 💔
💔
ANYTHING but sigma spy :broken_heart:
this got re-reviewed. using tostring on arguments can lead to environment escapes (and does in this case). you should also check the type of self since that also leads to an environment escape. look into oth.hook since thats a thing now. it's on the volt docs and in multiple execs and avoids many common detection vectors
@Sprocket haven't updated in a while, but will do what u told me to do thanks
@goodcurry I believe the right syntax for it would be like oth.hook(getrawmetatable(game).__namecall, function(...) do stuff end) also tables can have arbitrary keys, so doing tostring(k) leads to detections and env escapes if the game does something like this local a = setmetatable({}, {__concat = function()print("detected")end, __tostring = function() print("detected") return "meow" end}) local tab = {[a] = "hello"}