Spoofing a game service

I need to “spoof” the results of game:GetService, essentially returning my own version of a service, and making it so all code below the spoofing code uses my modified GetService. I have tried to use metatables, but game is an Instance and it’s metatable can’t be set.

You can do this at the top of your script: (I use this to add extra functions to globals when I need to)

local game = setmetatable({
    GetService = function(...)
       -- do stuff
    end
}, {__index=game})

image

image

1 Like

local results = {
    servicesUsed = {}
}

local oldHttpService = game:GetService("HttpService")

local customHttpService = setmetatable({
    RequestAsync = function(self, url, method, headers, body)
        local success, result = pcall(function()
            print(url, method, headers, body)
            return self:RequestAsync(url, method, headers, body)
        end)
        return result
end
}, {__index=oldHttpService})

local game = setmetatable({
    GetService = function(game, service)
        rawset(results.servicesUsed, service, true)
        if service == "HttpService" then
            -- return a copy of httpservice with modified getasync
            return customHttpService
        end
        return game:GetService(service)
    end
}, {__index=game})


    -- Remember to set enable HTTP Requests in game settings!
    local HttpService = game:GetService("HttpService")
     
    local function request()
    	local response = HttpService:RequestAsync(
    		{
    			Url = "http://httpbin.org/post",  -- This website helps debug HTTP requests
    			Method = "POST",
    			Headers = {
    				["Content-Type"] = "application/json"  -- When sending JSON, set this!
    			},
    			Body = HttpService:JSONEncode({hello = "world"})
    		}
    	)
     
    	-- Inspect the response table
    	if response.Success then
    		print("Status code:", response.StatusCode, response.StatusMessage)
    		print("Response body:\n", response.Body)
    	else
    		print("The request failed:", response.StatusCode, response.StatusMessage)
    	end
    end
     
    -- Remember to wrap the function in a 'pcall' to prevent the script from breaking if the request fails
    local success, message = pcall(request)
    if not success then
    	print("Http Request failed:", message)
    end


I’m using this snippet of code to log all used services, and http requests to measure a script’s security, but somehow, it think it’s running HttpService.JSONEncode and not HttpService:JSONEncode

“Expected ‘:’ not ‘.’ calling member function JSONEncode”

Although a little inconvenient, you can try something like this:

local function wrap(self, key: string)
    -- Wraps any methods in an extra function to fix the the "expect ':', not '.'" error
	local service = getmetatable(self).__service
	local success, output = pcall(function()
		return service[key]
	end)
	
	if not success then
		error(output) -- Key doesn't exist at all
	end
	
	if type(output) == "function" then
		return function(_, ...)
            -- Calls the method correctly
			return output(service, ...)
		end
	else
		return output
	end
end

local customHttpService = setmetatable({
	RequestAsync = function(self, ...)
		local args = {...}
		print(...)
		local success, result = pcall(function()
            -- I noticed that the parameters didn't match up, so I changed it a bit
			return getmetatable(self).__service:RequestAsync(table.unpack(args))
		end)
		return result
	end
}, {__service=oldHttpService,__index=wrap})

For other services, this may need to be modified a bit

2 Likes