alek_

Custom Remote Spy

Jul 7th, 2020
403
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 7.26 KB | None | 0 0
  1. -- Put this in your auto execute folder
  2.  
  3. _G.scanRemotes = true
  4.  
  5. _G.ignoreNames = {
  6.     Event = true;
  7.     MessagesChanged = true;
  8. }
  9.  
  10. setreadonly(getrawmetatable(game), false)
  11. local pseudoEnv = {}
  12. local gameMeta = getrawmetatable(game)
  13.  
  14. local tabChar = "      "
  15.  
  16. local function getSmaller(a, b, notLast)
  17.     local aByte = a:byte() or -1
  18.     local bByte = b:byte() or -1
  19.     if aByte == bByte then
  20.         if notLast and #a == 1 and #b == 1 then
  21.             return -1
  22.         elseif #b == 1 then
  23.             return false
  24.         elseif #a == 1 then
  25.             return true
  26.         else
  27.             return getSmaller(a:sub(2), b:sub(2), notLast)
  28.         end
  29.     else
  30.         return aByte < bByte
  31.     end
  32. end
  33.  
  34. local function parseData(obj, numTabs, isKey, overflow, noTables, forceDict)
  35.     local objType = typeof(obj)
  36.     local objStr = tostring(obj)
  37.     if objType == "table" then
  38.         if noTables then
  39.             return objStr
  40.         end
  41.         local isCyclic = overflow[obj]
  42.         overflow[obj] = true
  43.         local out = {}
  44.         local nextIndex = 1
  45.         local isDict = false
  46.         local hasTables = false
  47.         local data = {}
  48.  
  49.         for key, val in next, obj do
  50.             if not hasTables and typeof(val) == "table" then
  51.                 hasTables = true
  52.             end
  53.  
  54.             if not isDict and key ~= nextIndex then
  55.                 isDict = true
  56.             else
  57.                 nextIndex = nextIndex + 1
  58.             end
  59.  
  60.             data[#data+1] = {key, val}
  61.         end
  62.  
  63.         if isDict or hasTables or forceDict then
  64.             out[#out+1] = (isCyclic and "Cyclic " or "") .. "{"
  65.             table.sort(data, function(a, b)
  66.                 local aType = typeof(a[2])
  67.                 local bType = typeof(b[2])
  68.                 if bType == "string" and aType ~= "string" then
  69.                     return false
  70.                 end
  71.                 local res = getSmaller(aType, bType, true)
  72.                 if res == -1 then
  73.                     return getSmaller(tostring(a[1]), tostring(b[1]))
  74.                 else
  75.                     return res
  76.                 end
  77.             end)
  78.             for i = 1, #data do
  79.                 local arr = data[i]
  80.                 local nowKey = arr[1]
  81.                 local nowVal = arr[2]
  82.                 local parseKey = parseData(nowKey, numTabs+1, true, overflow, isCyclic)
  83.                 local parseVal = parseData(nowVal, numTabs+1, false, overflow, isCyclic)
  84.                 if isDict then
  85.                     local nowValType = typeof(nowVal)
  86.                     local preStr = ""
  87.                     local postStr = ""
  88.                     if i > 1 and (nowValType == "table" or typeof(data[i-1][2]) ~= nowValType) then
  89.                         preStr = "\n"
  90.                     end
  91.                     if i < #data and nowValType == "table" and typeof(data[i+1][2]) ~= "table" and typeof(data[i+1][2]) == nowValType then
  92.                         postStr = "\n"
  93.                     end
  94.                     out[#out+1] = preStr .. string.rep(tabChar, numTabs+1) .. parseKey .. " = " .. parseVal .. ";" .. postStr
  95.                 else
  96.                     out[#out+1] = string.rep(tabChar, numTabs+1) .. parseVal .. ";"
  97.                 end
  98.             end
  99.             out[#out+1] = string.rep(tabChar, numTabs) .. "}"
  100.         else
  101.             local data2 = {}
  102.             for i = 1, #data do
  103.                 local arr = data[i]
  104.                 local nowVal = arr[2]
  105.                 local parseVal = parseData(nowVal, 0, false, overflow, isCyclic)
  106.                 data2[#data2+1] = parseVal
  107.             end
  108.             out[#out+1] = "{" .. table.concat(data2, ", ") .. "}"
  109.         end
  110.  
  111.         return table.concat(out, "\n")
  112.     else
  113.         local returnVal = nil
  114.         if (objType == "string" or objType == "Content") and (not isKey or tonumber(obj:sub(1, 1))) then
  115.             local retVal = '"' .. objStr .. '"'
  116.             if isKey then
  117.                 retVal = "[" .. retVal .. "]"
  118.             end
  119.             returnVal = retVal
  120.         elseif objType == "EnumItem" then
  121.             returnVal = "Enum." .. tostring(obj.EnumType) .. "." .. obj.Name
  122.         elseif objType == "Enum" then
  123.             returnVal = "Enum." .. objStr
  124.         elseif objType == "Instance" then
  125.             returnVal = obj.Parent and obj:GetFullName() or obj.ClassName
  126.         elseif objType == "CFrame" then
  127.             returnVal = "CFrame.new(" .. objStr .. ")"
  128.         elseif objType == "Vector3" then
  129.             returnVal = "Vector3.new(" .. objStr .. ")"
  130.         elseif objType == "Vector2" then
  131.             returnVal = "Vector2.new(" .. objStr .. ")"
  132.         elseif objType == "UDim2" then
  133.             returnVal = "UDim2.new(" .. objStr:gsub("[{}]", "") .. ")"
  134.         elseif objType == "BrickColor" then
  135.             returnVal = "BrickColor.new(\"" .. objStr .. "\")"
  136.         elseif objType == "Color3" then
  137.             returnVal = "Color3.new(" .. objStr .. ")"
  138.         elseif objType == "NumberRange" then
  139.             returnVal = "NumberRange.new(" .. objStr:gsub("^%s*(.-)%s*$", "%1"):gsub(" ", ", ") .. ")"
  140.         elseif objType == "PhysicalProperties" then
  141.             returnVal = "PhysicalProperties.new(" .. objStr .. ")"
  142.         else
  143.             returnVal = objStr
  144.         end
  145.         return returnVal
  146.     end
  147. end
  148.  
  149. function tableToString(t)
  150.     return parseData(t, 0, false, {}, nil, false)
  151. end
  152.  
  153. local detectClasses = {
  154.     BindableEvent = true;
  155.     BindableFunction = true;
  156.     RemoteEvent = true;
  157.     RemoteFunction = true;
  158. }
  159.  
  160. local classMethods = {
  161.     BindableEvent = "Fire";
  162.     BindableFunction = "Invoke";
  163.     RemoteEvent = "FireServer";
  164.     RemoteFunction = "InvokeServer";
  165. }
  166.  
  167. local realMethods = {}
  168.  
  169. for name, enabled in next, detectClasses do
  170.     if enabled then
  171.         realMethods[classMethods[name]] = Instance.new(name)[classMethods[name]]
  172.     end
  173. end
  174.  
  175. for key, value in next, gameMeta do pseudoEnv[key] = value end
  176.  
  177. local incId = 0
  178.  
  179. local function getValues(self, key, ...)
  180.     return {realMethods[key](self, ...)}
  181. end
  182.  
  183. gameMeta.__index, gameMeta.__namecall = function(self, key)
  184.     if not realMethods[key] or _G.ignoreNames[self.Name] or not _G.scanRemotes then return pseudoEnv.__index(self, key) end
  185.     return function(_, ...)
  186.         incId = incId + 1
  187.         local nowId = incId
  188.         local strId = "[RemoteSpy_" .. nowId .. "]"
  189.  
  190.         local allPassed = {...}
  191.         local returnValues = {}
  192.  
  193.         local ok, data = pcall(getValues, self, key, ...)
  194.  
  195.         if ok then
  196.             returnValues = data
  197.             print("\n" .. strId .. " ClassName: " .. self.ClassName .. " | Path: " .. self:GetFullName() .. " | Method: " .. key .. "\n" .. strId .. " Packed Arguments: " .. tableToString(allPassed) .. "\n" .. strId .. " Packed Returned: " .. tableToString(returnValues) .. "\n")
  198.         else
  199.             print("\n" .. strId .. " ClassName: " .. self.ClassName .. " | Path: " .. self:GetFullName() .. " | Method: " .. key .. "\n" .. strId .. " Packed Arguments: " .. tableToString(allPassed) .. "\n" .. strId .. " Packed Returned: [ERROR] " .. data .. "\n")
  200.         end
  201.  
  202.         return unpack(returnValues)
  203.     end
  204. end
  205.  
  206. print("Loaded Remote Spy")
  207. print("")
  208. print("Remote Spy by isaraw8912, Ubicast")
Add Comment
Please, Sign In to add comment