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.