Categories > Exploiting > Roblox >

[HELP] OnClientInvoke w/ .__newindex

Posts: 5

Threads: 1

Joined: Dec, 2021

Reputation: 0

Posted

I'm new to metatables and I'm trying to write a script that will run whenever "OnClientInvoke" is updated. Here's what I've come up with so far:

 

[code]

local mt = getrawmetatable(game)

local old = mt.__newindex

setreadonly(mt, false)

 

mt.__newindex = newcclosure(function(self, method, func)

    if self == game:GetService("ReplicatedStorage").RemoteFunction and method == "OnClientInvoke" then

        old_func = func

        func = function(...)

            local args = {...}

            warn(unpack(args))

            return old_func(...)

        end

    end

    return old(self, method, func)

end)

[/code]

 

The issue is that nothing happens when "OnClientInvoke" is updated. I checked the developer console, and there are no errors or warnings. So, if anyone could assist me in resolving this problem, I would really appreciate it.

  • 0

blueless

Failed to fetch.

vip

Posts: 435

Threads: 41

Joined: Dec, 2021

Reputation: 17

Replied

   
game

"game" is not a table is a global. https://cdn.discordapp.com/attachments/915343431700717618/924726076402438175/unknown.png

 

  • 0

Failed to fetch.

Posts: 5

Threads: 1

Joined: Dec, 2021

Reputation: 0

Replied

@_realnickk Isn't .__namecall used for things that have a ":" in them, for example: RemoteFunction:FireServer()  OnClientInvoke uses "." example: RemoteFunction.OnClientInvoke = function(). I am most likely wrong about that though.

  • 0

Posts: 94

Threads: 14

Joined: Nov, 2018

Reputation: 8

Replied

@Ananymo9

The code seemed to work fine. But, the issue is that your script needs to wait for the server to call the client [1].

 

 

[1]

MyRemote:FireClient(game.Players.PlayerName, "ARGUMENTS...")

 

After some testing, this was my final code:

-- renamed variables
local GameMetatable = getrawmetatable(game)
local GameNewIndex_Backup = GameMetatable.__newindex 

-- 
setreadonly(GameMetatable, false)
--

-- wrapper for the original listener
local function spoofListener(listener)
    return function(...)
        local args = {...}
        warn(unpack(args))
        -- this calls the original listener
        return listener(...)
    end
end

GameMetatable.__newindex = newcclosure(function(self, method, listener)
    -- Safely get the remote from R.S.
    local remote = game:GetService("ReplicatedStorage"):FindFirstChild("RemoteFunction")
    if self == remote then
        return GameNewIndex_Backup(self, key, spoofListener(listener))
    else -- else ; not necessary but good for readibility
        return GameNewIndex_Backup(self, method, listener)
    end
end)

 

(i think the other answer are better than mine, so ye)

  • 0

GitHub: https://github.com/sound-infinity

Discord: SoundInfinity#2135

Posts: 5

Threads: 1

Joined: Dec, 2021

Reputation: 0

Replied

@_realnickk I tried your code It gives me this error: "OnClientInvoke is a callback member of RemoteFunction; you can only set the callback value, get is not available"

 

CODE:

local Old; Old = hookfunction(game:GetService("ReplicatedStorage").RemoteFunction.OnClientInvoke, function(...)

    local Args = {...}

    warn(unpack(Args))

    return Old(unpack(Args))

end)

 

  • 0

Added

@SoundInfinity Also, when I run your code, nothing still appears in the output.

  • 0

Posts: 94

Threads: 14

Joined: Nov, 2018

Reputation: 8

Replied

@Ananymo9 Okay, this time i tested it in my roblox place and it actually works

 

- spoofs the OnClientInvoke

- waits for the server to call Remote:InvokeClient(LocalPlayer, ...args)

- receives the message before the original function

- then calls the original function

 

# something I noticed is that this uses "FindFirstChild," so if there are more than 1 instances named "RemoteFunction" the script might not actually be working with the one you want to work with.

 

local function log_info(...) print("info:", ...) end

function spoofer_init()
    -- renamed variables
    local GameMetatable = getrawmetatable(game)
    local GameNewIndex_Backup = GameMetatable.__newindex 

    -- 
    setreadonly(GameMetatable, false)
    --

    -- wrapper for the original listener
    local function spoofListener(listener)
        log_info("spoofed a listener.")
        return function(...)
            log_info("a spoofed listener was called!")
            local args = {...}
            warn(unpack(args))
            return listener(...)-- this calls the original listener
        end
    end

    GameMetatable.__newindex = newcclosure(function(self, method, listener)
        -- Safely get the remote from R.S.
        local remote = game:GetService("ReplicatedStorage"):FindFirstChild("RemoteFunction")
        if self == remote then
            if method == "OnClientInvoke" then
                log_info("spoofed __newindex::OnClientInvoke")
                return GameNewIndex_Backup(self, method, spoofListener(listener))
            end
        end
        return GameNewIndex_Backup(self, method, listener)
    end)
end
function spoofer_test()
    local container = game:GetService("ReplicatedStorage")
    local remote = container:FindFirstChild("RemoteFunction") -- or Instance.new("RemoteFunction", container)
    if remote then
        -- this will be called only when the server gives a value
        -- refer to line 53
        remote.OnClientInvoke = function()
            log_info("original O.C.Invoke")
        end
    end
end

spoofer_init()
spoofer_test()

--[[ SERVER
 --# This was used to simulate an actual remote function  
 _G.rem = Instance.new("RemoteFunction",  game:GetService("ReplicatedStorage"))
 _G.rem:InvokeClient(game.Players:GetPlayers()[1], "Hello World!")
]]
  • 0

GitHub: https://github.com/sound-infinity

Discord: SoundInfinity#2135

Posts: 5

Threads: 1

Joined: Dec, 2021

Reputation: 0

Replied

@SoundInfinity I was testing it in my own place too and it works! tysm I had been stuck for a couple of days now and I finally found a solution

  • 0

Users viewing this thread:

( Members: 0, Guests: 1, Total: 1 )