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