GustasRBLX

remote spy

Aug 7th, 2019
63
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.24 KB | None | 0 0
  1. -- Originally written by Autumn
  2. -- Amended by asd & 3dsboy08
  3.  
  4. -- There's no reason to support Protosmasher, as it doesn't support newcclosure()
  5.  
  6. local enabled = {
  7. -- Set any of these objects to false to stop logging them
  8. BindableEvent = false,
  9. BindableFunction = false,
  10. RemoteEvent = true,
  11. RemoteFunction = true
  12. }
  13.  
  14. local ignore = {
  15. CharacterSoundEvent = true
  16. --[[ -- I'd personally recommend keeping this commented out, as game scripts can name their remotes these
  17. GetSetting = true,
  18. GetSelection = true,
  19. SelectionChanged = true,
  20. GetAwaiting = true
  21. --]]
  22. }
  23.  
  24. local metatable = assert(getrawmetatable, "needs access to function 'getrawmetatable'")(game)
  25. if setreadonly then
  26. setreadonly(metatable, false)
  27. end
  28.  
  29. local function CountTable(t)
  30. local count, key = 0
  31. repeat
  32. key = next(t, key)
  33. if key ~= nil then
  34. count = count + 1
  35. end
  36. until key == nil
  37. return count
  38. end
  39.  
  40. local PrintTable
  41. local function ParseObject(object, spacing, scope, checkedTables)
  42. local objectType = type(object)
  43. if objectType == "string" then
  44. return spacing .. string.format("%q", object)
  45. elseif objectType == "nil" then
  46. return spacing .. "nil"
  47. elseif objectType == "table" then
  48. if checkedTables[object] then
  49. return spacing .. tostring(object) .. " [recursive table]"
  50. else
  51. checkedTables[object] = true
  52. return spacing .. PrintTable(object, scope + 1, checkedTables)
  53. end
  54. elseif objectType == "userdata" then
  55. if typeof(object) == "userdata" then
  56. return spacing .. "userdata"
  57. else
  58. return spacing .. tostring(object)
  59. end
  60. else -- userdata, function, boolean, thread, number
  61. return spacing .. tostring(object)
  62. end
  63. end
  64. function PrintTable(t, scope, checkedTables)
  65. local mt = getrawmetatable(t)
  66. local backup = {}
  67. if mt and mt ~= t then
  68. for i, v in pairs(mt) do
  69. rawset(backup, i, v)
  70. rawset(mt, i, nil)
  71. end
  72. end
  73.  
  74. checkedTables = checkedTables or {}
  75. scope = scope or 1
  76. local result = (checkedTables and "{" or "") .. "\n"
  77. local spacing = string.rep("\t", scope)
  78. local function parse(index, value)
  79. result = result .. ParseObject(index, spacing, scope, checkedTables) .. " : " .. ParseObject(value, "", scope, checkedTables) .. "\n"
  80. end
  81. if CountTable(t) ~= #t then
  82. table.foreach(t, parse) -- I'm very aware this is a deprecated function
  83. else
  84. for index = 1, select("#", unpack(t)) do
  85. parse(index, t[index])
  86. end
  87. end
  88.  
  89. if mt and mt ~= t then
  90. for i, v in pairs(mt) do
  91. rawset(mt, rawget(backup, i), v)
  92. end
  93. end
  94.  
  95. return result .. string.sub(spacing, 1, #spacing - 1) .. (checkedTables and "}" or "")
  96. end
  97.  
  98. local methods = {
  99. BindableEvent = "Fire",
  100. BindableFunction = "Invoke",
  101. RemoteEvent = "FireServer",
  102. RemoteFunction = "InvokeServer"
  103. }
  104.  
  105. local __namecall = __namecall or metatable.__namecall
  106. local __index = __index or metatable.__index
  107. if getgenv then
  108. if removeSpy then
  109. removeSpy()
  110. end
  111. getgenv().__namecall = __namecall
  112. getgenv().__index = __index
  113. getgenv().removeSpy = function()
  114. getgenv().removeSpy = nil
  115. metatable.__namecall = __namecall
  116. metatable.__index = __index
  117. end
  118. end
  119.  
  120. local function RemoteCallback(self, ...)
  121. if typeof(self) ~= "Instance" then
  122. return error(select(2, pcall(__index, self))) -- magic
  123. end
  124. local arguments = {...}
  125. local result = {}
  126. local callerScript = rawget(getfenv(0), "script")
  127. callerScript = typeof(callerScript) == "Instance" and callerScript or nil
  128. print(string.format(
  129. "%s called!\nFrom Script: %s\nPath: %s\nArguments: %s\nReturn: %s",
  130. self.ClassName,
  131. tostring(not callerScript and "Not Found" or callerScript:GetFullName()),
  132. (not self.Parent and "[NIL]: " or "") .. self:GetFullName(),
  133. CountTable(arguments) == 0 and "None!" or PrintTable(arguments),
  134. CountTable(result) == 0 and "None!" or PrintTable(result)
  135. ))
  136. return unpack({methods[self.ClassName](self, ...)})
  137. end
  138. RemoteCallback = newcclosure(RemoteCallback)
  139.  
  140. methods.BindableEvent = hookfunc(Instance.new("BindableEvent").Fire, RemoteCallback)
  141. methods.BindableFunction = hookfunc(Instance.new("BindableFunction").Invoke, RemoteCallback)
  142. methods.RemoteEvent = hookfunc(Instance.new("RemoteEvent").FireServer, RemoteCallback)
  143. methods.RemoteFunction = hookfunc(Instance.new("RemoteFunction").InvokeServer, RemoteCallback)
  144.  
  145. local function IsAuthorized(self, index)
  146. return (index == "Fire" or index == "Invoke" or index == "FireServer" or index == "InvokeServer") and (enabled[self.ClassName] and not ignore[self.Name])
  147. end
  148.  
  149. function metatable:__namecall(...)
  150. local arguments = {...}
  151. local index = table.remove(arguments)
  152. --local remote = table.remove(arguments, 1)
  153. if IsAuthorized(self, index) then
  154. return RemoteCallback(self, unpack(arguments))
  155. end
  156. return __namecall(self, ...)
  157. end
  158. metatable.__namecall = newcclosure(metatable.__namecall)
Add Comment
Please, Sign In to add comment