-
-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathmain.cpp
76 lines (60 loc) · 2.32 KB
/
main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
#include "interface.h"
#include "appframework/IAppSystem.h"
#include "icvar.h"
ICvar* g_pCVar = NULL;
CreateInterfaceFn g_pfnServerCreateInterface = NULL;
extern ConCommand cvar_unhide;
extern ConCommand cvarlist_md;
typedef bool (*AppSystemConnectFn)(IAppSystem* appSystem, CreateInterfaceFn factory);
static AppSystemConnectFn g_pfnServerConfigConnect = NULL;
bool Connect(IAppSystem* appSystem, CreateInterfaceFn factory)
{
auto result = g_pfnServerConfigConnect(appSystem, factory);
g_pCVar = (ICvar*)factory("VEngineCvar007", NULL);
g_pCVar->RegisterConCommand(&cvar_unhide);
g_pCVar->RegisterConCommand(&cvarlist_md);
return result;
}
DLL_EXPORT void* CreateInterface(const char* pName, int* pReturnCode)
{
if (g_pfnServerCreateInterface == NULL)
{
// Engine should stop joining VAC-secured servers with a modified gameinfo,
// this is to be extra cautious.
auto insecure = CommandLine()->HasParm("-insecure");
if (!insecure)
{
Plat_FatalErrorFunc("Refusing to load cvar-unhide-s2 in secure mode.\n\nAdd -insecure to Counter-Strike's launch options and restart the game.");
}
// Generate the path to the real server.dll
CUtlString realServerPath(Plat_GetGameDirectory());
realServerPath.Append("\\csgo\\bin\\win64\\server.dll");
realServerPath.FixSlashes();
HMODULE serverModule = LoadLibrary(realServerPath.GetForModify());
g_pfnServerCreateInterface = (CreateInterfaceFn)GetProcAddress(serverModule, "CreateInterface");
if (g_pfnServerCreateInterface == NULL)
{
Plat_FatalErrorFunc("Could not find CreateInterface entrypoint in server.dll: %d", GetLastError());
}
}
auto original = g_pfnServerCreateInterface(pName, pReturnCode);
// Intercept the first interface requested by the engine
if (strcmp(pName, "Source2ServerConfig001") == 0)
{
auto vtable = *(void***)original;
DWORD oldProtect = 0;
if (!VirtualProtect(vtable, sizeof(void**), PAGE_EXECUTE_READWRITE, &oldProtect))
{
Plat_FatalErrorFunc("VirtualProtect PAGE_EXECUTE_READWRITE failed: %d", GetLastError());
}
// Intercept the Connect virtual method
g_pfnServerConfigConnect = (AppSystemConnectFn)vtable[0];
vtable[0] = &Connect;
DWORD ignore = 0;
if (!VirtualProtect(vtable, sizeof(void**), oldProtect, &ignore))
{
Plat_FatalErrorFunc("VirtualProtect restore failed: %d", GetLastError());
}
}
return original;
}