--[[ @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(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(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