QuestionInfoGmodZ AntiCheat

Posts 1–4 of 4 · Page 1 of 1
GmodZ AntiCheat
Code:
if CLIENT then
	local debug_getinfo 	= debug.getinfo
	local debug_getupvalue 	= debug.getupvalue
	local net_start 		= net.Start
	local net_writestring 	= net.WriteString
	local net_sendtoserver 	= net.SendToServer
	local local_player 		= LocalPlayer
	local hook_add 			= hook.Add
	local file_read			= file.Read
	local file_read			= file.Write
	local rawget 			= rawget
	local string_find 		= string.find
	local pairs 			= pairs
	local type 				= type
	local get_convarnumber 	= GetConVarNumber
	local set_metatable 	= setmetatable
	local string_char 		= string.char
	local math_random 		= math.random
	local string_gsub 		= string.gsub
	local registry 			= debug.getregistry

	local TYPE_TABLE		= TYPE_TABLE
	local TYPE_FUNCTION		= TYPE_FUNCTION
	local TYPE_STRING		= TYPE_STRING

	local mAC = {}

	local detours = {
		original = {},
		patches = {}
	}

	function detours:GetNamespace()
		local Namespace = GAMEMODE
		if not Namespace then
			Namespace = GM

			if not Namespace then
				return nil
			end
		end

		return Namespace
	end

	function detours:func( Library, index, new, meta )
		--If our library is passed as a string, we have to look it up.
		local str = Library

		if TypeID( Library ) == TYPE_STRING then
			if str == "_G" then
				Library = _G
			else
				if str == "GAMEMODE" or str == "GM" then
					Library = self:GetNamespace()
				elseif meta then
					Library = registry()[Library]
				else
					Library = _G[str]
				end
			end
		end

		--If this function is already detoured, restore it
		if self.original[index] then
			if self.patches[Library[index]] then
				self.patches[Library[index]] = nil
			end
			
			Library[index] = self.original[index]
			self.original[index] = nil
		end

		local old = Library[index]

		--Store the original function pointer and replace it.
		self.original[index] = Library[index]

		local NewFunction = function(...)
			return new(old, ...)
		end

		Library[index] = NewFunction
		self.patches[NewFunction] = old
		return old
	end

	function mAC:generate_randomstring( string_length )
		local str = ""
		
		for i = 1, string_length or 1 do
			str = str .. string_char( math_random( 65, 75 ) )
		end
		
		return str
	end

	function mAC:send_ban( ban_message )
		if self.IsBanned then
			return
		end
		
		net_start("mAC_Ban")
			net_writestring(ban_message)
		net_sendtoserver()
		
		--self.IsBanned = true
	end

	local check_funcs = {
		["file"] = {
			["Read"] = "@lua/includes/extensions/file.lua",
			["Write"] = "@lua/includes/extensions/file.lua",
			["Append"] = "@lua/includes/extensions/file.lua",
			["Exists"] = "=[C]",
			["Find"] = "=[C]",
			["Open"] = "=[C]",
		},
		["debug"] = {
			["getupvalue"] = "=[C]",
			["sethook"] = "=[C]",
			["getlocal"] = "=[C]",
			["setlocal"] = "=[C]",
			["gethook"] = "=[C]",
			["getmetatable"] = "=[C]",
			["setmetatable"] = "=[C]",
			["traceback"] = "=[C]",
			["setfenv"] = "=[C]",
			["getinfo"] = "=[C]",
			["setupvalue"] = "=[C]",
			["getregistry"] = "=[C]",
			["getfenv"] = "=[C]",
		},
		["net"] = {
                ["Start"] = "=[C]",
                ["Receive"] = "@lua/includes/modules/net.lua",
                ["ReadType"] = "@lua/includes/modules/net.lua",
                ["SendToServer"] = "=[C]",
        },
		["usermessage"] = {
                ["IncomingMessage"] = "@lua/includes/modules/usermessage.lua",
                ["GetTable"] = "@lua/includes/modules/usermessage.lua",
        },
		["render"] = {
			["Capture"] = "=[C]"
		},
		["GetConVar"] = "=[C]",
		["GetConVarNumber"] = "=[C]",
		["GetConVarString"] = "=[C]",
		["engineConsoleCommand"] = "@lua/includes/modules/concommand.lua",
		["RunConsoleCommand"] = "=[C]",
	}

	function mAC:CheckFunctionIntegrity()
		for key, value in pairs( check_funcs ) do
			local info
			
			if TypeID( value ) == TYPE_TABLE then
				for func, original_source in pairs( value ) do
					if not _G[key] or TypeID(_G[key][func]) != TYPE_FUNCTION then 
						continue 
					end
					
					info = debug_getinfo( _G[key][func], "S" )
						
					if string_gsub( info.source, [[\]], "" ) != original_source then
						self:send_ban( "Incorrect source for " .. key .. "." .. func .. ": " .. info.source )
						break
					end				
				end
			elseif TypeID( value ) == TYPE_STRING then
				if TypeID( _G[key] ) != TYPE_FUNCTION then 
					continue 
				end
				
				info = debug_getinfo( _G[key], "S" )
					
				if string_gsub( info.source, [[\]], "" ) != value then
					self:send_ban( "Incorrect source for " .. key .. ": " .. info.source )
					break
				end
			end
		end
	end

	local cvar_integrity = {
		["sv_cheats"] = 0,
		["sv_allowcslua"] = 0,
		["r_drawothermodels"] = 1,
		["host_timescale"] = 1,
		["mat_wireframe"] = 0,
	}

	local debug_funcs = {
		"getupvalue",
		"sethook",
		"getlocal",
		"setlocal",
		"gethook",
		"getmetatable",
		"setmetatable",
		"traceback",
		"setfenv",
		"getinfo",
		"setupvalue",
		"getregistry",
		"getfenv",
	}

	local Location_Whitelist = {
		["imperius"] = true,
		["impmodules"] = true,
		["impadmin"] = true,
		["firearms source 2"] = true,
		["fas_weapons"] = true,
		["implogs"] = true,
		["advdupe2"] = true
	}

	local function IsWhitelisted( str )
		local tokens = string.Explode( "/", str )
		
		if string.find(tokens[1], "@gamemodes") then
			return true
		end
		
		if Location_Whitelist[string.lower(tokens[2])] then
			return true
		end
		
		return false
	end

	function mAC:Override()
		_G.RunString = function()
			self:send_ban( "Attempted call to RunString - " .. debug_getinfo( 2, "S" ).source )
		end
		_G.RunStringEx = function()
			self:send_ban( "Attempted call to RunStringEx - " .. debug_getinfo( 2, "S" ).source )
		end
		
		detours:func( "_G", "CompileString", function( original, ... )
			local source = debug_getinfo( 2, "S" ).source
			
			if not IsWhitelisted( source ) then
				self:send_ban( "Unwanted call to CompileString. " .. source )
				return
			end
			
			original( ... )
		end )
		
		detours:func( "_G", "CompileFile", function( original, ... )
			local source = debug_getinfo( 2, "S" ).source
			
			if not IsWhitelisted( source ) then
				self:send_ban( "Unwanted call to CompileFile. " .. source )
				return
			end
			
			original( ... )
		end )
		
		detours:func( "hook", "Add", function( original, hk, str, func )
			local source = debug_getinfo( 2, "S" ).source
			
			if not IsWhitelisted( source ) then
				self:send_ban( "Unwanted Hook on " .. hk .. " - " .. str .. " " .. source )
				return
			end
			
			original( hk, str, func )
		end )
		
		detours:func( "_G", "require", function( original, m_str )
			local source = debug_getinfo( 2, "S" ).source
			
			if not IsWhitelisted( source ) then
				self:send_ban( "Attempted to require unknown module. - " .. source )
				return
			end
			
			original( m_str )
		end )
		
		detours:func( "_G", "include", function( original, m_str )
			local source = debug_getinfo( 2, "S" ).source
			
			if not IsWhitelisted( source ) then
				self:send_ban( "Attempted to include unknown file [" .. m_str .. "]. - " .. source )
				--return
			end
			
			original( m_str )
		end )
		
		detours:func( "_G", "CreateClientConVar", function( original, name, default, ... )
			local source = debug_getinfo( 2, "S" ).source
			
			if not IsWhitelisted( source ) then
				self:send_ban( "Attempted to create a non-whitelisted convar [" .. name .. "]. - " .. source )
				--return
			end
			
			original( name, default, ... )
		end )
		
		local __G = {}
		
		for key, value in pairs(_G) do
			__G[key] = value;
		end
		
		_G = {}
		
		local mt = {	
			__index = function( tab, key )
				return __G[key]
			end,
			__newindex = function( tab, key, value )
				for _, Protected in pairs( { "hook", "debug" } ) do
					if string_find( key, Protected ) then
						local Info = debug_getinfo( 3, "S" )
						if Info then
							mAC:send_ban( "Attempted to modify protected " .. Protected .. " library - " .. Info.source )
							return
						else
							mAC:send_ban( "Attempted to modify protected " .. Protected .. " library" )
							return
						end
					end
				end

				__G[key] = value
			end,
			__metatable = {}
		}
		
		pcall( set_metatable, _G, mt )
	end

	local function DoACTick()
		if not IsValid or not IsValid( local_player() ) then
			timer.Simple( 1, DoACTick )
			return
		end
		
		for convar, value in pairs(cvar_integrity) do
			if get_convarnumber( convar ) != value then
				mAC:send_ban( "Convar integrity check failed - " .. convar .. "." )
			end
		end
		
		if TypeID(_G.debug) != TYPE_TABLE then 
			mAC:send_ban( "Modified debug library." ) 
			return 
		end
		
		--Check for debug library integrity
		for _, str in pairs( debug_funcs ) do
			if TypeID( _G.debug[str] ) != TYPE_FUNCTION then
				mAC:send_ban( "Debug library modified - Index " .. str .. " was nil or invalid type." )
				break
			end
		end
		
		mAC:CheckFunctionIntegrity()
		
		for _, func in pairs( GAMEMODE ) do
			if TypeID( func ) == TYPE_FUNCTION then
				local Source = debug_getinfo( func, "S" ).source
				
				if not IsWhitelisted( Source ) then
					mAC:send_ban( "Pointer integrity check failed on GAMEMODE table. " .. Source )
					break
				end
			end
		end
		
		timer.Simple( 5, DoACTick )
	end

	hook_add( "OnGamemodeLoaded", mAC:generate_randomstring( math_random( 10, 17 ) ), function()
		mAC:Override()
		DoACTick()
	end )
else
	util.AddNetworkString( "mAC_Ban" )

	net.Receive( "mAC_Ban", function( len, pl )
		local str = "[mAC] " .. net.ReadString() .. "\n"
		file.Append( "ac_log.txt", str )
		print( str )
	end )
end
Why? why not might help someone.

EDIT: this is on impacted btw.
Impacted doesn't own Gmodz, they use fudshines shitty gamemode
I gave this to someone that server awhile ago.
detour debug.GetInfo then detour net.Start
Posts 1–4 of 4 · Page 1 of 1

Post a Reply

Similar Threads

Tags for this Thread

None

Need help?