-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpatch.c
More file actions
72 lines (52 loc) · 1.46 KB
/
patch.c
File metadata and controls
72 lines (52 loc) · 1.46 KB
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
#include <dlfcn.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
typedef const char *(*CountryFn)(void *);
static const char *GetIPCountry(void *self) {
fprintf(stderr, "[hook] GetIPCountry called\n");
return "US";
}
static int already_patched = 0;
static void hook(void *obj) {
if (!obj || already_patched) {
fprintf(stderr, "[hook] skip (null or already patched)\n");
return;
}
void ***p = (void ***)obj;
if (!p || !*p) {
fprintf(stderr, "[hook] invalid object layout\n");
return;
}
void **vt = *p;
/* basic sanity check */
if (!vt[4]) {
fprintf(stderr, "[hook] slot4 is null\n");
return;
}
fprintf(stderr, "[hook] original slot4 = %p\n", vt[4]);
/* copy only first 8 entries to avoid OOB reads */
static void *vtable[8];
for (int i = 0; i < 8; i++) {
vtable[i] = vt[i];
}
vtable[4] = (void *)GetIPCountry;
*p = vtable;
already_patched = true;
fprintf(stderr, "[hook] patch complete\n");
}
void *CreateInterface(const char *name, int *rc) {
static void *(*real)(const char *, int *) = NULL;
if (!real)
real = dlsym(RTLD_NEXT, "CreateInterface");
void *obj = real(name, rc);
fprintf(stderr, "[hook] requested: %s\n", name ? name : "(null)");
if (name && strcmp(name, "SteamUtils013") == 0 && obj) {
fprintf(stderr, "[hook] steamutils found\n");
hook(obj);
}
return obj;
}
__attribute__((constructor)) static void init() {
fprintf(stderr, "[hook] loaded\n");
}