Sep 14, 2016 08:14 PM
(This post was last modified: Sep 14, 2016 08:22 PM by Informable.)
In a ROBLOX game, there is a metatable that all ROBLOX Instances share. In many Lua script injection exploits, there will be an added function which allows you to take that metatable and change it, even though it's normally locked and unchangeable.
It's important to take care when doing this, because one wrong move and the entire game will implode on itself in a flood of ugly errors. Or you might cause extremely unexpected behavior and crash yourself. Every single script on your client will be affected by the changes you make to this metatable, and so you want to keep it working.
However, with the ability to change this metatable, it's possible to hook any method inside of any instance. That is a very powerful thing. The changes you make to these methods will affect every script in the game that uses them, and that change will happen instantly during runtime, as if nothing ever happened.
This is extremely useful, especially for games that script with FilteringEnabled on. You can hook methods like FireServer/InvokeServer and trick your client into thinking the server is returning something that it isn't. Or you can spy on what methods a script is calling, and bend it to your will by hooking those methods to do your bidding.
Let me walk you through the process. In this example, we will assume your environment has a function called "getrawmetatable" (a common name for this particular function in ROBLOX scripting exploits), and that it returns a non-read-only version of any userdata's metatable.
We'll start out by creating two variables: One to hold the game's real metatable, and one to hold a table that we'll use to back up that metatable. The backup is important, because we still want to maintain the real metatable's original behavior for everything except what we hook.
Next, we iterate through the real metatable's contents and copy them into the backup table:
Now that we have the backup in place, it's time to modify the real metatable. This is where you need to be extra tricky. The metamethod that we want is __index. Every time any script on your client looks for a method inside an instance, it's indexing that instance, and it's the __index metamethod that decides what to return. We can change that and return our own thing.
That return line, if reached, should pass the request over to the original __index that we backed up, and return the result as it would under normal circumstances. But above that line, we can put some conditionals to return what we want instead. Let's try hooking the Kick function for fun:
What we've just done is made it so that if a script tries accessing the Kick method of a Player object (e.g. game.Players.Weenie:Kick()), it will instead return our custom function, which kills the player. Now every single script on our client that tries to call Kick will instead kill the player it was called on.
This isn't very useful by itself, but if you use your imagination, you can find many other creative uses for it. Remember that game creators on ROBLOX don't normally realize that the LocalScripts they set up can be manipulated in that way. You may find a vulnerability in an admin script or some sort of vector for exploiting a FilteringEnabled game, and the only way to exploit that vulnerability may be through this type of hooking.
Thanks for reading. If you have any questions, post them! 👍
It's important to take care when doing this, because one wrong move and the entire game will implode on itself in a flood of ugly errors. Or you might cause extremely unexpected behavior and crash yourself. Every single script on your client will be affected by the changes you make to this metatable, and so you want to keep it working.
However, with the ability to change this metatable, it's possible to hook any method inside of any instance. That is a very powerful thing. The changes you make to these methods will affect every script in the game that uses them, and that change will happen instantly during runtime, as if nothing ever happened.
This is extremely useful, especially for games that script with FilteringEnabled on. You can hook methods like FireServer/InvokeServer and trick your client into thinking the server is returning something that it isn't. Or you can spy on what methods a script is calling, and bend it to your will by hooking those methods to do your bidding.
Let me walk you through the process. In this example, we will assume your environment has a function called "getrawmetatable" (a common name for this particular function in ROBLOX scripting exploits), and that it returns a non-read-only version of any userdata's metatable.
We'll start out by creating two variables: One to hold the game's real metatable, and one to hold a table that we'll use to back up that metatable. The backup is important, because we still want to maintain the real metatable's original behavior for everything except what we hook.
Code
local meta = getrawmetatable(game)
local oldmeta = {}Next, we iterate through the real metatable's contents and copy them into the backup table:
Code
for i,v in next,meta do
oldmeta[i] = v
endNow that we have the backup in place, it's time to modify the real metatable. This is where you need to be extra tricky. The metamethod that we want is __index. Every time any script on your client looks for a method inside an instance, it's indexing that instance, and it's the __index metamethod that decides what to return. We can change that and return our own thing.
Code
meta.__index = function(t, k)
return oldmeta.__index(t, k)
endThat return line, if reached, should pass the request over to the original __index that we backed up, and return the result as it would under normal circumstances. But above that line, we can put some conditionals to return what we want instead. Let's try hooking the Kick function for fun:
Code
meta.__index = function(t, k)
if k:lower() == "kick" and t:IsA("Player") then
return function(self)
if self.Character:FindFirstChild("Humanoid") then
self.Character.Humanoid.Health = 0
end
end
end
return oldmeta.__index(t, k)
endWhat we've just done is made it so that if a script tries accessing the Kick method of a Player object (e.g. game.Players.Weenie:Kick()), it will instead return our custom function, which kills the player. Now every single script on our client that tries to call Kick will instead kill the player it was called on.
This isn't very useful by itself, but if you use your imagination, you can find many other creative uses for it. Remember that game creators on ROBLOX don't normally realize that the LocalScripts they set up can be manipulated in that way. You may find a vulnerability in an admin script or some sort of vector for exploiting a FilteringEnabled game, and the only way to exploit that vulnerability may be through this type of hooking.
Thanks for reading. If you have any questions, post them! 👍




![[Image: De7wpim.gif]](https://i.imgur.com/De7wpim.gif)
![[Image: 2YB0X4r.gif]](https://i.imgur.com/2YB0X4r.gif)