-
Notifications
You must be signed in to change notification settings - Fork 1
/
coverride.c
206 lines (180 loc) · 6.79 KB
/
coverride.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
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
/*
gcc -DDEBUG=1 -DDEBUG_2_SYSLOG=1 -DDEBUG_2_STDERR=0 -fPIC -shared \
-o libcoverride.so coverride.c -ldl -Wall -Wextra -Werror
echo "/path/to/libcoverride.so" | sudo tee -a /etc/ld.so.preload
*/
#define _GNU_SOURCE
#include <arpa/inet.h>
#include <dirent.h>
#include <dlfcn.h>
#include <netdb.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <syslog.h>
#include <unistd.h>
#ifndef DEBUG
#define DEBUG 0
#endif
#ifndef DEBUG_2_SYSLOG
#define DEBUG_2_SYSLOG 1
#endif
#ifndef DEBUG_2_STDERR
#define DEBUG_2_STDERR 0
#endif
#define DEBUG_PRINT(fmt, ...) \
do { \
if (DEBUG) { \
if (DEBUG_2_SYSLOG) { \
syslog(LOG_INFO | LOG_USER, "override|%s: " fmt, __func__, \
__VA_ARGS__); \
closelog(); \
} \
if (DEBUG_2_STDERR) \
fprintf(stderr, "override|%s: " fmt, __func__, __VA_ARGS__); \
} \
} while (0)
void translate_path(const char **old_str, const char **new_str,
char *flexi_str __attribute__((unused)),
size_t flexi_str_len __attribute__((unused))) {
/* do something with me? */
*new_str = (char *)*old_str;
}
#define TRANSLATE_STR(old_str, new_str) \
DEBUG_PRINT("%s\n", old_str); \
char flexi_str[PATH_MAX]; \
translate_path(&old_str, &new_str, flexi_str, sizeof(flexi_str)); \
DEBUG_PRINT("%s\n", new_str);
int open(const char *str, int flags, mode_t mode) {
const char *__str = str;
TRANSLATE_STR(str, __str)
int (*real_open)() = dlsym(RTLD_NEXT, __func__);
return real_open(__str, flags, mode);
}
int openat(int dirfd, const char *pathname, int flags) {
DEBUG_PRINT("%s\n", pathname);
// LD_PRELOAD=/path/to/libcoverride.so gzip /path/to/crap
int (*real_openat)() = dlsym(RTLD_NEXT, __func__);
return real_openat(dirfd, pathname, flags);
}
DIR *opendir(const char *str) {
const char *__str = str;
TRANSLATE_STR(str, __str)
DIR *(*real_opendir)() = dlsym(RTLD_NEXT, __func__);
return real_opendir(__str);
}
int access(const char *str, int mode) {
const char *__str = str;
TRANSLATE_STR(str, __str)
int (*real_access)() = dlsym(RTLD_NEXT, __func__);
return real_access(__str, mode);
}
FILE *fopen(const char *str, const char *mode) {
const char *__str = str;
TRANSLATE_STR(str, __str)
FILE *(*real_fopen)() = dlsym(RTLD_NEXT, __func__);
return real_fopen(__str, mode);
}
FILE *fopen64(const char *str, const char *mode) {
const char *__str = str;
TRANSLATE_STR(str, __str)
FILE *(*real_fopen64)() = dlsym(RTLD_NEXT, __func__);
return real_fopen64(__str, mode);
}
int stat(const char *str, struct stat *buf) {
const char *__str = str;
TRANSLATE_STR(str, __str)
int (*real_stat)() = dlsym(RTLD_NEXT, __func__);
return real_stat(__str, buf);
}
int lstat(const char *str, struct stat *buf) {
const char *__str = str;
TRANSLATE_STR(str, __str)
int (*real_lstat)() = dlsym(RTLD_NEXT, __func__);
return real_lstat(__str, buf);
}
int __xstat(int ver, const char *str, struct stat *buf) {
const char *__str = str;
TRANSLATE_STR(str, __str)
int (*real___xstat)() = dlsym(RTLD_NEXT, __func__);
return real___xstat(ver, __str, buf);
}
int __xstat64(int ver, const char *str, struct stat64 *buf) {
const char *__str = str;
TRANSLATE_STR(str, __str)
int (*real___xstat64)() = dlsym(RTLD_NEXT, __func__);
return real___xstat64(ver, __str, buf);
}
int __lxstat(int ver, const char *str, struct stat *buf) {
const char *__str = str;
TRANSLATE_STR(str, __str)
int (*real___lxstat)() = dlsym(RTLD_NEXT, __func__);
return real___lxstat(ver, __str, buf);
}
int __lxstat64(int ver, const char *str, struct stat64 *buf) {
const char *__str = str;
TRANSLATE_STR(str, __str)
int (*real___lxstat64)() = dlsym(RTLD_NEXT, __func__);
return real___lxstat64(ver, __str, buf);
}
int fstatat(int dirfd, const char *str, struct stat *buf, int flags) {
const char *__str = str;
TRANSLATE_STR(str, __str)
int (*real_fstatat)() = dlsym(RTLD_NEXT, __func__);
return real_fstatat(dirfd, __str, buf, flags);
}
int __fxstatat(int ver, int dirfd, const char *str, struct stat *buf,
int flags) {
const char *__str = str;
TRANSLATE_STR(str, __str)
int (*real___fxstatat)() = dlsym(RTLD_NEXT, __func__);
return real___fxstatat(ver, dirfd, __str, buf, flags);
}
ssize_t getxattr(const char *str, const char *name, void *value, size_t size) {
const char *__str = str;
TRANSLATE_STR(str, __str)
ssize_t (*real_getxattr)() = dlsym(RTLD_NEXT, __func__);
return real_getxattr(__str, name, value, size);
}
ssize_t lgetxattr(const char *str, const char *name, void *value, size_t size) {
const char *__str = str;
TRANSLATE_STR(str, __str)
ssize_t (*real_lgetxattr)() = dlsym(RTLD_NEXT, __func__);
return real_lgetxattr(__str, name, value, size);
}
int getaddrinfo(const char *node, const char *service,
const struct addrinfo *hints, struct addrinfo **res) {
DEBUG_PRINT("%s %s\n", node, service);
int (*real_getaddrinfo)() = dlsym(RTLD_NEXT, __func__);
#ifndef GETADDRINFO_EXAMPLE
return real_getaddrinfo(node, service, hints, res);
#else
/*
LD_PRELOAD=$PWD/libcoverride.so \
python -c 'import socket; print(socket.getaddrinfo("googleapis.com", 80))'
*/
int ret = real_getaddrinfo(node, service, hints, res);
if (ret == 0) {
DEBUG_PRINT("%s %d\n", node, (*res)->ai_family);
if (strcasestr(node, "googleapis.com") && ((*res)->ai_family == AF_INET)) {
struct sockaddr_in *addr_in = (struct sockaddr_in *)((*res)->ai_addr);
DEBUG_PRINT("%s\n", inet_ntoa(addr_in->sin_addr));
int ret2 = inet_pton(2, "199.36.153.4", &addr_in->sin_addr);
DEBUG_PRINT("%s %d\n", inet_ntoa(addr_in->sin_addr), ret2);
}
}
return ret;
#endif
}
struct hostent *gethostbyname(const char *name) {
DEBUG_PRINT("%s\n", name);
struct hostent *(*real_gethostbyname)() = dlsym(RTLD_NEXT, __func__);
return real_gethostbyname(name);
}
struct hostent *gethostbyname2(const char *name, int af) {
DEBUG_PRINT("%s\n", name);
// LD_PRELOAD=$PWD/libcoverride.so getent hosts google.com
struct hostent *(*real_gethostbyname2)() = dlsym(RTLD_NEXT, __func__);
return real_gethostbyname2(name, af);
}