Checking a client's hooks

I’m currently making a hook checking system for my server(for anti cheat purposes)

I currently have this code:

local convars = {<a table full of convars>}     
for k, v in pairs(hook.GetTable()) do
	for l, m in pairs(v) do
		if (!convars[l]) then
			print("CAUGHT NONREGISTERED HOOK: "..tostring(l))

And what I get is something like this:


Even though that hook is in the table.

How come it is doing that?

Also, while I’m on the topic of hook checking, is this a reliable way to check for cheats on a client?

What im gonna attempt to do is create a hook checking system that admins can use, and it tells them what the hook is(the hook name), and where it is located on the clients game(it isn’t gonna autoban except for a few blacklisted ones like hack/cheat)

I’m assuming your table looks something like this, if my speculations are incorrect, please provide the rest of the code as well.
local convars = {“CreateMenubar”, “otherhook”, …}
The problem is that while “CreateMenubar” is inside the table, the key for it is 1.
The most efficient way to deal with this is this:
local convars = {
CreateMenubar = true,
otherhook = true
Then your code would work.

An easyway for (simple) anticheats to check for modified hooks is to check the location of the callback function using debug.getinfo.
Then instead of whitelisting each hook, you can whitelist locations where the hooks are allowed to be.
(For example the gamemodes folder, etc.). This, as well as a convar check for sv_cheats 1, will detect most lua cheats.

For my table, I use GLON to decode all the hooks.

Here is what the table looks like, I’m not gonna post the full table just because of how massive it is.

local convars = glon.decode("aCreateUtilitiesCategoriesaULXJailDisconnectedCheckaCreateMenuBar")

There should be absolutely no need to use glon.
Your table layout is wrong, either try printing it out with PrintTable or setup the table without using glon.


[editline]22nd February 2016[/editline]

The table works fine:

1	=	CreateUtilitiesCategories
2	=	ULXJailDisconnectedCheck
3	=	ULXRagdollDisconnectedCheck
4	=	ULXMaulDisconnectedCheck
5	=	ULibPlayerAuthCheck
6	=	SpawniconGenerated
7	=	DoDieFunction
8	=	xgui_plyUpdateCmds
9	=	xgui_plyUpdateGroups
10	=	ulxPlayerDropJailCheck

The problem is that the keys in your table are numbers and not the strings.
So doing convars[“CreateMenubar”] will return the value associated with the “CreateMenubar” key. In your case there is none so it returns nil.

So now you have two options. Do it the right way and change how your table is set up.
Or use table.HasValue().

table.HasValue() worked. Thanks. Sorry, im still new to LUA.

Alright, well I had it working until the update that just occured.

Now i get this really weird hook:

the debug info says it’s located on line 50


the window also pops up twice, here is the code:

local function GH(ply, hooks, called)
	local frame = vgui.Create("DFrame");
	frame:SetSize(450, 525);
	frame:SetTitle("Showing unknown hooks for "..called:Nick().."..");
	local dview = vgui.Create("DListView", frame);
	dview:DockMargin(10, 0, 10, 24)
	dview:AddColumn("Hook Name");
	dview:AddColumn("File Location");
	dview:AddColumn("File Type");
	dview:AddColumn("Line Defined");
	for k, v in pairs(hooks) do
		dview:AddLine(, v.loc, v.type, v.linedefined, v.ssrc)

net.Receive("g_gh", function()
	local ply = net.ReadEntity();
	local hooks = glon.decode(net.ReadString());
	local called = net.ReadEntity()
	GH(ply, hooks, called);

Anyone have any ideas?