Advertisement
gilward

Gilward's Remote Spy

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