This repository has been archived by the owner on Feb 27, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 182
/
boost.c
138 lines (106 loc) · 3.47 KB
/
boost.c
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
136
137
138
#include <stdint.h>
#include "minhook/include/MinHook.h"
typedef void(__fastcall* netcat_insert_direct_t)(uint64_t catalog, uint64_t* key, uint64_t** item);
netcat_insert_direct_t netcat_insert_direct = NULL;
typedef size_t (__cdecl* strlen_t)(const char *str);
strlen_t builtin_strlen = NULL;
HMODULE g_hmod = NULL;
HANDLE g_uninject_thread = NULL;
uint64_t netcat_insert_dedupe_addr = 0;
uint64_t strlen_addr = 0;
// proper dll self unloading - not sure where I got this from
DWORD WINAPI unload_thread(LPVOID lpThreadParameter)
{
CloseHandle(g_uninject_thread);
FreeLibraryAndExitThread(g_hmod, 0);
}
void unload()
{
g_uninject_thread = CreateThread(NULL, 0, &unload_thread, NULL, 0, NULL);
}
// not-really-safe strlen
// comes with a built in "cache" for exactly one item
size_t strlen_cacher(char* str)
{
static char* start = NULL;
static char* end = NULL;
size_t len = 0;
const size_t cap = 20000;
// if we have a "cached" string and current pointer is within it
if (start && str >= start && str <= end) {
// calculate the new strlen
len = end - str;
// if we're near the end, unload self
// we don't want to mess something else up
if (len < cap / 2)
MH_DisableHook((LPVOID)strlen_addr);
// super-fast return!
return len;
}
// count the actual length
// we need at least one measurement of the large JSON
// or normal strlen for other strings
len = builtin_strlen(str);
// if it was the really long string
// save it's start and end addresses
if (len > cap) {
start = str;
end = str + len;
}
// slow, boring return
return len;
}
// normally this checks for duplicates before inserting
// but to speed things up we just skip that and insert directly
char __fastcall netcat_insert_dedupe_hooked(uint64_t catalog, uint64_t* key, uint64_t* item)
{
// didn't bother reversing the structure
uint64_t not_a_hashmap = catalog + 88;
// no idea what this does, but repeat what the original did
if (!(*(uint8_t(__fastcall**)(uint64_t*))(*item + 48))(item))
return 0;
// insert directly
netcat_insert_direct(not_a_hashmap, key, &item);
// remove hooks when the last item's hash is hit
// and unload the .dll, we are done here :)
if (*key == 0x7FFFD6BE) {
MH_DisableHook((LPVOID)netcat_insert_dedupe_addr);
unload();
}
return 1;
}
void initialize()
{
// set up function hooks
uint64_t base_addr = (uint64_t)GetModuleHandleA(NULL);
if (GetModuleHandleA("steam_api64.dll") == NULL) {
// addresses hardcoded for Social Club version 2215/1.53
netcat_insert_dedupe_addr = base_addr + 0x10A9664;
strlen_addr = base_addr + 0x17BD600;
netcat_insert_direct = (netcat_insert_direct_t)(base_addr + 0x24EA8C);
} else {
// addresses hardcoded for Steam version 2215/1.53
netcat_insert_dedupe_addr = base_addr + 0x10AA918;
strlen_addr = base_addr + 0x17C01A0;
netcat_insert_direct = (netcat_insert_direct_t)(base_addr + 0x5BB07C);
}
MH_Initialize();
MH_CreateHook((LPVOID)strlen_addr, &strlen_cacher, (LPVOID*)&builtin_strlen);
MH_CreateHook((LPVOID)netcat_insert_dedupe_addr, &netcat_insert_dedupe_hooked, NULL);
MH_EnableHook((LPVOID)strlen_addr);
MH_EnableHook((LPVOID)netcat_insert_dedupe_addr);
}
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReversed)
{
switch (fdwReason)
{
case DLL_PROCESS_ATTACH:
g_hmod = hinstDLL;
initialize();
break;
case DLL_PROCESS_DETACH:
MH_Uninitialize();
break;
}
return TRUE;
}