-
Notifications
You must be signed in to change notification settings - Fork 21
/
extension.cpp
135 lines (111 loc) · 3.39 KB
/
extension.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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#include "extension.h"
#include "sigs.h"
using namespace std;
#define TIER0_NAME SOURCE_BIN_PREFIX "tier0" SOURCE_BIN_SUFFIX SOURCE_BIN_EXT
Cleaner g_Cleaner;
SMEXT_LINK(&g_Cleaner);
CDetour *g_pDetour = 0;
unordered_set<string> szStrings;
#if SOURCE_ENGINE >= SE_LEFT4DEAD2
DETOUR_DECL_MEMBER4(Detour_LogDirect, LoggingResponse_t, LoggingChannelID_t, channelID, LoggingSeverity_t, severity, Color, color, const tchar *, pMessage)
{
for (const auto& str : szStrings) {
const char* str_cstr = str.c_str();
if (strstr(pMessage, str_cstr) != nullptr) {
return LR_CONTINUE;
}
}
return DETOUR_MEMBER_CALL(Detour_LogDirect)(channelID, severity, color, pMessage);
}
#else
DETOUR_DECL_STATIC2(Detour_DefSpew, SpewRetval_t, SpewType_t, channel, char *, text)
{
for (const auto& str : szStrings) {
const char* str_cstr = str.c_str();
if (strstr(text, str_cstr) != nullptr) {
return SPEW_CONTINUE;
}
}
return DETOUR_STATIC_CALL(Detour_DefSpew)(channel, text);
}
#endif
// https://stackoverflow.com/questions/10178700/c-strip-non-ascii-characters-from-string
static bool badChar(char& c)
{
// everything below space excluding null term and del or above
return (c != 0 && (c < 32 || c > 126));
}
static void stripBadChars(string& str)
{
// remove all chars matching our "badchar" func
str.erase(remove_if(str.begin(),str.end(), badChar), str.end());
}
bool Cleaner::SDK_OnLoad(char *error, size_t maxlength, bool late)
{
CDetourManager::Init(g_pSM->GetScriptingEngine(), 0);
char szPath[256];
g_pSM->BuildPath(Path_SM, szPath, sizeof(szPath), "configs/cleaner.cfg");
rootconsole->ConsolePrint("[CLEANER] Reading strings to clean from 'cleaner.cfg'");
ifstream cleanerConfig(szPath);
string line;
int counter = 1;
while (getline(cleanerConfig, line))
{
// significantly more robust way of stripping evil chars from our string so we don't crash
// when we try to strip them. this includes newlines, control chars, non ascii unicde, etc.
stripBadChars(line);
// don't strip tiny (including 1 len or less) strings
if (line.length() >= 2)
{
szStrings.insert(line);
}
else
{
rootconsole->ConsolePrint("[CLEANER] Not stripping string on -> L%i with 1 or less length! Length: %i", counter, line.length());
}
counter++;
}
rootconsole->ConsolePrint("[CLEANER] %i strings added from cleaner.cfg", szStrings.size());
cleanerConfig.close();
// init our detours
#if SOURCE_ENGINE >= SE_LEFT4DEAD2
#ifdef PLATFORM_WINDOWS
HMODULE tier0 = GetModuleHandle(TIER0_NAME);
void * fn = memutils->FindPattern(tier0, SIG_WINDOWS, SIG_WIN_SIZE);
#elif defined PLATFORM_LINUX
void * tier0 = dlopen(TIER0_NAME, RTLD_NOW);
void * fn = memutils->ResolveSymbol(tier0, SIG_LINUX);
dlclose(tier0);
#else
#error "Unsupported OS"
#endif
if (!fn)
{
rootconsole->ConsolePrint("[CLEANER] Failed to find signature. Please contact the author.");
return false;
}
#if defined SIG_LINUX_OFFSET
#ifdef PLATFORM_LINUX
fn = (void *)((intptr_t)fn + SIG_LINUX_OFFSET);
#endif
#endif
g_pDetour = DETOUR_CREATE_MEMBER(Detour_LogDirect, fn);
#else
g_pDetour = DETOUR_CREATE_STATIC(Detour_DefSpew, (gpointer)GetSpewOutputFunc());
#endif
if (g_pDetour == NULL)
{
rootconsole->ConsolePrint("[CLEANER] Failed to initialize the detours. Please contact the author.");
return false;
}
g_pDetour->EnableDetour();
return true;
}
void Cleaner::SDK_OnUnload()
{
if(g_pDetour)
{
g_pDetour->Destroy();
g_pDetour = NULL;
}
}