Hook library emulation
Keyless VerifiedUniversal

Hook library emulation

Universal Scriptdepsodepso 515 views 1.2K executesUpdated Oct 9, 2026
5.0/ 5(1 votes)
10100% Positive
Lua Script•307 lines (7315 chars)
--[[
	@author depso (depthso)
	@description Hook library emulation, used for having middle hooks

	@Examples:
    	local Old; Old = Emulation:HookFunction(true, MyFunction, function(...) 
    		const Args = {...}
    		-- Stuff here
    
            return Emulation:Unpack(Args)
        end)
    
        local Old; Old = Emulation:HookFunction(true, MyFunction, function(Type, ...) 
            if Type == "GetItemData" then
                return { Amount = 67 }
            end
            
            return ...
        end)
    
    	--// Hooks both __namecall and __index call methods
    	local Old; Old = Emulation:HookMetaFunc(game.HttpService, "JSONEncode", true, function(IsNameCall: boolean, ...) 
    		return Old(...)
    	end)
]]

const Module = { -- exposed to gc 🫣
	HookedFunctions = {},
	UnhookedSpoof = {},
	ExeClosureSpoof = {},
	MetaHooks = {},
	UserHooks = {}
}

--// Protected functions (yes this is messy)
const CloneFunc = clonefunction(clonefunction)
const Hookfunc = clonefunction(hookfunction)
const MakeCFunc = clonefunction(newcclosure)
const IsCClosure = clonefunction(iscclosure)
const Unpack = clonefunction(unpack)
const IsHooked = clonefunction(isfunctionhooked)
const RestoreFunc = clonefunction(restorefunction)
const IsExeClosure = clonefunction(isexecutorclosure)
const GetRawMetatable = clonefunction(getrawmetatable)
const GetNameCallMethod = clonefunction(getnamecallmethod)
const Clear = clonefunction(table.clear)
const Maxn = clonefunction(table.maxn)

--// Globals
const GlobalENV = getgenv()

--// types
type self = typeof(Module) -- and do i gaf to complete this type? no... fuk u
type closure = (...any) -> ...any

@native function Module.Unpack(self: self, Args, Length: number?)
	return Unpack(Args, 1, Length or Maxn(Args))
end

function Module.CallReal(self: self, Func: closure)
	const HookedFunctions = self.HookedFunctions

	--// Call unhooked
	const Unhooked = HookedFunctions[Func]
	if Unhooked then 
		return Unhooked()
	end

	--// Call normally if there's no hook
	return Func()


    -- get baited this function is never used 🤡
end

function Module.HookFunction<closure>(self: self, HardArgs: boolean?, Func: closure, NewFunc: closure?)
	if not Func then return end

	const UserHooks = self.UserHooks
	const HookedFunctions = self.HookedFunctions
	const Cloned = CloneFunc(Func)
	
	const Callback = function(...)
		const Userhook = UserHooks[Func]

		--// Check for an intercept
		if NewFunc then
			if HardArgs then
				return NewFunc(...)
			else -- Unpacking has a limit
				const Responce = {NewFunc(...)}
				if #Responce > 0 then
					return self:Unpack(Responce)
				end
			end
		end

		--// Pass to the hook made by the user
		if Userhook then
			return Userhook(...)
		end

		--// Unaffected
		return Cloned(...)
	end

	--// Hook function
	const Old = Hookfunc(Func, MakeCFunc(Callback))
	HookedFunctions[Func] = Old

	return Old
end

function Module.HookMetaMethod<closure>(self: self, Method: string, Callback: closure): closure
	const Func = GetRawMetatable(game)[Method]
	return self:HookFunction(false, Func, Callback)
end

function Module.HookMetaFunc(self: self, Object: Instance, Method: string, HardArgs: boolean, Callback: closure)
	local Methods = self.MetaHooks[Object]
	const Success, Function = pcall(function()
		return Object[Method]
	end)

	--// Check if the method exists
	if not Success then
		return
	end

	--// Check if the object has a methods dict
	if not Methods then
		Methods = {}
		self.MetaHooks[Object] = Methods
	end

	const Wrapped = MakeCFunc(Callback)
	
	--// Asign function to method call
	Methods[Method] = MakeCFunc(function(...)
		return Wrapped(true, ...)
	end)

	--// Hook __index method aka function
	return self:HookFunction(HardArgs, Function, MakeCFunc(function(...)
		return Wrapped(false, ...)
	end))
end

function Module.ProtectFunction(self: self, Func: closure)
	self:HookFunction(false, Func)
end

function Module.IsProtectedFunction(self: self, Func: closure): boolean
	return self.HookedFunctions[Func] ~= nil
end

function Module.SpoofUnhooked(self: self, Func: closure)
	self.UnhookedSpoof[Func] = true
end
function Module.SpoofExeClosure(self: self, Func: closure)
	self.ExeClosureSpoof[Func] = true
end

function Module.Export(self: self, Names: { string }, Func: closure)
	for _, Name in Names do
		--// Check if the executor has that function
		const OriginalFunc = GlobalENV[Name]
		if not OriginalFunc then continue end

		--// Prevent hooking
		self:ProtectFunction(OriginalFunc)
		
		--// Clone function
		const Closure = MakeCFunc(CloneFunc(Func))

		--// Patch closure type
		if IsExeClosure(OriginalFunc) then
			self:SpoofExeClosure(Closure)
		end

		--// Set new function
		GlobalENV[Name] = Closure
	end

	--// Offload to gc
	Clear(Names)
end

--// clonefunction patch
do
	Module:Export({"clonefunction", "clonefunc", "replaceclosure"}, function(Func: closure)
		--// Allow passthrough if the function is not protected
		const HookProtected = Module:IsProtectedFunction(Func)
		if not HookProtected then 
			return CloneFunc(Func)
		end

		--// New function
		const New = @native function(...)
			return Func(...)
		end

		--// Convert closure type accordingly

		--// C closure
		if IsCClosure(Func) then
			return MakeCFunc(New)

		--// Lua closure
		else
			return New
		end
	end)
end

--// hookfunction patch
do
	Module:Export({"hookfunction", "hookfunc"}, function(Func: closure, Hook)
		--// Allow passthrough if the function is not protected
		local HookProtected = Module:IsProtectedFunction(Func)
		if not HookProtected then 
			return Hookfunc(Func, Hook)
		end

		--// Set hook
		Module.UserHooks[Func] = Hook

		--// Pretend to return unhooked
		local FakeUnhooked = CloneFunc(Func)
		Module:SpoofUnhooked(FakeUnhooked)

		return FakeUnhooked
	end)
end

--// isfunctionhooked patch
do
	Module:Export({"isfunctionhooked"}, function(Func: closure)
		--// Check for user hook
		if Module.UserHooks[Func] then return true end

		--// Check for spoof
		if Module.UnhookedSpoof[Func] then return false end

		--// Check for protected
		const HookProtected = Module:IsProtectedFunction(Func)
		if HookProtected then return false end

		return IsHooked(Func)
	end)
end

--// restorefunction patch
do
	Module:Export({"restorefunction", "restorefunc"}, function(Func: closure)
		--// Check for user hook
		const UserHook = Module.UserHooks[Func]
		if UserHook then
			Clear(UserHook)
			Module.UserHooks[Func] = nil
			return
		end

		--// Check for protected
		const HookProtected = Module:IsProtectedFunction(Func)
		if HookProtected then 
			return 
		end

		--// Pass
		return RestoreFunc(Func)
	end)
end

--// isexecutorclosure patch
do 
	Module:Export({"isexecutorclosure"}, function(Func: closure)
		--// Check for user hook
		const Spoof = Module.ExeClosureSpoof[Func]
		if Spoof then 
			return false
		end

		--// Pass
		return IsExeClosure(Func)
	end)
end

--// __namecall patch
do 
	Module:HookMetaMethod("__namecall", function(self: game, ...)
		const Method = GetNameCallMethod()
		const Methods = Module.MetaHooks[self]
		const Func = Methods and Methods[Method]

		--// Intercept
		if Func then
			return Func(self, ...)
		end
		return
	end)
end

-- but saar this is detected by using getgc(true)
-- > stfu go exclude it from results nerd 🖕

return Module

Features & Information

This doesn't protect aganist things like stack overflow checks, I don't care. I recommend you use delta, examples are provided in the script
#open source#utility#tool#free

Community Comments (0)

No comments yet for this script.

More Scripts for Universal Scripts